create changelog entry
[debian/openrocket] / core / test / net / sf / openrocket / util / TestMutex.java
1 package net.sf.openrocket.util;
2
3 import static org.junit.Assert.*;
4
5 import org.junit.Before;
6 import org.junit.Test;
7
8 public class TestMutex {
9         
10         @Before
11         public void setup() {
12                 System.setProperty("openrocket.debug.safetycheck", "true");
13         }
14         
15         @Test
16         public void testSingleLocking() {
17                 SafetyMutex.ConcreteSafetyMutex m = new SafetyMutex.ConcreteSafetyMutex();
18                 
19                 // Test single locking
20                 assertNull(m.lockingThread);
21                 m.verify();
22                 m.lock("here");
23                 assertNotNull(m.lockingThread);
24                 assertTrue(m.unlock("here"));
25                 
26         }
27         
28         @Test
29         public void testDoubleLocking() {
30                 SafetyMutex.ConcreteSafetyMutex m = new SafetyMutex.ConcreteSafetyMutex();
31                 
32                 // Test double locking
33                 m.verify();
34                 m.lock("foobar");
35                 m.verify();
36                 m.lock("bazqux");
37                 m.verify();
38                 assertTrue(m.unlock("bazqux"));
39                 m.verify();
40                 assertTrue(m.unlock("foobar"));
41                 m.verify();
42         }
43         
44         @Test
45         public void testDoubleUnlocking() {
46                 SafetyMutex.ConcreteSafetyMutex m = new SafetyMutex.ConcreteSafetyMutex();
47                 // Mark error reported to not init exception handler
48                 SafetyMutex.ConcreteSafetyMutex.errorReported = true;
49                 
50                 m.lock("here");
51                 assertTrue(m.unlock("here"));
52                 assertFalse(m.unlock("here"));
53         }
54         
55         
56
57         private volatile int testState = 0;
58         private volatile String failure = null;
59         
60         @Test(timeout = 1000)
61         public void testThreadingErrors() {
62                 final SafetyMutex.ConcreteSafetyMutex m = new SafetyMutex.ConcreteSafetyMutex();
63                 
64                 // Initialize and start the thread
65                 Thread thread = new Thread() {
66                         @Override
67                         public void run() {
68                                 try {
69                                         
70                                         // Test locking a locked mutex
71                                         waitFor(1);
72                                         try {
73                                                 m.lock("in thread one");
74                                                 failure = "Succeeded in locking a mutex locked by a different thread";
75                                                 return;
76                                         } catch (ConcurrencyException e) {
77                                                 // OK
78                                         }
79                                         
80                                         // Test unlocking a mutex locked by a different thread
81                                         if (m.unlock("in thread two")) {
82                                                 failure = "Succeeded in unlocking a mutex locked by a different thread";
83                                                 return;
84                                         }
85                                         
86                                         // Test verifying a locked mutex that already has an error
87                                         try {
88                                                 m.verify();
89                                                 failure = "Succeeded in verifying a mutex locked by a different thread";
90                                                 return;
91                                         } catch (ConcurrencyException e) {
92                                                 // OK
93                                         }
94                                         
95                                         // Test locking a mutex after it's been unlocked
96                                         testState = 2;
97                                         waitFor(3);
98                                         m.lock("in thread three");
99                                         m.verify();
100                                         
101                                         // Wait for other side to test
102                                         testState = 4;
103                                         waitFor(5);
104                                         
105                                         // Exit code
106                                         testState = 6;
107                                         
108                                 } catch (Exception e) {
109                                         failure = "Exception occurred in thread: " + e;
110                                         return;
111                                 }
112                                 
113                         }
114                 };
115                 thread.setDaemon(true);
116                 thread.start();
117                 
118                 m.lock("one");
119                 testState = 1;
120                 
121                 waitFor(2);
122                 assertNull("Thread error: " + failure, failure);
123                 
124                 m.verify();
125                 m.unlock("one");
126                 testState = 3;
127                 
128                 waitFor(4);
129                 assertNull("Thread error: " + failure, failure);
130                 
131                 try {
132                         m.lock("two");
133                         fail("Succeeded in locking a locked mutex in main thread");
134                 } catch (ConcurrencyException e) {
135                         // OK
136                 }
137                 
138                 // Test unlocking a mutex locked by a different thread
139                 assertFalse(m.unlock("here"));
140                 
141                 try {
142                         m.verify();
143                         fail("Succeeded in verifying a locked mutex in main thread");
144                 } catch (ConcurrencyException e) {
145                         // OK
146                 }
147                 
148                 testState = 5;
149                 waitFor(6);
150                 assertNull("Thread error: " + failure, failure);
151         }
152         
153         private void waitFor(int state) {
154                 while (testState != state && failure == null) {
155                         try {
156                                 Thread.sleep(1);
157                         } catch (InterruptedException e) {
158                         }
159                 }
160         }
161         
162         
163         public void testBogusMutex() {
164                 SafetyMutex m = new SafetyMutex.BogusSafetyMutex();
165                 m.lock("foo");
166                 m.lock("bar");
167                 m.lock("baz");
168                 m.verify();
169                 m.unlock("a");
170                 m.unlock(null);
171                 m.unlock("");
172                 m.unlock("c");
173         }
174         
175 }