001package org.eclipse.aether.named; 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 org.junit.Assert; 023import org.junit.Rule; 024import org.junit.Test; 025import org.junit.rules.TestName; 026 027import java.util.concurrent.CountDownLatch; 028import java.util.concurrent.TimeUnit; 029 030import static org.hamcrest.MatcherAssert.assertThat; 031import static org.hamcrest.Matchers.is; 032import static org.hamcrest.Matchers.not; 033import static org.hamcrest.Matchers.sameInstance; 034 035/** 036 * UT support for {@link NamedLockFactory}. 037 */ 038public abstract class NamedLockFactoryTestSupport { 039 040 protected static NamedLockFactory namedLockFactory; 041 042 @Rule 043 public TestName testName = new TestName(); 044 045 protected String lockName() 046 { 047 return testName.getMethodName(); 048 } 049 050 @Test 051 public void refCounting() { 052 final String name = lockName(); 053 try (NamedLock one = namedLockFactory.getLock(name); 054 NamedLock two = namedLockFactory.getLock(name)) { 055 assertThat(one, sameInstance(two)); 056 one.close(); 057 two.close(); 058 059 try (NamedLock three = namedLockFactory.getLock(name)) { 060 assertThat(three, not(sameInstance(two))); 061 } 062 } 063 } 064 065 @Test(expected = IllegalStateException.class) 066 public void unlockWoLock() { 067 final String name = lockName(); 068 try (NamedLock one = namedLockFactory.getLock(name)) { 069 one.unlock(); 070 } 071 } 072 073 @Test 074 public void wwBoxing() throws InterruptedException { 075 final String name = lockName(); 076 try (NamedLock one = namedLockFactory.getLock(name)) { 077 assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true)); 078 assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true)); 079 one.unlock(); 080 one.unlock(); 081 } 082 } 083 084 @Test 085 public void rrBoxing() throws InterruptedException { 086 final String name = lockName(); 087 try (NamedLock one = namedLockFactory.getLock(name)) { 088 assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true)); 089 assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true)); 090 one.unlock(); 091 one.unlock(); 092 } 093 } 094 095 @Test 096 public void wrBoxing() throws InterruptedException { 097 final String name = lockName(); 098 try (NamedLock one = namedLockFactory.getLock(name)) { 099 assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(true)); 100 assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true)); 101 one.unlock(); 102 one.unlock(); 103 } 104 } 105 106 @Test 107 public void rwBoxing() throws InterruptedException { 108 final String name = lockName(); 109 try (NamedLock one = namedLockFactory.getLock(name)) { 110 assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true)); 111 assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), is(false)); 112 one.unlock(); 113 } 114 } 115 116 @Test(timeout = 5000) 117 public void sharedAccess() throws InterruptedException { 118 final String name = lockName(); 119 CountDownLatch winners = new CountDownLatch(2); // we expect 2 winners 120 CountDownLatch losers = new CountDownLatch(0); // we expect 0 losers 121 Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers)); 122 Thread t2 = new Thread(new Access(namedLockFactory, name, true, winners, losers)); 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 final String name = lockName(); 134 CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner 135 CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser 136 Thread t1 = new Thread(new Access(namedLockFactory, name, false, winners, losers)); 137 Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers)); 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 final String name = lockName(); 149 CountDownLatch winners = new CountDownLatch(1); // we expect 1 winner 150 CountDownLatch losers = new CountDownLatch(1); // we expect 1 loser 151 Thread t1 = new Thread(new Access(namedLockFactory, name, true, winners, losers)); 152 Thread t2 = new Thread(new Access(namedLockFactory, name, false, winners, losers)); 153 t1.start(); 154 t2.start(); 155 t1.join(); 156 t2.join(); 157 winners.await(); 158 losers.await(); 159 } 160 161 private static class Access implements Runnable { 162 final NamedLockFactory namedLockFactory; 163 final String name; 164 final boolean shared; 165 final CountDownLatch winner; 166 final CountDownLatch loser; 167 168 public Access(NamedLockFactory namedLockFactory, 169 String name, 170 boolean shared, 171 CountDownLatch winner, 172 CountDownLatch loser) { 173 this.namedLockFactory = namedLockFactory; 174 this.name = name; 175 this.shared = shared; 176 this.winner = winner; 177 this.loser = loser; 178 } 179 180 @Override 181 public void run() { 182 try (NamedLock lock = namedLockFactory.getLock(name)) { 183 if (shared ? lock.lockShared(100L, TimeUnit.MILLISECONDS) : lock.lockExclusively(100L, TimeUnit.MILLISECONDS)) { 184 try { 185 winner.countDown(); 186 loser.await(); 187 } finally { 188 lock.unlock(); 189 } 190 } else { 191 loser.countDown(); 192 winner.await(); 193 } 194 } catch (InterruptedException e) { 195 Assert.fail(e.getMessage()); 196 } 197 } 198 } 199}