001package org.eclipse.aether.named.hazelcast; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.util.concurrent.CountDownLatch; 023import java.util.concurrent.TimeUnit; 024 025import org.eclipse.aether.named.NamedLock; 026import org.eclipse.aether.named.NamedLockFactory; 027import org.junit.AfterClass; 028import org.junit.Assert; 029import org.junit.Rule; 030import org.junit.Test; 031import org.junit.rules.TestName; 032 033import static org.hamcrest.MatcherAssert.assertThat; 034import static org.hamcrest.Matchers.is; 035import static org.hamcrest.Matchers.not; 036import static org.hamcrest.Matchers.sameInstance; 037 038/** 039 * UT support for {@link NamedLockFactory}. 040 */ 041public abstract class NamedLockFactoryTestSupport 042{ 043 protected static final HazelcastClientUtils utils = new HazelcastClientUtils(); 044 045 protected static NamedLockFactory namedLockFactory; 046 047 @Rule 048 public TestName testName = new TestName(); 049 050 @AfterClass 051 public static void cleanup() 052 { 053 if ( namedLockFactory != null ) 054 { 055 namedLockFactory.shutdown(); 056 } 057 utils.cleanup(); 058 } 059 060 @Test 061 public void refCounting() 062 { 063 final String name = testName.getMethodName(); 064 try ( NamedLock one = namedLockFactory.getLock( name ); 065 NamedLock two = namedLockFactory.getLock( name ) ) 066 { 067 assertThat( one, sameInstance( two ) ); 068 one.close(); 069 two.close(); 070 071 try ( NamedLock three = namedLockFactory.getLock( name ) ) 072 { 073 assertThat( three, not( sameInstance( two ) ) ); 074 } 075 } 076 } 077 078 @Test( expected = IllegalStateException.class ) 079 public void unlockWoLock() 080 { 081 final String name = testName.getMethodName(); 082 try ( NamedLock one = namedLockFactory.getLock( name ) ) 083 { 084 one.unlock(); 085 } 086 } 087 088 @Test 089 public void wwBoxing() throws InterruptedException 090 { 091 final String name = testName.getMethodName(); 092 try ( NamedLock one = namedLockFactory.getLock( name ) ) 093 { 094 assertThat( one.lockExclusively( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 095 assertThat( one.lockExclusively( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 096 one.unlock(); 097 one.unlock(); 098 } 099 } 100 101 @Test 102 public void rrBoxing() throws InterruptedException 103 { 104 final String name = testName.getMethodName(); 105 try ( NamedLock one = namedLockFactory.getLock( name ) ) 106 { 107 assertThat( one.lockShared( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 108 assertThat( one.lockShared( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 109 one.unlock(); 110 one.unlock(); 111 } 112 } 113 114 @Test 115 public void wrBoxing() throws InterruptedException 116 { 117 final String name = testName.getMethodName(); 118 try ( NamedLock one = namedLockFactory.getLock( name ) ) 119 { 120 assertThat( one.lockExclusively( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 121 assertThat( one.lockShared( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 122 one.unlock(); 123 one.unlock(); 124 } 125 } 126 127 @Test 128 public void rwBoxing() throws InterruptedException 129 { 130 final String name = testName.getMethodName(); 131 try ( NamedLock one = namedLockFactory.getLock( name ) ) 132 { 133 assertThat( one.lockShared( 1L, TimeUnit.MILLISECONDS ), is( true ) ); 134 assertThat( one.lockExclusively( 1L, TimeUnit.MILLISECONDS ), is( false ) ); 135 one.unlock(); 136 } 137 } 138 139 @Test( timeout = 5000 ) 140 public void sharedAccess() throws InterruptedException 141 { 142 final String name = testName.getMethodName(); 143 CountDownLatch winners = new CountDownLatch( 2 ); // we expect 2 winner 144 CountDownLatch losers = new CountDownLatch( 0 ); // we expect 0 loser 145 Thread t1 = new Thread( new Access( namedLockFactory, name, true, winners, losers ) ); 146 Thread t2 = new Thread( new Access( namedLockFactory, name, true, winners, losers ) ); 147 t1.start(); 148 t2.start(); 149 t1.join(); 150 t2.join(); 151 winners.await(); 152 losers.await(); 153 } 154 155 @Test( timeout = 5000 ) 156 public void exclusiveAccess() throws InterruptedException 157 { 158 final String name = testName.getMethodName(); 159 CountDownLatch winners = new CountDownLatch( 1 ); // we expect 1 winner 160 CountDownLatch losers = new CountDownLatch( 1 ); // we expect 1 loser 161 Thread t1 = new Thread( new Access( namedLockFactory, name, false, winners, losers ) ); 162 Thread t2 = new Thread( new Access( namedLockFactory, name, false, winners, losers ) ); 163 t1.start(); 164 t2.start(); 165 t1.join(); 166 t2.join(); 167 winners.await(); 168 losers.await(); 169 } 170 171 @Test( timeout = 5000 ) 172 public void mixedAccess() throws InterruptedException 173 { 174 final String name = testName.getMethodName(); 175 CountDownLatch winners = new CountDownLatch( 1 ); // we expect 1 winner 176 CountDownLatch losers = new CountDownLatch( 1 ); // we expect 1 loser 177 Thread t1 = new Thread( new Access( namedLockFactory, name, true, winners, losers ) ); 178 Thread t2 = new Thread( new Access( namedLockFactory, name, false, winners, losers ) ); 179 t1.start(); 180 t2.start(); 181 t1.join(); 182 t2.join(); 183 winners.await(); 184 losers.await(); 185 } 186 187 private static class Access implements Runnable 188 { 189 final NamedLockFactory namedLockFactory; 190 final String name; 191 final boolean shared; 192 final CountDownLatch winner; 193 final CountDownLatch loser; 194 195 public Access( NamedLockFactory namedLockFactory, 196 String name, 197 boolean shared, 198 CountDownLatch winner, 199 CountDownLatch loser ) 200 { 201 this.namedLockFactory = namedLockFactory; 202 this.name = name; 203 this.shared = shared; 204 this.winner = winner; 205 this.loser = loser; 206 } 207 208 @Override 209 public void run() 210 { 211 try ( NamedLock lock = namedLockFactory.getLock( name ) ) 212 { 213 if ( shared ? lock.lockShared( 100L, TimeUnit.MILLISECONDS ) : 214 lock.lockExclusively( 100L, TimeUnit.MILLISECONDS ) ) 215 { 216 try 217 { 218 winner.countDown(); 219 loser.await(); 220 } 221 finally 222 { 223 lock.unlock(); 224 } 225 } 226 else 227 { 228 loser.countDown(); 229 winner.await(); 230 } 231 } 232 catch ( InterruptedException e ) 233 { 234 Assert.fail( e.getMessage() ); 235 } 236 } 237 } 238}