1 /* 2 * Copyright (C) 2014 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.util.concurrent; 18 19 import static com.google.common.util.concurrent.GeneratedMonitorTest.startThread; 20 import static com.google.common.util.concurrent.Uninterruptibles.joinUninterruptibly; 21 22 import com.google.common.util.concurrent.GeneratedMonitorTest.FlagGuard; 23 import java.util.concurrent.atomic.AtomicBoolean; 24 import java.util.concurrent.atomic.AtomicInteger; 25 import java.util.concurrent.atomic.AtomicReference; 26 import junit.framework.TestCase; 27 28 /** 29 * Supplemental tests for {@link Monitor}. 30 * 31 * <p>This test class contains various test cases that don't fit into the test case generation in 32 * {@link GeneratedMonitorTest}. 33 * 34 * @author Justin T. Sampson 35 */ 36 37 public class SupplementalMonitorTest extends TestCase { 38 testLeaveWithoutEnterThrowsIMSE()39 public void testLeaveWithoutEnterThrowsIMSE() { 40 Monitor monitor = new Monitor(); 41 try { 42 monitor.leave(); 43 fail("expected IllegalMonitorStateException"); 44 } catch (IllegalMonitorStateException expected) { 45 } 46 } 47 testGetWaitQueueLengthWithWrongMonitorThrowsIMSE()48 public void testGetWaitQueueLengthWithWrongMonitorThrowsIMSE() { 49 Monitor monitor1 = new Monitor(); 50 Monitor monitor2 = new Monitor(); 51 FlagGuard guard = new FlagGuard(monitor2); 52 try { 53 monitor1.getWaitQueueLength(guard); 54 fail("expected IllegalMonitorStateException"); 55 } catch (IllegalMonitorStateException expected) { 56 } 57 } 58 testHasWaitersWithWrongMonitorThrowsIMSE()59 public void testHasWaitersWithWrongMonitorThrowsIMSE() { 60 Monitor monitor1 = new Monitor(); 61 Monitor monitor2 = new Monitor(); 62 FlagGuard guard = new FlagGuard(monitor2); 63 try { 64 monitor1.hasWaiters(guard); 65 fail("expected IllegalMonitorStateException"); 66 } catch (IllegalMonitorStateException expected) { 67 } 68 } 69 testNullMonitorInGuardConstructorThrowsNPE()70 public void testNullMonitorInGuardConstructorThrowsNPE() { 71 try { 72 new FlagGuard(null); 73 fail("expected NullPointerException"); 74 } catch (NullPointerException expected) { 75 } 76 } 77 testIsFair()78 public void testIsFair() { 79 assertTrue(new Monitor(true).isFair()); 80 assertFalse(new Monitor(false).isFair()); 81 } 82 testOccupiedMethods()83 public void testOccupiedMethods() { 84 Monitor monitor = new Monitor(); 85 verifyOccupiedMethodsInCurrentThread(monitor, false, false, 0); 86 verifyOccupiedMethodsInAnotherThread(monitor, false, false, 0); 87 monitor.enter(); 88 try { 89 verifyOccupiedMethodsInCurrentThread(monitor, true, true, 1); 90 verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0); 91 monitor.enter(); 92 try { 93 verifyOccupiedMethodsInCurrentThread(monitor, true, true, 2); 94 verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0); 95 } finally { 96 monitor.leave(); 97 } 98 verifyOccupiedMethodsInCurrentThread(monitor, true, true, 1); 99 verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0); 100 } finally { 101 monitor.leave(); 102 } 103 verifyOccupiedMethodsInCurrentThread(monitor, false, false, 0); 104 verifyOccupiedMethodsInAnotherThread(monitor, false, false, 0); 105 } 106 verifyOccupiedMethodsInCurrentThread( Monitor monitor, boolean expectedIsOccupied, boolean expectedIsOccupiedByCurrentThread, int expectedOccupiedDepth)107 private static void verifyOccupiedMethodsInCurrentThread( 108 Monitor monitor, 109 boolean expectedIsOccupied, 110 boolean expectedIsOccupiedByCurrentThread, 111 int expectedOccupiedDepth) { 112 assertEquals(expectedIsOccupied, monitor.isOccupied()); 113 assertEquals(expectedIsOccupiedByCurrentThread, monitor.isOccupiedByCurrentThread()); 114 assertEquals(expectedOccupiedDepth, monitor.getOccupiedDepth()); 115 } 116 verifyOccupiedMethodsInAnotherThread( final Monitor monitor, boolean expectedIsOccupied, boolean expectedIsOccupiedByCurrentThread, int expectedOccupiedDepth)117 private static void verifyOccupiedMethodsInAnotherThread( 118 final Monitor monitor, 119 boolean expectedIsOccupied, 120 boolean expectedIsOccupiedByCurrentThread, 121 int expectedOccupiedDepth) { 122 final AtomicBoolean actualIsOccupied = new AtomicBoolean(); 123 final AtomicBoolean actualIsOccupiedByCurrentThread = new AtomicBoolean(); 124 final AtomicInteger actualOccupiedDepth = new AtomicInteger(); 125 final AtomicReference<Throwable> thrown = new AtomicReference<>(); 126 joinUninterruptibly( 127 startThread( 128 new Runnable() { 129 @Override 130 public void run() { 131 try { 132 actualIsOccupied.set(monitor.isOccupied()); 133 actualIsOccupiedByCurrentThread.set(monitor.isOccupiedByCurrentThread()); 134 actualOccupiedDepth.set(monitor.getOccupiedDepth()); 135 } catch (Throwable t) { 136 thrown.set(t); 137 } 138 } 139 })); 140 assertNull(thrown.get()); 141 assertEquals(expectedIsOccupied, actualIsOccupied.get()); 142 assertEquals(expectedIsOccupiedByCurrentThread, actualIsOccupiedByCurrentThread.get()); 143 assertEquals(expectedOccupiedDepth, actualOccupiedDepth.get()); 144 } 145 } 146