1 /*
2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 import java.awt.*;
26 import java.awt.event.*;
27 
28 /*
29  * @test
30  * @summary  To Test the following assertions in InvovationEvent.
31  * 1.InvocationEvent when dispatched, should invoke the
32  *   run() method of the Runnable Interface.
33  * 2.If catchExceptions is false, Exception should be
34  *   propagated up to the EventDispatchThread's dispatch loop.
35  * 3.If catchExceptions is true, InvocationEvent.getExceptions()
36  *   should return the exception thrown inside thr run() method.
37  * 4.When InvocationEvent object is posted on to the EventQueue,
38  *   InvocationEvent.dispatch() method should be invoked by the
39  *   EventQueue.
40  * 5.If the notifier object is not null, notifyAll() of the
41  *   notifier object should be invoked when the run() method returns.
42  * 6.To test whether the threads are invoked in the right order
43  *   When InvocationEvents are nested.
44  * 7.The getWhen method should return timestamp which is less than
45  *   current System time and greater than the time before it has
46  *   actually happened
47  * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
48  * @run main InvocationEventTest
49  */
50 
51 public class InvocationEventTest {
52     EventQueue eventQ1 = new EventQueue();
53 
54     Object lock = new Object();
55 
56     static final int delay = 5000;
57 
58     public volatile boolean notifierStatus = false;
59     public Object notifierLock = new Object();
60 
61     public volatile boolean threadStatus = false;
62     public volatile boolean childInvoked = false;
63 
doTest()64     public synchronized void doTest() throws Exception {
65         // Testing assertions 1, 2 and 7:
66         // 1.InvocationEvent when dispatched, should invoke the
67         //   run() method of the Runnable Interface.
68         // 2.If catchExceptions is false, Exception should be
69         //   propagated up to the EventDispatchThread's dispatch loop.
70         // 7.The getWhen method should return timestamp which is less than
71         //   current System time and greater than the time before it has
72         //   actually happened
73 
74         long timeBeforeInvoking = System.currentTimeMillis();
75 
76         Thread.sleep(10);
77 
78         InvocationEvent invoc = new InvocationEvent(this, () -> { threadStatus = true; }, lock, false);
79         invoc.dispatch();
80 
81         Thread.sleep(10);
82 
83         if (!threadStatus) {
84             synchronized (lock) {
85                 lock.wait(delay);
86             }
87         }
88 
89         // testing getException() when no exception is thrown
90         if (invoc.getWhen() <= timeBeforeInvoking ||
91                 invoc.getWhen() >= System.currentTimeMillis()) {
92             throw new RuntimeException("getWhen method is not getting the time at which event occured");
93         }
94 
95         if (invoc.getException() != null) {
96             throw new RuntimeException("InvocationEvent.getException() does not return null " +
97                     "when catchException is false");
98         }
99 
100         // testing the normal behaviour of InvocationEvent
101         if (!threadStatus) {
102             throw new RuntimeException("InvocationEvent when dispatched, did not" +
103                     " invoke the run() of the Runnable interface  ");
104         }
105         threadStatus = false;
106 
107         // Testing assertion 3:
108         // 3.If catchExceptions is true, InvocationEvent.getExceptions()
109         //   should return the exception thrown inside the run() method.
110         RuntimeException sampleExn = new RuntimeException(" test exception");
111 
112         invoc = new InvocationEvent(this, () -> { threadStatus = true; throw sampleExn; }, lock, true);
113         invoc.dispatch();
114         if (!threadStatus) {
115             synchronized (lock) {
116                 lock.wait(delay);
117             }
118         }
119         // testing getException() when exception is thrown
120         // Should return the same exception thrown inside the run() method
121         if (!invoc.getException().equals(sampleExn)) {
122             throw new RuntimeException("getException() does not return " +
123                     "the same Exception thrown inside the run() method ");
124         }
125         threadStatus = false;
126 
127         // Testing assertions 4 and 5:
128         // 4.When InvocationEvent object is posted on to the EventQueue,
129         //   InvocationEvent.dispatch() method should be invoked by the
130         //   EventQueue.
131         // 5.If the notifier object is not null, notifyAll() of the
132         //   notifier object should be invoked when the run() method returns.
133 
134         Thread notify = new Thread(){
135             public void run() {
136                 synchronized (this) {
137                     try { wait(); } catch (InterruptedException e) { throw new RuntimeException(e); }
138                 }
139                 notifierStatus = true;
140                 synchronized (notifierLock) {
141                     notifierLock.notifyAll();
142                 }
143             }
144         };
145         notify.start();
146 
147         while (notify.getState() != Thread.State.WAITING)
148             Thread.sleep(delay/5);
149 
150         InvocationEvent invocation = new InvocationEvent(this, () -> { }, (Object) notify, false);
151         eventQ1.postEvent(invocation);
152 
153         while(!invocation.isDispatched())
154             synchronized (notifierLock) {
155                 notifierLock.wait(delay);
156             }
157 
158         while (notify.getState() != Thread.State.TERMINATED)
159             Thread.sleep(delay/5);
160 
161         if (!notifierStatus) {
162             throw new RuntimeException("Notifier object did not get notified" +
163                     " When the run method of the Runnable returns ");
164         }
165 
166         // Testing assertion 6:
167         // 6.To test whether the threads are invoked in the right order
168         //   When InvocationEvents are nested.
169         Thread thread = new Thread(){
170             public void run() {
171                 InvocationEvent evt = new InvocationEvent(this, () -> { childInvoked = true; }, (Object) this, false);
172                 new EventQueue().postEvent(evt);
173                 synchronized (this) {
174                     try {
175                         wait(delay);
176                     } catch (InterruptedException e) {
177                         throw new RuntimeException(e);
178                     }
179                 }
180                 threadStatus = true;
181             }
182         };
183 
184         invocation = new InvocationEvent(this, thread, lock, false);
185 
186         eventQ1.postEvent(invocation);
187 
188         while (!invocation.isDispatched())
189             synchronized (lock) {
190                 lock.wait(delay);
191             }
192 
193         if (!threadStatus || !childInvoked) {
194             throw new RuntimeException("Nesting of InvocationEvents when dispatched," +
195                     " did not invoke the run() of the Runnables properly ");
196         }
197     }
198 
main(String[] args)199     public static void main(String[] args) throws Exception {
200         new InvocationEventTest().doTest();
201     }
202 }
203 
204