blob: 0a8899c0e6acfe63f06aa766c1a333f97aabe5d9 [file] [log] [blame]
Brian O'Connorc6713a82015-02-24 11:55:48 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Brian O'Connorc6713a82015-02-24 11:55:48 -08003 *
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 */
16package org.onlab.util;
17
18import org.apache.commons.lang.mutable.MutableBoolean;
19import org.junit.Ignore;
20import org.junit.Test;
21
22import java.util.concurrent.CountDownLatch;
23import java.util.concurrent.ExecutorService;
24import java.util.concurrent.Executors;
25import java.util.concurrent.TimeUnit;
26
27import static org.junit.Assert.*;
28
29/**
30 * Tests of the BlockingBoolean utility.
31 */
32public class BlockingBooleanTest {
33
Yuta HIGUCHIc2093cb2017-01-12 09:37:52 -080034 private static final int FAIL_TIMEOUT = 1000; //ms
Brian O'Connor5eb77c82015-03-02 18:09:39 -080035
Brian O'Connorc6713a82015-02-24 11:55:48 -080036 @Test
37 public void basics() {
38 BlockingBoolean b = new BlockingBoolean(false);
39 assertEquals(false, b.get());
40 b.set(true);
41 assertEquals(true, b.get());
42 b.set(true);
43 assertEquals(true, b.get());
44 b.set(false);
45 assertEquals(false, b.get());
46 }
47
48 private void waitChange(boolean value, int numThreads) {
49 BlockingBoolean b = new BlockingBoolean(!value);
50
51 CountDownLatch latch = new CountDownLatch(numThreads);
52 ExecutorService exec = Executors.newFixedThreadPool(numThreads);
53 for (int i = 0; i < numThreads; i++) {
54 exec.submit(() -> {
55 try {
56 b.await(value);
57 latch.countDown();
58 } catch (InterruptedException e) {
59 fail();
60 }
61 });
62 }
63 b.set(value);
64 try {
Yuta HIGUCHIc2093cb2017-01-12 09:37:52 -080065 assertTrue(latch.await(FAIL_TIMEOUT, TimeUnit.MILLISECONDS));
Brian O'Connorc6713a82015-02-24 11:55:48 -080066 } catch (InterruptedException e) {
67 fail();
68 }
69 exec.shutdown();
70 }
71
72 @Test
73 public void waitTrueChange() {
74 waitChange(true, 4);
75 }
76
77 @Test
78 public void waitFalseChange() {
79 waitChange(false, 4);
80 }
81
82 @Test
83 public void waitSame() {
84 BlockingBoolean b = new BlockingBoolean(true);
85
86 CountDownLatch latch = new CountDownLatch(1);
87 ExecutorService exec = Executors.newSingleThreadExecutor();
88 exec.submit(() -> {
89 try {
90 b.await(true);
91 latch.countDown();
92 } catch (InterruptedException e) {
93 fail();
94 }
95 });
96 try {
Yuta HIGUCHIc2093cb2017-01-12 09:37:52 -080097 assertTrue(latch.await(FAIL_TIMEOUT, TimeUnit.MILLISECONDS));
Brian O'Connorc6713a82015-02-24 11:55:48 -080098 } catch (InterruptedException e) {
99 fail();
100 }
101 exec.shutdown();
102 }
103
104 @Test
105 public void someWait() {
106 BlockingBoolean b = new BlockingBoolean(false);
107
108 int numThreads = 4;
109 CountDownLatch sameLatch = new CountDownLatch(numThreads / 2);
110 CountDownLatch waitLatch = new CountDownLatch(numThreads / 2);
111
112 ExecutorService exec = Executors.newFixedThreadPool(numThreads);
113 for (int i = 0; i < numThreads; i++) {
114 final boolean value = (i % 2 == 1);
115 exec.submit(() -> {
116 try {
117 b.await(value);
118 if (value) {
119 waitLatch.countDown();
120 } else {
121 sameLatch.countDown();
122 }
123 } catch (InterruptedException e) {
124 fail();
125 }
126 });
127 }
128 try {
Yuta HIGUCHIc2093cb2017-01-12 09:37:52 -0800129 assertTrue(sameLatch.await(FAIL_TIMEOUT, TimeUnit.MILLISECONDS));
Brian O'Connorc6713a82015-02-24 11:55:48 -0800130 assertEquals(waitLatch.getCount(), numThreads / 2);
131 } catch (InterruptedException e) {
132 fail();
133 }
134 b.set(true);
135 try {
Yuta HIGUCHIc2093cb2017-01-12 09:37:52 -0800136 assertTrue(waitLatch.await(FAIL_TIMEOUT, TimeUnit.MILLISECONDS));
Brian O'Connorc6713a82015-02-24 11:55:48 -0800137 } catch (InterruptedException e) {
138 fail();
139 }
140 exec.shutdown();
141 }
142
143 @Test
144 public void waitTimeout() {
145 BlockingBoolean b = new BlockingBoolean(true);
146
147 CountDownLatch latch = new CountDownLatch(1);
148 ExecutorService exec = Executors.newSingleThreadExecutor();
149 exec.submit(() -> {
150 try {
151 if (!b.await(false, 1, TimeUnit.NANOSECONDS)) {
152 latch.countDown();
153 } else {
154 fail();
155 }
156 } catch (InterruptedException e) {
157 fail();
158 }
159 });
160 try {
Yuta HIGUCHIc2093cb2017-01-12 09:37:52 -0800161 assertTrue(latch.await(FAIL_TIMEOUT, TimeUnit.MILLISECONDS));
Brian O'Connorc6713a82015-02-24 11:55:48 -0800162 } catch (InterruptedException e) {
163 fail();
164 }
165 exec.shutdown();
166
167 }
168
169 @Test
170 @Ignore
171 public void samePerf() {
172 int iters = 10_000;
173
174 BlockingBoolean b1 = new BlockingBoolean(false);
175 long t1 = System.nanoTime();
176 for (int i = 0; i < iters; i++) {
177 b1.set(false);
178 }
179 long t2 = System.nanoTime();
180 MutableBoolean b2 = new MutableBoolean(false);
181 for (int i = 0; i < iters; i++) {
182 b2.setValue(false);
183 }
184 long t3 = System.nanoTime();
185 System.out.println((t2 - t1) + " " + (t3 - t2) + " " + ((t2 - t1) <= (t3 - t2)));
186 }
187
188 @Test
189 @Ignore
190 public void changePerf() {
191 int iters = 10_000;
192
193 BlockingBoolean b1 = new BlockingBoolean(false);
194 boolean v = true;
195 long t1 = System.nanoTime();
196 for (int i = 0; i < iters; i++) {
197 b1.set(v);
198 v = !v;
199 }
200 long t2 = System.nanoTime();
201 MutableBoolean b2 = new MutableBoolean(false);
202 for (int i = 0; i < iters; i++) {
203 b2.setValue(v);
204 v = !v;
205 }
206 long t3 = System.nanoTime();
207 System.out.println((t2 - t1) + " " + (t3 - t2) + " " + ((t2 - t1) <= (t3 - t2)));
208 }
209
210}