/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package libcore.java.lang; import junit.framework.TestCase; import java.util.concurrent.CountDownLatch; public class OldAndroidMonitorTest extends TestCase { public void testWaitArgumentsTest() throws Exception { /* Try some valid arguments. These should all * return very quickly. */ try { synchronized (this) { /* millisecond version */ wait(1); wait(10); /* millisecond + nanosecond version */ wait(0, 1); wait(0, 999999); wait(1, 1); wait(1, 999999); } } catch (InterruptedException ex) { throw new RuntimeException("good Object.wait() interrupted", ex); } catch (Exception ex) { throw new RuntimeException("Unexpected exception when calling" + "Object.wait() with good arguments", ex); } /* Try some invalid arguments. */ boolean sawException = false; try { synchronized (this) { wait(-1); } } catch (InterruptedException ex) { throw new RuntimeException("bad Object.wait() interrupted", ex); } catch (IllegalArgumentException ex) { sawException = true; } catch (Exception ex) { throw new RuntimeException("Unexpected exception when calling" + "Object.wait() with bad arguments", ex); } if (!sawException) { throw new RuntimeException("bad call to Object.wait() should " + "have thrown IllegalArgumentException"); } sawException = false; try { synchronized (this) { wait(0, -1); } } catch (InterruptedException ex) { throw new RuntimeException("bad Object.wait() interrupted", ex); } catch (IllegalArgumentException ex) { sawException = true; } catch (Exception ex) { throw new RuntimeException("Unexpected exception when calling" + "Object.wait() with bad arguments", ex); } if (!sawException) { throw new RuntimeException("bad call to Object.wait() should " + "have thrown IllegalArgumentException"); } sawException = false; try { synchronized (this) { /* The legal range of nanos is 0-999999. */ wait(0, 1000000); } } catch (InterruptedException ex) { throw new RuntimeException("bad Object.wait() interrupted", ex); } catch (IllegalArgumentException ex) { sawException = true; } catch (Exception ex) { throw new RuntimeException("Unexpected exception when calling" + "Object.wait() with bad arguments", ex); } if (!sawException) { throw new RuntimeException("bad call to Object.wait() should " + "have thrown IllegalArgumentException"); } } /** * A thread that blocks forever on {@code wait()} until it's interrupted. */ static class Waiter extends Thread { private final Object lock; private final CountDownLatch cdl; private boolean wasInterrupted; public Waiter(Object lock, CountDownLatch cdl) { this.lock = lock; this.cdl = cdl; wasInterrupted = false; } @Override public void run() { synchronized (lock) { try { cdl.countDown(); while (true) { lock.wait(); } } catch (InterruptedException ex) { wasInterrupted = true; } } } public boolean wasInterrupted() { synchronized (lock) { return wasInterrupted; } } } public void testInterrupt() throws Exception { final Object lock = new Object(); final CountDownLatch cdl = new CountDownLatch(1); final Waiter waiter = new Waiter(lock, cdl); waiter.start(); // Wait for the "waiter" to start and acquire |lock| for the first time. try { cdl.await(); } catch (InterruptedException ie) { fail(); } // Interrupt |waiter| after we acquire |lock|. This ensures that |waiter| is // currently blocked on a call to "wait". synchronized (lock) { waiter.interrupt(); } // Wait for the waiter to complete. try { waiter.join(); } catch (InterruptedException ie) { fail(); } // Assert than an InterruptedException was thrown. assertTrue(waiter.wasInterrupted()); } }