• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import static org.junit.Assert.assertThrows;
22 
23 import com.google.common.util.concurrent.GeneratedMonitorTest.FlagGuard;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import java.util.concurrent.atomic.AtomicInteger;
26 import java.util.concurrent.atomic.AtomicReference;
27 import junit.framework.TestCase;
28 
29 /**
30  * Supplemental tests for {@link Monitor}.
31  *
32  * <p>This test class contains various test cases that don't fit into the test case generation in
33  * {@link GeneratedMonitorTest}.
34  *
35  * @author Justin T. Sampson
36  */
37 public class SupplementalMonitorTest extends TestCase {
38 
testLeaveWithoutEnterThrowsIMSE()39   public void testLeaveWithoutEnterThrowsIMSE() {
40     Monitor monitor = new Monitor();
41     assertThrows(IllegalMonitorStateException.class, () -> monitor.leave());
42   }
43 
testGetWaitQueueLengthWithWrongMonitorThrowsIMSE()44   public void testGetWaitQueueLengthWithWrongMonitorThrowsIMSE() {
45     Monitor monitor1 = new Monitor();
46     Monitor monitor2 = new Monitor();
47     FlagGuard guard = new FlagGuard(monitor2);
48     assertThrows(IllegalMonitorStateException.class, () -> monitor1.getWaitQueueLength(guard));
49   }
50 
testHasWaitersWithWrongMonitorThrowsIMSE()51   public void testHasWaitersWithWrongMonitorThrowsIMSE() {
52     Monitor monitor1 = new Monitor();
53     Monitor monitor2 = new Monitor();
54     FlagGuard guard = new FlagGuard(monitor2);
55     assertThrows(IllegalMonitorStateException.class, () -> monitor1.hasWaiters(guard));
56   }
57 
testNullMonitorInGuardConstructorThrowsNPE()58   public void testNullMonitorInGuardConstructorThrowsNPE() {
59     assertThrows(NullPointerException.class, () -> new FlagGuard(null));
60   }
61 
testIsFair()62   public void testIsFair() {
63     assertTrue(new Monitor(true).isFair());
64     assertFalse(new Monitor(false).isFair());
65   }
66 
testOccupiedMethods()67   public void testOccupiedMethods() {
68     Monitor monitor = new Monitor();
69     verifyOccupiedMethodsInCurrentThread(monitor, false, false, 0);
70     verifyOccupiedMethodsInAnotherThread(monitor, false, false, 0);
71     monitor.enter();
72     try {
73       verifyOccupiedMethodsInCurrentThread(monitor, true, true, 1);
74       verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0);
75       monitor.enter();
76       try {
77         verifyOccupiedMethodsInCurrentThread(monitor, true, true, 2);
78         verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0);
79       } finally {
80         monitor.leave();
81       }
82       verifyOccupiedMethodsInCurrentThread(monitor, true, true, 1);
83       verifyOccupiedMethodsInAnotherThread(monitor, true, false, 0);
84     } finally {
85       monitor.leave();
86     }
87     verifyOccupiedMethodsInCurrentThread(monitor, false, false, 0);
88     verifyOccupiedMethodsInAnotherThread(monitor, false, false, 0);
89   }
90 
verifyOccupiedMethodsInCurrentThread( Monitor monitor, boolean expectedIsOccupied, boolean expectedIsOccupiedByCurrentThread, int expectedOccupiedDepth)91   private static void verifyOccupiedMethodsInCurrentThread(
92       Monitor monitor,
93       boolean expectedIsOccupied,
94       boolean expectedIsOccupiedByCurrentThread,
95       int expectedOccupiedDepth) {
96     assertEquals(expectedIsOccupied, monitor.isOccupied());
97     assertEquals(expectedIsOccupiedByCurrentThread, monitor.isOccupiedByCurrentThread());
98     assertEquals(expectedOccupiedDepth, monitor.getOccupiedDepth());
99   }
100 
verifyOccupiedMethodsInAnotherThread( final Monitor monitor, boolean expectedIsOccupied, boolean expectedIsOccupiedByCurrentThread, int expectedOccupiedDepth)101   private static void verifyOccupiedMethodsInAnotherThread(
102       final Monitor monitor,
103       boolean expectedIsOccupied,
104       boolean expectedIsOccupiedByCurrentThread,
105       int expectedOccupiedDepth) {
106     final AtomicBoolean actualIsOccupied = new AtomicBoolean();
107     final AtomicBoolean actualIsOccupiedByCurrentThread = new AtomicBoolean();
108     final AtomicInteger actualOccupiedDepth = new AtomicInteger();
109     final AtomicReference<Throwable> thrown = new AtomicReference<>();
110     joinUninterruptibly(
111         startThread(
112             new Runnable() {
113               @Override
114               public void run() {
115                 try {
116                   actualIsOccupied.set(monitor.isOccupied());
117                   actualIsOccupiedByCurrentThread.set(monitor.isOccupiedByCurrentThread());
118                   actualOccupiedDepth.set(monitor.getOccupiedDepth());
119                 } catch (Throwable t) {
120                   thrown.set(t);
121                 }
122               }
123             }));
124     assertNull(thrown.get());
125     assertEquals(expectedIsOccupied, actualIsOccupied.get());
126     assertEquals(expectedIsOccupiedByCurrentThread, actualIsOccupiedByCurrentThread.get());
127     assertEquals(expectedOccupiedDepth, actualOccupiedDepth.get());
128   }
129 }
130