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.eclipse.aether.named.support.LockUpgradeNotSupportedException;
27  import org.junit.AfterClass;
28  import org.junit.Assert;
29  import org.junit.Rule;
30  import org.junit.Test;
31  import org.junit.rules.TestName;
32  
33  import static org.hamcrest.MatcherAssert.assertThat;
34  import static org.hamcrest.Matchers.is;
35  import static org.hamcrest.Matchers.not;
36  import static org.hamcrest.Matchers.sameInstance;
37  
38  /**
39   * UT support for {@link NamedLockFactory}.
40   */
41  public abstract class NamedLockFactoryTestSupport {
42      protected static final HazelcastClientUtils utils = new HazelcastClientUtils();
43  
44      protected static NamedLockFactory namedLockFactory;
45  
46      @Rule
47      public TestName testName = new TestName();
48  
49      @AfterClass
50      public static void cleanup() {
51          if (namedLockFactory != null) {
52              namedLockFactory.shutdown();
53          }
54          utils.cleanup();
55      }
56  
57      @Test
58      public void refCounting() {
59          final String name = testName.getMethodName();
60          try (NamedLock one = namedLockFactory.getLock(name);
61                  NamedLock two = namedLockFactory.getLock(name)) {
62              assertThat(one, sameInstance(two));
63              one.close();
64              two.close();
65  
66              try (NamedLock three = namedLockFactory.getLock(name)) {
67                  assertThat(three, not(sameInstance(two)));
68              }
69          }
70      }
71  
72      @Test(expected = IllegalStateException.class)
73      public void unlockWoLock() {
74          final String name = testName.getMethodName();
75          try (NamedLock one = namedLockFactory.getLock(name)) {
76              one.unlock();
77          }
78      }
79  
80      @Test
81      public void wwBoxing() throws InterruptedException {
82          final String name = testName.getMethodName();
83          try (NamedLock one = namedLockFactory.getLock(name)) {
84              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
85              assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
86              one.unlock();
87              one.unlock();
88          }
89      }
90  
91      @Test
92      public void rrBoxing() throws InterruptedException {
93          final String name = testName.getMethodName();
94          try (NamedLock one = namedLockFactory.getLock(name)) {
95              assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
96              assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
97              one.unlock();
98              one.unlock();
99          }
100     }
101 
102     @Test
103     public void wrBoxing() throws InterruptedException {
104         final String name = testName.getMethodName();
105         try (NamedLock one = namedLockFactory.getLock(name)) {
106             assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true));
107             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
108             one.unlock();
109             one.unlock();
110         }
111     }
112 
113     @Test
114     public void rwBoxing() throws InterruptedException {
115         final String name = testName.getMethodName();
116         try (NamedLock one = namedLockFactory.getLock(name)) {
117             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
118             try {
119                 one.lockExclusively(1L, TimeUnit.MILLISECONDS);
120             } catch (LockUpgradeNotSupportedException e) {
121                 // good
122             }
123             one.unlock();
124         }
125     }
126 
127     @Test(timeout = 5000)
128     public void sharedAccess() throws InterruptedException {
129         final String name = testName.getMethodName();
130         CountDownLatch winners = new CountDownLatch(2); // we expect 2 winner
131         CountDownLatch losers = new CountDownLatch(0); // we expect 0 loser
132         Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
133         Thread t2 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
134         t1.start();
135         t2.start();
136         t1.join();
137         t2.join();
138         winners.await();
139         losers.await();
140     }
141 
142     @Test(timeout = 5000)
143     public void exclusiveAccess() throws InterruptedException {
144         final String name = testName.getMethodName();
145         CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner
146         CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser
147         Thread t1 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
148         Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
149         t1.start();
150         t2.start();
151         t1.join();
152         t2.join();
153         winners.await();
154         losers.await();
155     }
156 
157     @Test(timeout = 5000)
158     public void mixedAccess() throws InterruptedException {
159         final String name = testName.getMethodName();
160         CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner
161         CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser
162         Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers));
163         Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers));
164         t1.start();
165         t2.start();
166         t1.join();
167         t2.join();
168         winners.await();
169         losers.await();
170     }
171 
172     private static class Access implements Runnable {
173         final NamedLockFactory namedLockFactory;
174         final String name;
175         final boolean shared;
176         final CountDownLatch winner;
177         final CountDownLatch loser;
178 
179         public Access(
180                 NamedLockFactory namedLockFactory,
181                 String name,
182                 boolean shared,
183                 CountDownLatch winner,
184                 CountDownLatch loser) {
185             this.namedLockFactory = namedLockFactory;
186             this.name = name;
187             this.shared = shared;
188             this.winner = winner;
189             this.loser = loser;
190         }
191 
192         @Override
193         public void run() {
194             try (NamedLock lock = namedLockFactory.getLock(name)) {
195                 if (shared
196                         ? lock.lockShared(100L, TimeUnit.MILLISECONDS)
197                         : lock.lockExclusively(100L, TimeUnit.MILLISECONDS)) {
198                     try {
199                         winner.countDown();
200                         loser.await();
201                     } finally {
202                         lock.unlock();
203                     }
204                 } else {
205                     loser.countDown();
206                     winner.await();
207                 }
208             } catch (InterruptedException e) {
209                 Assert.fail(e.getMessage());
210             }
211         }
212     }
213 }