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