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 public class SupplementalMonitorTest extends TestCase { 37 testLeaveWithoutEnterThrowsIMSE()38 public void testLeaveWithoutEnterThrowsIMSE() { 39 Monitor monitor = new Monitor(); 40 try { 41 monitor.leave(); 42 fail("expected IllegalMonitorStateException"); 43 } catch (IllegalMonitorStateException expected) { 44 } 45 } 46 testGetWaitQueueLengthWithWrongMonitorThrowsIMSE()47 public void testGetWaitQueueLengthWithWrongMonitorThrowsIMSE() { 48 Monitor monitor1 = new Monitor(); 49 Monitor monitor2 = new Monitor(); 50 FlagGuard guard = new FlagGuard(monitor2); 51 try { 52 monitor1.getWaitQueueLength(guard); 53 fail("expected IllegalMonitorStateException"); 54 } catch (IllegalMonitorStateException expected) { 55 } 56 } 57 testHasWaitersWithWrongMonitorThrowsIMSE()58 public void testHasWaitersWithWrongMonitorThrowsIMSE() { 59 Monitor monitor1 = new Monitor(); 60 Monitor monitor2 = new Monitor(); 61 FlagGuard guard = new FlagGuard(monitor2); 62 try { 63 monitor1.hasWaiters(guard); 64 fail("expected IllegalMonitorStateException"); 65 } catch (IllegalMonitorStateException expected) { 66 } 67 } 68 testNullMonitorInGuardConstructorThrowsNPE()69 public void testNullMonitorInGuardConstructorThrowsNPE() { 70 try { 71 new FlagGuard(null); 72 fail("expected NullPointerException"); 73 } catch (NullPointerException expected) { 74 } 75 } 76 testIsFair()77 public void testIsFair() { 78 assertTrue(new Monitor(true).isFair()); 79 assertFalse(new Monitor(false).isFair()); 80 } 81 testOccupiedMethods()82 public void testOccupiedMethods() { 83 Monitor monitor = new Monitor(); 84 verifyOccupiedMethodsInCurrentThread(monitor, false, false, 0); 85 verifyOccupiedMethodsInAnotherThread(monitor, false, false, 0); 86 monitor.enter(); 87 try { 88 verifyOccupiedMethodsInCurrentThread(monitor, true, true, 1); 89 verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0); 90 monitor.enter(); 91 try { 92 verifyOccupiedMethodsInCurrentThread(monitor, true, true, 2); 93 verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0); 94 } finally { 95 monitor.leave(); 96 } 97 verifyOccupiedMethodsInCurrentThread(monitor, true, true, 1); 98 verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0); 99 } finally { 100 monitor.leave(); 101 } 102 verifyOccupiedMethodsInCurrentThread(monitor, false, false, 0); 103 verifyOccupiedMethodsInAnotherThread(monitor, false, false, 0); 104 } 105 verifyOccupiedMethodsInCurrentThread( Monitor monitor, boolean expectedIsOccupied, boolean expectedIsOccupiedByCurrentThread, int expectedOccupiedDepth)106 private static void verifyOccupiedMethodsInCurrentThread( 107 Monitor monitor, 108 boolean expectedIsOccupied, 109 boolean expectedIsOccupiedByCurrentThread, 110 int expectedOccupiedDepth) { 111 assertEquals(expectedIsOccupied, monitor.isOccupied()); 112 assertEquals(expectedIsOccupiedByCurrentThread, monitor.isOccupiedByCurrentThread()); 113 assertEquals(expectedOccupiedDepth, monitor.getOccupiedDepth()); 114 } 115 verifyOccupiedMethodsInAnotherThread( final Monitor monitor, boolean expectedIsOccupied, boolean expectedIsOccupiedByCurrentThread, int expectedOccupiedDepth)116 private static void verifyOccupiedMethodsInAnotherThread( 117 final Monitor monitor, 118 boolean expectedIsOccupied, 119 boolean expectedIsOccupiedByCurrentThread, 120 int expectedOccupiedDepth) { 121 final AtomicBoolean actualIsOccupied = new AtomicBoolean(); 122 final AtomicBoolean actualIsOccupiedByCurrentThread = new AtomicBoolean(); 123 final AtomicInteger actualOccupiedDepth = new AtomicInteger(); 124 final AtomicReference<Throwable> thrown = new AtomicReference<>(); 125 joinUninterruptibly( 126 startThread( 127 new Runnable() { 128 @Override 129 public void run() { 130 try { 131 actualIsOccupied.set(monitor.isOccupied()); 132 actualIsOccupiedByCurrentThread.set(monitor.isOccupiedByCurrentThread()); 133 actualOccupiedDepth.set(monitor.getOccupiedDepth()); 134 } catch (Throwable t) { 135 thrown.set(t); 136 } 137 } 138 })); 139 assertNull(thrown.get()); 140 assertEquals(expectedIsOccupied, actualIsOccupied.get()); 141 assertEquals(expectedIsOccupiedByCurrentThread, actualIsOccupiedByCurrentThread.get()); 142 assertEquals(expectedOccupiedDepth, actualOccupiedDepth.get()); 143 } 144 } 145