1/*
2 * Copyright (C) 2007 The Android Open Source Project
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
17package libcore.java.lang;
18
19import junit.framework.TestCase;
20
21import java.util.concurrent.CountDownLatch;
22
23public class OldAndroidMonitorTest extends TestCase {
24
25    public void testWaitArgumentsTest() throws Exception {
26            /* Try some valid arguments.  These should all
27             * return very quickly.
28             */
29            try {
30                synchronized (this) {
31                    /* millisecond version */
32                    wait(1);
33                    wait(10);
34
35                    /* millisecond + nanosecond version */
36                    wait(0, 1);
37                    wait(0, 999999);
38                    wait(1, 1);
39                    wait(1, 999999);
40                }
41            } catch (InterruptedException ex) {
42                throw new RuntimeException("good Object.wait() interrupted",
43                        ex);
44            } catch (Exception ex) {
45                throw new RuntimeException("Unexpected exception when calling" +
46                        "Object.wait() with good arguments", ex);
47            }
48
49            /* Try some invalid arguments.
50             */
51            boolean sawException = false;
52            try {
53                synchronized (this) {
54                    wait(-1);
55                }
56            } catch (InterruptedException ex) {
57                throw new RuntimeException("bad Object.wait() interrupted", ex);
58            } catch (IllegalArgumentException ex) {
59                sawException = true;
60            } catch (Exception ex) {
61                throw new RuntimeException("Unexpected exception when calling" +
62                        "Object.wait() with bad arguments", ex);
63            }
64            if (!sawException) {
65                throw new RuntimeException("bad call to Object.wait() should " +
66                        "have thrown IllegalArgumentException");
67            }
68
69            sawException = false;
70            try {
71                synchronized (this) {
72                    wait(0, -1);
73                }
74            } catch (InterruptedException ex) {
75                throw new RuntimeException("bad Object.wait() interrupted", ex);
76            } catch (IllegalArgumentException ex) {
77                sawException = true;
78            } catch (Exception ex) {
79                throw new RuntimeException("Unexpected exception when calling" +
80                        "Object.wait() with bad arguments", ex);
81            }
82            if (!sawException) {
83                throw new RuntimeException("bad call to Object.wait() should " +
84                        "have thrown IllegalArgumentException");
85            }
86
87            sawException = false;
88            try {
89                synchronized (this) {
90                    /* The legal range of nanos is 0-999999. */
91                    wait(0, 1000000);
92                }
93            } catch (InterruptedException ex) {
94                throw new RuntimeException("bad Object.wait() interrupted", ex);
95            } catch (IllegalArgumentException ex) {
96                sawException = true;
97            } catch (Exception ex) {
98                throw new RuntimeException("Unexpected exception when calling" +
99                        "Object.wait() with bad arguments", ex);
100            }
101            if (!sawException) {
102                throw new RuntimeException("bad call to Object.wait() should " +
103                        "have thrown IllegalArgumentException");
104            }
105    }
106
107    /**
108     * A thread that blocks forever on {@code wait()} until it's interrupted.
109     */
110    static class Waiter extends Thread {
111        private final Object lock;
112        private final CountDownLatch cdl;
113        private boolean wasInterrupted;
114
115        public Waiter(Object lock, CountDownLatch cdl) {
116            this.lock = lock;
117            this.cdl = cdl;
118            wasInterrupted = false;
119        }
120
121        @Override
122        public void run() {
123            synchronized (lock) {
124                try {
125                    cdl.countDown();
126                    while (true) {
127                        lock.wait();
128                    }
129                } catch (InterruptedException ex) {
130                    wasInterrupted = true;
131                }
132            }
133        }
134
135        public boolean wasInterrupted() {
136            synchronized (lock) {
137                return wasInterrupted;
138            }
139        }
140    }
141
142    public void testInterrupt() throws Exception {
143        final Object lock = new Object();
144        final CountDownLatch cdl = new CountDownLatch(1);
145        final Waiter waiter = new Waiter(lock, cdl);
146
147        waiter.start();
148
149        // Wait for the "waiter" to start and acquire |lock| for the first time.
150        try {
151            cdl.await();
152        } catch (InterruptedException ie) {
153            fail();
154        }
155
156        // Interrupt |waiter| after we acquire |lock|. This ensures that |waiter| is
157        // currently blocked on a call to "wait".
158        synchronized (lock) {
159            waiter.interrupt();
160        }
161
162        // Wait for the waiter to complete.
163        try {
164            waiter.join();
165        } catch (InterruptedException ie) {
166            fail();
167        }
168
169        // Assert than an InterruptedException was thrown.
170        assertTrue(waiter.wasInterrupted());
171    }
172}
173