2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import junit.framework.TestCase;
20 import android.test.suitebuilder.annotation.MediumTest;
21 import android.test.suitebuilder.annotation.LargeTest;
22 import android.test.suitebuilder.annotation.SmallTest;
24 public class MonitorTest extends TestCase {
27 public void testWaitArgumentsTest() throws Exception {
28 /* Try some valid arguments. These should all
29 * return very quickly.
33 /* millisecond version */
37 /* millisecond + nanosecond version */
43 } catch (InterruptedException ex) {
44 throw new RuntimeException("good Object.wait() interrupted",
46 } catch (Exception ex) {
47 throw new RuntimeException("Unexpected exception when calling" +
48 "Object.wait() with good arguments", ex);
51 /* Try some invalid arguments.
53 boolean sawException = false;
58 } catch (InterruptedException ex) {
59 throw new RuntimeException("bad Object.wait() interrupted", ex);
60 } catch (IllegalArgumentException ex) {
62 } catch (Exception ex) {
63 throw new RuntimeException("Unexpected exception when calling" +
64 "Object.wait() with bad arguments", ex);
67 throw new RuntimeException("bad call to Object.wait() should " +
68 "have thrown IllegalArgumentException");
76 } catch (InterruptedException ex) {
77 throw new RuntimeException("bad Object.wait() interrupted", ex);
78 } catch (IllegalArgumentException ex) {
80 } catch (Exception ex) {
81 throw new RuntimeException("Unexpected exception when calling" +
82 "Object.wait() with bad arguments", ex);
85 throw new RuntimeException("bad call to Object.wait() should " +
86 "have thrown IllegalArgumentException");
92 /* The legal range of nanos is 0-999999. */
95 } catch (InterruptedException ex) {
96 throw new RuntimeException("bad Object.wait() interrupted", ex);
97 } catch (IllegalArgumentException ex) {
99 } catch (Exception ex) {
100 throw new RuntimeException("Unexpected exception when calling" +
101 "Object.wait() with bad arguments", ex);
104 throw new RuntimeException("bad call to Object.wait() should " +
105 "have thrown IllegalArgumentException");
109 private class Interrupter extends Thread {
112 Interrupter(String name, Waiter waiter) {
114 this.waiter = waiter;
120 } catch (Throwable t) {
121 MonitorTest.errorException = t;
122 MonitorTest.testThread.interrupt();
128 // System.out.println("InterruptTest: starting waiter");
132 Thread.currentThread().sleep(500);
133 } catch (InterruptedException ex) {
134 throw new RuntimeException("Test sleep interrupted.", ex);
137 /* Waiter is spinning, and its monitor should still be thin.
139 // System.out.println("Test interrupting waiter");
143 for (int i = 0; i < 3; i++) {
144 /* Wait for the waiter to start waiting.
146 synchronized (waiter.interrupterLock) {
148 waiter.interrupterLock.wait();
149 } catch (InterruptedException ex) {
150 throw new RuntimeException("Test wait interrupted.", ex);
154 /* Before interrupting, grab the waiter lock, which
155 * guarantees that the waiter is already sitting in wait().
157 synchronized (waiter) {
158 //System.out.println("Test interrupting waiter (" + i + ")");
163 // System.out.println("Test waiting for waiter to die.");
166 } catch (InterruptedException ex) {
167 throw new RuntimeException("Test join interrupted.", ex);
169 // System.out.println("InterruptTest done.");
173 private class Waiter extends Thread {
174 Object interrupterLock = new Object();
175 Boolean spin = false;
177 Waiter(String name) {
184 } catch (Throwable t) {
185 MonitorTest.errorException = t;
186 MonitorTest.testThread.interrupt();
191 // System.out.println("Waiter spinning");
193 // We're going to get interrupted while we spin.
196 // System.out.println("Waiter done spinning; interrupted.");
198 throw new RuntimeException("Thread not interrupted " +
202 synchronized (this) {
203 Boolean sawEx = false;
206 synchronized (interrupterLock) {
207 interrupterLock.notify();
209 // System.out.println("Waiter calling wait()");
211 } catch (InterruptedException ex) {
213 // System.out.println("wait(): Waiter caught " + ex);
215 // System.out.println("wait() finished");
218 throw new RuntimeException("Thread not interrupted " +
222 synchronized (this) {
223 Boolean sawEx = false;
226 synchronized (interrupterLock) {
227 interrupterLock.notify();
229 // System.out.println("Waiter calling wait(1000)");
231 } catch (InterruptedException ex) {
233 // System.out.println("wait(1000): Waiter caught " + ex);
235 // System.out.println("wait(1000) finished");
238 throw new RuntimeException("Thread not interrupted " +
239 "during wait(1000)");
242 synchronized (this) {
243 Boolean sawEx = false;
246 synchronized (interrupterLock) {
247 interrupterLock.notify();
249 // System.out.println("Waiter calling wait(1000, 5000)");
250 this.wait(1000, 5000);
251 } catch (InterruptedException ex) {
253 // System.out.println("wait(1000, 5000): Waiter caught " + ex);
255 // System.out.println("wait(1000, 5000) finished");
258 throw new RuntimeException("Thread not interrupted " +
259 "during wait(1000, 5000)");
263 // System.out.println("Waiter returning");
267 private static Throwable errorException;
268 private static Thread testThread;
270 // TODO: Flaky test. Add back MediumTest annotation once fixed
271 public void testInterruptTest() throws Exception {
274 testThread = Thread.currentThread();
275 errorException = null;
277 Waiter waiter = new Waiter("InterruptTest Waiter");
278 Interrupter interrupter =
279 new Interrupter("InterruptTest Interrupter", waiter);
285 } catch (InterruptedException ex) {
286 throw new RuntimeException("Test join interrupted.", ex);
289 if (errorException != null) {
290 throw new RuntimeException("InterruptTest failed",
299 private static void deepWait(int depth, Object lock) {
300 synchronized (lock) {
302 deepWait(depth - 1, lock);
304 String threadName = Thread.currentThread().getName();
306 // System.out.println(threadName + " waiting");
308 // System.out.println(threadName + " done waiting");
309 } catch (InterruptedException ex) {
310 // System.out.println(threadName + " interrupted.");
316 private class Worker extends Thread {
320 Worker(int id, Object lock) {
321 super("Worker(" + id + ")");
329 while (MonitorTest.running) {
330 MonitorTest.deepWait(id, lock);
333 // System.out.println(getName() + " done after " + iterations + " iterations.");
337 private static Object commonLock = new Object();
338 private static Boolean running = false;
342 public void testNestedMonitors() throws Exception {
343 final int NUM_WORKERS = 5;
345 Worker w[] = new Worker[NUM_WORKERS];
348 for (i = 0; i < NUM_WORKERS; i++) {
349 w[i] = new Worker(i * 2 - 1, new Object());
354 // System.out.println("NestedMonitors: starting workers");
355 for (i = 0; i < NUM_WORKERS; i++) {
360 Thread.currentThread().sleep(1000);
361 } catch (InterruptedException ex) {
362 // System.out.println("Test sleep interrupted.");
365 for (i = 0; i < 100; i++) {
366 for (int j = 0; j < NUM_WORKERS; j++) {
367 synchronized (w[j].lock) {
373 // System.out.println("NesterMonitors: stopping workers");
375 for (i = 0; i < NUM_WORKERS; i++) {
376 synchronized (w[i].lock) {
377 w[i].lock.notifyAll();
382 private static class CompareAndExchange extends Thread {
383 static Object toggleLock = null;
384 static int toggle = -1;
385 static Boolean running = false;
388 toggleLock = new Object();
391 Worker w1 = new Worker(0, 1);
392 Worker w2 = new Worker(2, 3);
393 Worker w3 = new Worker(4, 5);
394 Worker w4 = new Worker(6, 7);
398 // System.out.println("CompareAndExchange: starting workers");
407 } catch (InterruptedException ex) {
408 // System.out.println(getName() + " interrupted.");
411 // System.out.println("MonitorTest: stopping workers");
417 class Worker extends Thread {
421 Worker(int i1, int i2) {
422 super("Worker(" + i1 + ", " + i2 + ")");
430 /* Latch this because run() may set the static field to
431 * null at some point.
433 Object toggleLock = CompareAndExchange.toggleLock;
435 // System.out.println(getName() + " running");
437 while (CompareAndExchange.running) {
438 synchronized (toggleLock) {
442 if (CompareAndExchange.toggle == i1) {
444 CompareAndExchange.toggle = test = i2;
447 CompareAndExchange.toggle = test = i1;
449 if ((check = CompareAndExchange.toggle) != test) {
450 // System.out.println("Worker(" + i1 + ", " +
451 // i2 + ") " + "test " + test +
452 // " != toggle " + check);
453 throw new RuntimeException(
454 "locked value changed");
460 } catch (InterruptedException ex) {
461 // System.out.println(getName() + " interrupted.");
464 // System.out.println(getName() + " done after " +
465 // iterations + " iterations.");