View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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.junit.AfterClass;
27  import org.junit.Assert;
28  import org.junit.Rule;
29  import org.junit.Test;
30  import org.junit.rules.TestName;
31  
32  import static org.hamcrest.MatcherAssert.assertThat;
33  import static org.hamcrest.Matchers.is;
34  import static org.hamcrest.Matchers.not;
35  import static org.hamcrest.Matchers.sameInstance;
36  
37  /**
38   * UT support for {@link NamedLockFactory}.
39   */
40  public abstract class NamedLockFactoryTestSupport {
41      protected static final HazelcastClientUtils utils = new HazelcastClientUtils();
42  
43      protected static NamedLockFactory namedLockFactory;
44  
45      @Rule
46      public TestName testName = new TestName();
47  
48      @AfterClass
49      public static void cleanup() {
50          if (namedLockFactory != null) {
51              namedLockFactory.shutdown();
52          }
53          utils.cleanup();
54      }
55  
56      @Test
57      public void refCounting() {
58          final String name = testName.getMethodName();
59          try (NamedLock one = namedLockFactory.getLock(name);
60                  NamedLock two = namedLockFactory.getLock(name)) {
61              assertThat(one, sameInstance(two));
62              one.close();
63              two.close();
64  
65              try (NamedLock three = namedLockFactory.getLock(name)) {
66                  assertThat(three, not(sameInstance(two)));
67              }
68          }
69      }
70  
71      @Test(expected = IllegalStateException.class)
72      public void unlockWoLock() {
73          final String name = testName.getMethodName();
74          try (NamedLock one = namedLockFactory.getLock(name)) {
75              one.unlock();
76          }
77      }
78  
79      @Test
80      public void wwBoxing() throws InterruptedException {
81          final String name = testName.getMethodName();
82          try (NamedLock one = namedLockFactory.getLock(name)) {
83              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
84              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
85              one.unlock();
86              one.unlock();
87          }
88      }
89  
90      @Test
91      public void rrBoxing() throws InterruptedException {
92          final String name = testName.getMethodName();
93          try (NamedLock one = namedLockFactory.getLock(name)) {
94              assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
95              assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
96              one.unlock();
97              one.unlock();
98          }
99      }
100 
101     @Test
102     public void wrBoxing() throws InterruptedException {
103         final String name = testName.getMethodName();
104         try (NamedLock one = namedLockFactory.getLock(name)) {
105             assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
106             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
107             one.unlock();
108             one.unlock();
109         }
110     }
111 
112     @Test
113     public void rwBoxing() throws InterruptedException {
114         final String name = testName.getMethodName();
115         try (NamedLock one = namedLockFactory.getLock(name)) {
116             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
117             assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(false));
118             one.unlock();
119         }
120     }
121 
122     @Test(timeout = 5000)
123     public void sharedAccess() throws InterruptedException {
124         final String name = testName.getMethodName();
125         CountDownLatch winners = new CountDownLatch(2); // we expect 2 winner
126         CountDownLatch losers = new CountDownLatch(0); // we expect 0 loser
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(timeout = 5000)
138     public void exclusiveAccess() throws InterruptedException {
139         final String name = testName.getMethodName();
140         CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner
141         CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser
142         Thread t1 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
143         Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
144         t1.start();
145         t2.start();
146         t1.join();
147         t2.join();
148         winners.await();
149         losers.await();
150     }
151 
152     @Test(timeout = 5000)
153     public void mixedAccess() throws InterruptedException {
154         final String name = testName.getMethodName();
155         CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner
156         CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser
157         Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
158         Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
159         t1.start();
160         t2.start();
161         t1.join();
162         t2.join();
163         winners.await();
164         losers.await();
165     }
166 
167     private static class Access implements Runnable {
168         final NamedLockFactory namedLockFactory;
169         final String name;
170         final boolean shared;
171         final CountDownLatch winner;
172         final CountDownLatch loser;
173 
174         public Access(
175                 NamedLockFactory namedLockFactory,
176                 String name,
177                 boolean shared,
178                 CountDownLatch winner,
179                 CountDownLatch loser) {
180             this.namedLockFactory = namedLockFactory;
181             this.name = name;
182             this.shared = shared;
183             this.winner = winner;
184             this.loser = loser;
185         }
186 
187         @Override
188         public void run() {
189             try (NamedLock lock = namedLockFactory.getLock(name)) {
190                 if (shared
191                         ? lock.lockShared(100L, TimeUnit.MILLISECONDS)
192                         : lock.lockExclusively(100L, TimeUnit.MILLISECONDS)) {
193                     try {
194                         winner.countDown();
195                         loser.await();
196                     } finally {
197                         lock.unlock();
198                     }
199                 } else {
200                     loser.countDown();
201                     winner.await();
202                 }
203             } catch (InterruptedException e) {
204                 Assert.fail(e.getMessage());
205             }
206         }
207     }
208 }