1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.named.hazelcast;
20
21 import java.util.concurrent.CountDownLatch;
22 import java.util.concurrent.TimeUnit;
23
24 import org.eclipse.aether.named.NamedLock;
25 import org.eclipse.aether.named.NamedLockFactory;
26 import org.eclipse.aether.named.support.LockUpgradeNotSupportedException;
27 import org.junit.jupiter.api.AfterAll;
28 import org.junit.jupiter.api.Test;
29 import org.junit.jupiter.api.TestInfo;
30 import org.junit.jupiter.api.Timeout;
31
32 import static org.junit.jupiter.api.Assertions.*;
33
34
35
36
37 public abstract class NamedLockFactoryTestSupport {
38 protected static final HazelcastClientUtils utils = new HazelcastClientUtils();
39
40 protected static NamedLockFactory namedLockFactory;
41
42 @AfterAll
43 static void cleanup() {
44 if (namedLockFactory != null) {
45 namedLockFactory.shutdown();
46 }
47 utils.cleanup();
48 }
49
50 @Test
51 void refCounting(TestInfo testInfo) {
52 final String name = testInfo.getDisplayName();
53 try (NamedLock one = namedLockFactory.getLock(name);
54 NamedLock two = namedLockFactory.getLock(name)) {
55 assertSame(one, two);
56 one.close();
57 two.close();
58
59 try (NamedLock three = namedLockFactory.getLock(name)) {
60 assertNotSame(three, two);
61 }
62 }
63 }
64
65 @Test
66 void unlockWoLock(TestInfo testInfo) {
67 final String name = testInfo.getDisplayName();
68 try (NamedLock one = namedLockFactory.getLock(name)) {
69 assertThrows(IllegalStateException.class, one::unlock);
70 }
71 }
72
73 @Test
74 void wwBoxing(TestInfo testInfo) throws InterruptedException {
75 final String name = testInfo.getDisplayName();
76 try (NamedLock one = namedLockFactory.getLock(name)) {
77 assertTrue(one.lockExclusively(1L, TimeUnit.MILLISECONDS));
78 assertTrue(one.lockExclusively(1L, TimeUnit.MILLISECONDS));
79 one.unlock();
80 one.unlock();
81 }
82 }
83
84 @Test
85 void rrBoxing(TestInfo testInfo) throws InterruptedException {
86 final String name = testInfo.getDisplayName();
87 try (NamedLock one = namedLockFactory.getLock(name)) {
88 assertTrue(one.lockShared(1L, TimeUnit.MILLISECONDS));
89 assertTrue(one.lockShared(1L, TimeUnit.MILLISECONDS));
90 one.unlock();
91 one.unlock();
92 }
93 }
94
95 @Test
96 void wrBoxing(TestInfo testInfo) throws InterruptedException {
97 final String name = testInfo.getDisplayName();
98 try (NamedLock one = namedLockFactory.getLock(name)) {
99 assertTrue(one.lockExclusively(1L, TimeUnit.MILLISECONDS));
100 assertTrue(one.lockShared(1L, TimeUnit.MILLISECONDS));
101 one.unlock();
102 one.unlock();
103 }
104 }
105
106 @Test
107 void rwBoxing(TestInfo testInfo) throws InterruptedException {
108 final String name = testInfo.getDisplayName();
109 try (NamedLock one = namedLockFactory.getLock(name)) {
110 assertTrue(one.lockShared(1L, TimeUnit.MILLISECONDS));
111 try {
112 one.lockExclusively(1L, TimeUnit.MILLISECONDS);
113 fail("lock upgrade should be not supported");
114 } catch (LockUpgradeNotSupportedException e) {
115
116 }
117 one.unlock();
118 }
119 }
120
121 @Test
122 @Timeout(5)
123 public void sharedAccess(TestInfo testInfo) throws InterruptedException {
124 final String name = testInfo.getDisplayName();
125 CountDownLatch winners = new CountDownLatch(2);
126 CountDownLatch losers = new CountDownLatch(0);
127 Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
128 Thread t2 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
129 t1.start();
130 t2.start();
131 t1.join();
132 t2.join();
133 winners.await();
134 losers.await();
135 }
136
137 @Test
138 @Timeout(5)
139 public void exclusiveAccess(TestInfo testInfo) throws InterruptedException {
140 final String name = testInfo.getDisplayName();
141 CountDownLatch winners = new CountDownLatch(1);
142 CountDownLatch losers = new CountDownLatch(1);
143 Thread t1 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
144 Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
145 t1.start();
146 t2.start();
147 t1.join();
148 t2.join();
149 winners.await();
150 losers.await();
151 }
152
153 @Test
154 @Timeout(5)
155 public void mixedAccess(TestInfo testInfo) throws InterruptedException {
156 final String name = testInfo.getDisplayName();
157 CountDownLatch winners = new CountDownLatch(1);
158 CountDownLatch losers = new CountDownLatch(1);
159 Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
160 Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
161 t1.start();
162 t2.start();
163 t1.join();
164 t2.join();
165 winners.await();
166 losers.await();
167 }
168
169 private static class Access implements Runnable {
170 final NamedLockFactory namedLockFactory;
171 final String name;
172 final boolean shared;
173 final CountDownLatch winner;
174 final CountDownLatch loser;
175
176 public Access(
177 NamedLockFactory namedLockFactory,
178 String name,
179 boolean shared,
180 CountDownLatch winner,
181 CountDownLatch loser) {
182 this.namedLockFactory = namedLockFactory;
183 this.name = name;
184 this.shared = shared;
185 this.winner = winner;
186 this.loser = loser;
187 }
188
189 @Override
190 public void run() {
191 try (NamedLock lock = namedLockFactory.getLock(name)) {
192 if (shared
193 ? lock.lockShared(100L, TimeUnit.MILLISECONDS)
194 : lock.lockExclusively(100L, TimeUnit.MILLISECONDS)) {
195 try {
196 winner.countDown();
197 loser.await();
198 } finally {
199 lock.unlock();
200 }
201 } else {
202 loser.countDown();
203 winner.await();
204 }
205 } catch (InterruptedException e) {
206 fail(e.getMessage());
207 }
208 }
209 }
210 }