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.io.IOException;
22 import java.nio.file.Files;
23 import java.nio.file.Paths;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.concurrent.CountDownLatch;
27 import java.util.concurrent.TimeUnit;
28
29 import org.eclipse.aether.RepositorySystemSession;
30 import org.eclipse.aether.SyncContext;
31 import org.eclipse.aether.artifact.DefaultArtifact;
32 import org.eclipse.aether.internal.impl.synccontext.named.DiscriminatingNameMapper;
33 import org.eclipse.aether.internal.impl.synccontext.named.GAVNameMapper;
34 import org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter;
35 import org.eclipse.aether.named.NamedLockFactory;
36 import org.eclipse.aether.named.support.LockUpgradeNotSupportedException;
37 import org.eclipse.aether.repository.LocalRepository;
38 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
39 import org.junit.AfterClass;
40 import org.junit.Assert;
41 import org.junit.Before;
42 import org.junit.Test;
43
44 import static org.mockito.Mockito.mock;
45 import static org.mockito.Mockito.when;
46
47
48
49
50 public abstract class NamedLockFactoryAdapterTestSupport {
51 protected static final HazelcastClientUtils UTILS = new HazelcastClientUtils();
52
53 private static final long ADAPTER_TIME = 100L;
54
55 private static final TimeUnit ADAPTER_TIME_UNIT = TimeUnit.MILLISECONDS;
56
57
58
59
60
61 private static NamedLockFactoryAdapter adapter;
62
63 private RepositorySystemSession session;
64
65 protected static void setNamedLockFactory(final NamedLockFactory namedLockFactory) {
66 adapter = new NamedLockFactoryAdapter(new DiscriminatingNameMapper(GAVNameMapper.gav()), namedLockFactory);
67 }
68
69 @AfterClass
70 public static void cleanup() {
71 if (adapter != null) {
72 adapter.getNamedLockFactory().shutdown();
73 }
74
75 UTILS.cleanup();
76 }
77
78 @Before
79 public void before() throws IOException {
80 Files.createDirectories(Paths.get(System.getProperty("java.io.tmpdir")));
81 LocalRepository localRepository =
82 new LocalRepository(Files.createTempDirectory("test").toFile());
83 session = mock(RepositorySystemSession.class);
84 when(session.getLocalRepository()).thenReturn(localRepository);
85 HashMap<String, Object> config = new HashMap<>();
86 config.put(NamedLockFactoryAdapter.TIME_KEY, String.valueOf(ADAPTER_TIME));
87 config.put(NamedLockFactoryAdapter.TIME_UNIT_KEY, ADAPTER_TIME_UNIT.name());
88 when(session.getConfigProperties()).thenReturn(config);
89 }
90
91 @Test
92 public void justCreateAndClose() {
93 adapter.newInstance(session, false).close();
94 }
95
96 @Test
97 public void justAcquire() {
98 try (SyncContext syncContext = adapter.newInstance(session, false)) {
99 syncContext.acquire(
100 Arrays.asList(
101 new DefaultArtifact("groupId:artifactId:1.0"),
102 new DefaultArtifact("groupId:artifactId:1.1")),
103 null);
104 }
105 }
106
107 @Test(timeout = 5000)
108 public void sharedAccess() throws InterruptedException {
109 CountDownLatch winners = new CountDownLatch(2);
110 CountDownLatch losers = new CountDownLatch(0);
111 Thread t1 = new Thread(new Access(true, winners, losers, adapter, session, null));
112 Thread t2 = new Thread(new Access(true, winners, losers, adapter, session, null));
113 t1.start();
114 t2.start();
115 t1.join();
116 t2.join();
117 winners.await();
118 losers.await();
119 }
120
121 @Test(timeout = 5000)
122 public void exclusiveAccess() throws InterruptedException {
123 CountDownLatch winners = new CountDownLatch(1);
124 CountDownLatch losers = new CountDownLatch(1);
125 Thread t1 = new Thread(new Access(false, winners, losers, adapter, session, null));
126 Thread t2 = new Thread(new Access(false, winners, losers, adapter, session, null));
127 t1.start();
128 t2.start();
129 t1.join();
130 t2.join();
131 winners.await();
132 losers.await();
133 }
134
135 @Test(timeout = 5000)
136 public void mixedAccess() throws InterruptedException {
137 CountDownLatch winners = new CountDownLatch(1);
138 CountDownLatch losers = new CountDownLatch(1);
139 Thread t1 = new Thread(new Access(true, winners, losers, adapter, session, null));
140 Thread t2 = new Thread(new Access(false, winners, losers, adapter, session, null));
141 t1.start();
142 t2.start();
143 t1.join();
144 t2.join();
145 winners.await();
146 losers.await();
147 }
148
149 @Test(timeout = 5000)
150 public void nestedSharedShared() throws InterruptedException {
151 CountDownLatch winners = new CountDownLatch(2);
152 CountDownLatch losers = new CountDownLatch(0);
153 Thread t1 = new Thread(new Access(
154 true, winners, losers, adapter, session, new Access(true, winners, losers, adapter, session, null)));
155 t1.start();
156 t1.join();
157 winners.await();
158 losers.await();
159 }
160
161 @Test(timeout = 5000)
162 public void nestedExclusiveShared() throws InterruptedException {
163 CountDownLatch winners = new CountDownLatch(2);
164 CountDownLatch losers = new CountDownLatch(0);
165 Thread t1 = new Thread(new Access(
166 false, winners, losers, adapter, session, new Access(true, winners, losers, adapter, session, null)));
167 t1.start();
168 t1.join();
169 winners.await();
170 losers.await();
171 }
172
173 @Test(timeout = 5000)
174 public void nestedExclusiveExclusive() throws InterruptedException {
175 CountDownLatch winners = new CountDownLatch(2);
176 CountDownLatch losers = new CountDownLatch(0);
177 Thread t1 = new Thread(new Access(
178 false, winners, losers, adapter, session, new Access(false, winners, losers, adapter, session, null)));
179 t1.start();
180 t1.join();
181 winners.await();
182 losers.await();
183 }
184
185 @Test(timeout = 5000)
186 public void nestedSharedExclusive() throws InterruptedException {
187 CountDownLatch winners = new CountDownLatch(1);
188 CountDownLatch losers = new CountDownLatch(1);
189 Thread t1 = new Thread(new Access(
190 true, winners, losers, adapter, session, new Access(false, winners, losers, adapter, session, null)));
191 t1.start();
192 t1.join();
193 winners.await();
194 losers.await();
195 }
196
197 private static class Access implements Runnable {
198 final boolean shared;
199 final CountDownLatch winner;
200 final CountDownLatch loser;
201 final NamedLockFactoryAdapter adapter;
202 final RepositorySystemSession session;
203 final Access chained;
204
205 Access(
206 boolean shared,
207 CountDownLatch winner,
208 CountDownLatch loser,
209 NamedLockFactoryAdapter adapter,
210 RepositorySystemSession session,
211 Access chained) {
212 this.shared = shared;
213 this.winner = winner;
214 this.loser = loser;
215 this.adapter = adapter;
216 this.session = session;
217 this.chained = chained;
218 }
219
220 @Override
221 public void run() {
222 try {
223 try (SyncContext syncContext = adapter.newInstance(session, shared)) {
224 syncContext.acquire(
225 Arrays.asList(
226 new DefaultArtifact("groupId:artifactId:1.0"),
227 new DefaultArtifact("groupId:artifactId:1.1")),
228 null);
229 winner.countDown();
230 if (chained != null) {
231 chained.run();
232 }
233 loser.await();
234 } catch (IllegalStateException | LockUpgradeNotSupportedException e) {
235 loser.countDown();
236 winner.await();
237 }
238 } catch (InterruptedException e) {
239 Assert.fail("interrupted");
240 }
241 }
242 }
243 }