1 /**
2 * Copyright (c) 2014, stateful.co
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met: 1) Redistributions of source code must retain the above
8 * copyright notice, this list of conditions and the following
9 * disclaimer. 2) Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution. 3) Neither the name of the stateful.co nor
13 * the names of its contributors may be used to endorse or promote
14 * products derived from this software without specific prior written
15 * permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package co.stateful.core;
31
32 import co.stateful.spi.Locks;
33 import com.jcabi.aspects.Parallel;
34 import com.jcabi.aspects.Tv;
35 import com.jcabi.urn.URN;
36 import java.util.concurrent.Callable;
37 import java.util.concurrent.atomic.AtomicInteger;
38 import org.hamcrest.MatcherAssert;
39 import org.hamcrest.Matchers;
40 import org.junit.Test;
41
42 /**
43 * Integration case for {@link DyLocks}.
44 * @author Yegor Bugayenko (yegor@tpc2.com)
45 * @version $Id$
46 */
47 public final class DyLocksITCase {
48
49 /**
50 * DyLocks can lock/unlock in parallel threads.
51 * @throws Exception If some problem inside
52 */
53 @Test
54 public void locksAndUnlocksInThreads() throws Exception {
55 final Locks locks = new DefaultUser(
56 new URN("urn:test:787009")
57 ).locks();
58 final String name = "lock-9033";
59 final AtomicInteger done = new AtomicInteger();
60 new Callable<Void>() {
61 @Override
62 @Parallel(threads = Tv.TWENTY)
63 public Void call() throws Exception {
64 if (locks.lock(name, "nothing special").isEmpty()) {
65 done.incrementAndGet();
66 }
67 return null;
68 }
69 } .call();
70 MatcherAssert.assertThat(
71 done.get(),
72 Matchers.equalTo(1)
73 );
74 }
75
76 /**
77 * DyLocks can lock/unlock with mandatory label.
78 * @throws Exception If some problem inside
79 * @since 1.6
80 */
81 @Test
82 public void locksAndUnlocksWithLabel() throws Exception {
83 final Locks locks = new DefaultUser(
84 new URN("urn:test:78119")
85 ).locks();
86 final String name = "lock-980";
87 final String label = "some label \u20ac";
88 locks.lock(name, label);
89 MatcherAssert.assertThat(
90 locks.unlock(name, "wrong label"),
91 Matchers.not(Matchers.equalTo(""))
92 );
93 MatcherAssert.assertThat(
94 locks.unlock(name, label),
95 Matchers.equalTo("")
96 );
97 MatcherAssert.assertThat(
98 locks.lock(name, "new label"),
99 Matchers.equalTo("")
100 );
101 }
102
103 }