Initial import
[jpf-core.git] / src / tests / gov / nasa / jpf / test / vm / threads / InterruptTest.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.test.vm.threads;
19
20 import gov.nasa.jpf.util.test.TestJPF;
21
22 import java.util.concurrent.locks.LockSupport;
23
24 import org.junit.Test;
25
26 /**
27  * raw test for Thread.interrupt conformance
28  */
29 public class InterruptTest extends TestJPF {
30
31   @Test public void testInterruptStatus () {
32     if (verifyNoPropertyViolation()) {
33       Thread t = Thread.currentThread();
34
35       assert !t.isInterrupted() : "initial interrupt status is set";
36
37       System.out.println("setting interrupt status");
38       t.interrupt();
39
40       assert t.isInterrupted() : "interrupt status not set";
41
42       System.out.println("query and clear interrupt status");
43       assert Thread.interrupted() : "interrupt status prematurely reset";
44
45       assert !Thread.interrupted() : "interrupt status wasn't reset";
46     }
47   }
48
49   @Test public void testWaitSyncInterrupt() {
50     if (verifyNoPropertyViolation()) {
51       Runnable r = new Runnable() {
52
53         @Override
54                 public void run() {
55
56           // doesn't matter from where we interrupt (thread can interrupt itself)
57           Thread t = Thread.currentThread();
58           t.interrupt();
59
60           synchronized (this) {
61             // if we don't enter here, this should be reported as a deadlock
62
63             System.out.println("T waiting");
64             try {
65               wait(); // this should immediately throw, i.e. return
66               assert false : "wait() did not throw InterruptedException";
67             } catch (InterruptedException ix) {
68               ix.printStackTrace(); // should include Object.wait()
69               System.out.println("T interrupted, terminating");
70               assert !t.isInterrupted() : "throw didn't reset interrupt status";
71               return;
72             } catch (Throwable x) {
73               assert false : "wait did throw wrong exception: " + x;
74               return;
75             }
76           }
77           assert false : "should never get here";
78         }
79       };
80
81       Thread t1 = new Thread(r);
82
83       t1.interrupt(); // should have no effect - it's not runnable yet
84       assert !t1.isInterrupted() : "non-started thread has interrupt status set";
85
86       t1.start();
87       System.out.println("main terminated");
88     }
89   }
90
91   @Test public void testWaitAsyncInterrupt() {
92     if (verifyNoPropertyViolation()) {
93       Runnable r = new Runnable() {
94
95         @Override
96                 public void run() {
97           synchronized (this) {
98             // if we don't enter here, this should be reported as a deadlock
99             try {
100               System.out.println("T waiting");
101               wait();
102               assert false : "wait() did not throw InterruptedException";
103             } catch (InterruptedException ix) {
104               ix.printStackTrace(); // should include Object.wait()
105               System.out.println("T interrupted, terminating");
106               assert !Thread.currentThread().isInterrupted() : "throw didn't reset interrupt status";
107               return;
108             } catch (Throwable x) {
109               assert false : "wait did throw wrong exception: " + x;
110               return;
111             }
112           }
113           assert false : "should never get here";
114         }
115       };
116
117       Thread t1 = new Thread(r);
118       t1.start();
119
120       // no matter if this is executed before or after t1 enters Object.wait()
121       // it should terminate it by throwing. In fact, JPF should explore both
122       // paths
123       System.out.println("main interrupting t1");
124       t1.interrupt();
125
126       System.out.println("main terminated");
127     }
128   }
129
130   boolean interrupted;
131   boolean waiting;
132
133   @Test public void testBlockedWaitAsyncInterrupt() {
134     if (verifyNoPropertyViolation()) {
135
136       interrupted = false;
137       waiting = false;
138
139       Runnable r = new Runnable() {
140
141         @Override
142                 public void run() {
143           synchronized (this) {
144             // if we don't enter here, this should be reported as a deadlock
145             try {
146               System.out.println("T waiting");
147               waiting = true;
148               wait();
149               assert false : "wait() did not throw InterruptedException";
150             } catch (InterruptedException ix) {
151               ix.printStackTrace(); // should include Object.wait()
152               assert !Thread.currentThread().isInterrupted() : "throw didn't reset interrupt status";
153               System.out.println("T interrupted, terminating");
154               interrupted = true;
155               return;
156             } catch (Throwable x) {
157               assert false : "wait did throw wrong exception: " + x;
158               return;
159             }
160           }
161           assert false : "should never get here";
162         }
163       };
164
165       Thread t1 = new Thread(r);
166       t1.start();
167
168       while (!waiting) {
169         Thread.yield();
170       }
171
172       synchronized (r) {
173         System.out.println("main interrupting t1");
174         t1.interrupt();
175
176         // t1 can't run before we release the lock
177         Thread.yield(); // this shouldn't reschedule, t1 is blocked
178         assert !interrupted : "t1 prematurely scheduled w/o acquiring the lock";
179         System.out.println("main terminated, t1 runnable again");
180       }
181     }
182   }
183
184   @Test public void testPark() {
185     if (verifyNoPropertyViolation()) {
186
187       interrupted = false;
188
189       Thread t1 = new Thread(new Runnable() {
190
191         @Override
192                 public void run() {
193           System.out.println("T parking..");
194           LockSupport.park();
195           interrupted = true;
196           System.out.println("T terminated");
197         }
198       });
199
200       t1.start();
201
202       System.out.println("main interrupting");
203       t1.interrupt();
204
205       try {
206         System.out.println("main joining t1..");
207         t1.join();
208         System.out.println("main joined t1");
209       } catch (InterruptedException e) {
210         assert false : "t1.join() interrupted in main";
211       }
212
213       assert interrupted : "LockSupport.park() didn't get interrupted";
214       System.out.println("main terminated");
215     }
216   }
217
218 }