blob: a605fbe30f9cd654a5b9e3ce699e20ce9225f8b6 [file] [log] [blame]
Felix Meschberger9d365712010-10-27 07:05:42 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * 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,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.coordination.impl;
20
21import org.apache.felix.service.coordination.Coordination;
22import org.apache.felix.service.coordination.CoordinationException;
23import org.apache.felix.service.coordination.Participant;
24
25import junit.framework.TestCase;
26
27@SuppressWarnings("deprecation")
28public class CoordinatorImplTest extends TestCase
29{
30
31 private CoordinationMgr mgr;
32 private CoordinatorImpl coordinator;
33
34 @Override
35 protected void setUp() throws Exception
36 {
37 super.setUp();
38
39 mgr = new CoordinationMgr();
40 coordinator = new CoordinatorImpl(null, mgr);
41 }
42
43 public void test_createCoordination()
44 {
45 final String name = "test";
46 final Coordination c1 = coordinator.create(name);
47 assertNotNull(c1);
48 assertEquals(name, c1.getName());
49 assertNull(coordinator.getCurrentCoordination());
50 assertFalse(c1.isFailed());
51 assertFalse(c1.isTerminated());
52 assertTrue(c1.getParticipants().isEmpty());
53
54 assertTrue(c1.fail(new Exception()));
55 assertTrue(c1.isFailed());
56 assertTrue(c1.isTerminated());
57 assertNull(coordinator.getCurrentCoordination());
58
59 assertFalse(c1.fail(new Exception()));
60 try
61 {
62 c1.end();
63 fail("Expected IllegalStateException on end() after fail()");
64 }
65 catch (IllegalStateException ise)
66 {
67 // expected
68 }
69
70 final Coordination c2 = coordinator.create(name);
71 assertNotNull(c2);
72 assertEquals(name, c2.getName());
73 assertNull(coordinator.getCurrentCoordination());
74 assertFalse(c2.isFailed());
75 assertFalse(c2.isTerminated());
76 assertTrue(c2.getParticipants().isEmpty());
77
78 assertEquals(Coordination.OK, c2.end());
79 assertFalse(c2.isFailed());
80 assertTrue(c2.isTerminated());
81 assertNull(coordinator.getCurrentCoordination());
82
83 assertFalse(c2.fail(new Exception()));
84 try
85 {
86 c2.end();
87 fail("Expected IllegalStateException on second end()");
88 }
89 catch (IllegalStateException ise)
90 {
91 // expected
92 }
93 }
94
95 public void test_beginCoordination()
96 {
97 final String name = "test";
98 final Coordination c1 = coordinator.begin(name);
99 assertNotNull(c1);
100 assertEquals(name, c1.getName());
101
102 assertEquals(c1, coordinator.getCurrentCoordination());
103 assertEquals(c1, coordinator.pop());
104
105 assertNull(coordinator.getCurrentCoordination());
106 coordinator.push(c1);
107 assertEquals(c1, coordinator.getCurrentCoordination());
108
109 c1.end();
110 assertNull(coordinator.getCurrentCoordination());
111
112 final Coordination c2 = coordinator.begin(name);
113 assertNotNull(c2);
114 assertEquals(name, c2.getName());
115 assertEquals(c2, coordinator.getCurrentCoordination());
116 c2.fail(null);
117 assertNull(coordinator.getCurrentCoordination());
118 }
119
120 public void test_beginCoordination_stack()
121 {
122 final String name = "test";
123
124 final Coordination c1 = coordinator.begin(name);
125 assertNotNull(c1);
126 assertEquals(name, c1.getName());
127 assertEquals(c1, coordinator.getCurrentCoordination());
128
129 final Coordination c2 = coordinator.begin(name);
130 assertNotNull(c2);
131 assertEquals(name, c2.getName());
132 assertEquals(c2, coordinator.getCurrentCoordination());
133
134 c2.end();
135 assertEquals(c1, coordinator.getCurrentCoordination());
136
137 c1.end();
138 assertNull(coordinator.getCurrentCoordination());
139 }
140
141 public void test_beginCoordination_stack2()
142 {
143 final String name = "test";
144
145 final Coordination c1 = coordinator.begin(name);
146 assertNotNull(c1);
147 assertEquals(name, c1.getName());
148 assertEquals(c1, coordinator.getCurrentCoordination());
149
150 final Coordination c2 = coordinator.begin(name);
151 assertNotNull(c2);
152 assertEquals(name, c2.getName());
153 assertEquals(c2, coordinator.getCurrentCoordination());
154
155 c1.end();
156 assertEquals(c2, coordinator.getCurrentCoordination());
157
158 c2.end();
159 assertNull(coordinator.getCurrentCoordination());
160 }
161
162 public void test_participate_with_ended()
163 {
164 final String name = "test";
165 final Coordination c1 = coordinator.create(name);
166
167 final MockParticipant p1 = new MockParticipant();
168 c1.participate(p1);
169 assertTrue(c1.getParticipants().contains(p1));
170 assertEquals(1, c1.getParticipants().size());
171
172 c1.end();
173 assertTrue(p1.ended);
174 assertFalse(p1.failed);
175 assertEquals(c1, p1.c);
176
177 // assert order of call
178 final Coordination c2 = coordinator.create(name);
179 final MockParticipant p21 = new MockParticipant();
180 final MockParticipant p22 = new MockParticipant();
181 c2.participate(p21);
182 c2.participate(p22);
183 assertTrue(c2.getParticipants().contains(p21));
184 assertTrue(c2.getParticipants().contains(p22));
185 assertEquals(2, c2.getParticipants().size());
186
187 c2.end();
188 assertTrue(p21.ended);
189 assertEquals(c2, p21.c);
190 assertTrue(p22.ended);
191 assertEquals(c2, p22.c);
192 assertTrue("p21 must be called before p22", p21.time < p22.time);
193
194 // assert order of call with two registrations
195 final Coordination c3 = coordinator.create(name);
196 final MockParticipant p31 = new MockParticipant();
197 final MockParticipant p32 = new MockParticipant();
198 c3.participate(p31);
199 c3.participate(p32);
200 c3.participate(p31); // should be "ignored"
201 assertTrue(c3.getParticipants().contains(p31));
202 assertTrue(c3.getParticipants().contains(p32));
203 assertEquals(2, c3.getParticipants().size());
204
205 c3.end();
206 assertTrue(p31.ended);
207 assertEquals(c3, p31.c);
208 assertTrue(p32.ended);
209 assertEquals(c3, p32.c);
210 assertTrue("p21 must be called before p22", p31.time < p32.time);
211 }
212
213 public void test_participate_with_failed()
214 {
215 final String name = "test";
216 final Coordination c1 = coordinator.create(name);
217
218 final MockParticipant p1 = new MockParticipant();
219 c1.participate(p1);
220 assertTrue(c1.getParticipants().contains(p1));
221 assertEquals(1, c1.getParticipants().size());
222
223 c1.fail(null);
224 assertFalse(p1.ended);
225 assertTrue(p1.failed);
226 assertEquals(c1, p1.c);
227
228 // assert order of call
229 final Coordination c2 = coordinator.create(name);
230 final MockParticipant p21 = new MockParticipant();
231 final MockParticipant p22 = new MockParticipant();
232 c2.participate(p21);
233 c2.participate(p22);
234 assertTrue(c2.getParticipants().contains(p21));
235 assertTrue(c2.getParticipants().contains(p22));
236 assertEquals(2, c2.getParticipants().size());
237
238 c2.fail(null);
239 assertTrue(p21.failed);
240 assertEquals(c2, p21.c);
241 assertTrue(p22.failed);
242 assertEquals(c2, p22.c);
243 assertTrue("p21 must be called before p22", p21.time < p22.time);
244
245 // assert order of call with two registrations
246 final Coordination c3 = coordinator.create(name);
247 final MockParticipant p31 = new MockParticipant();
248 final MockParticipant p32 = new MockParticipant();
249 c3.participate(p31);
250 c3.participate(p32);
251 c3.participate(p31); // should be "ignored"
252 assertTrue(c3.getParticipants().contains(p31));
253 assertTrue(c3.getParticipants().contains(p32));
254 assertEquals(2, c3.getParticipants().size());
255
256 c3.fail(null);
257 assertTrue(p31.failed);
258 assertEquals(c3, p31.c);
259 assertTrue(p32.failed);
260 assertEquals(c3, p32.c);
261 assertTrue("p21 must be called before p22", p31.time < p32.time);
262 }
263
264 public void test_Coordination_timeout() throws InterruptedException
265 {
266 final String name = "test";
267 final Coordination c1 = coordinator.create(name);
268 final MockParticipant p1 = new MockParticipant();
269 c1.participate(p1);
270 assertTrue(c1.getParticipants().contains(p1));
271 assertEquals(1, c1.getParticipants().size());
272
273 // set a short timeout and wait for it to pass
274 c1.addTimeout(100);
275 Thread.sleep(150);
276
277 // expect coordination to have terminated
278 assertTrue(c1.isTerminated());
279 assertTrue(c1.isFailed());
280
281 // expect Participant.failed() being called
282 assertTrue(p1.failed);
283 assertEquals(c1, p1.c);
284 }
285
286 public void test_Coordination_participate_timeout() throws InterruptedException
287 {
288 final String name1 = "test1";
289 final String name2 = "test2";
290 final MockParticipant p1 = new MockParticipant();
291
292 // ensure short timeout for participation
293 mgr.configure(60000, 200);
294
295 final Coordination c1 = coordinator.create(name1);
296 c1.participate(p1);
297 assertTrue(c1.getParticipants().contains(p1));
298 assertEquals(1, c1.getParticipants().size());
299
300 // preset p1PartFailure to be be sure the participation actually starts
301 p1.participateFailure(new Exception("Not Started yet"));
302
303 Thread c2Thread = new Thread()
304 {
305 public void run()
306 {
307 final Coordination c2 = coordinator.create(name2);
308 try
309 {
310 p1.participateFailure(null);
311 c2.participate(p1);
312 }
313 catch (Throwable t)
314 {
315 p1.participateFailure(t);
316 }
317 finally
318 {
319 c2.terminate();
320 }
321 }
322 };
323 c2Thread.start();
324
325 // wait at most 2 seconds for the second thread to terminate
326 // we expect this if the participation properly times out
327 c2Thread.join(2000);
328 assertFalse("Thread for second Coordination did not terminate....", c2Thread.isAlive());
329
330 Throwable p1PartFailure = p1.participateFailure;
331 if (p1PartFailure == null)
332 {
333 fail("Expecting CoordinationException/TIMEOUT for second participation");
334 }
335 else if (p1PartFailure instanceof CoordinationException)
336 {
337 assertEquals(CoordinationException.TIMEOUT, ((CoordinationException) p1PartFailure).getReason());
338 }
339 else
340 {
341 fail("Unexpected Throwable while trying to participate: " + p1PartFailure);
342 }
343
344 c1.terminate();
345
346 // make sure c2Thread has terminated
347 if (c2Thread.isAlive())
348 {
349 c2Thread.interrupt();
350 c2Thread.join(1000);
351 assertFalse("Thread for second Coordination did not terminate....", c2Thread.isAlive());
352 }
353 }
354
355 static final class MockParticipant implements Participant
356 {
357
358 long time;
359
360 Coordination c;
361
362 boolean failed;
363
364 boolean ended;
365
366 Throwable participateFailure;
367
368 public void failed(Coordination c) throws Exception
369 {
370 this.failed = true;
371 this.c = c;
372 this.time = System.nanoTime();
373 }
374
375 public void ended(Coordination c) throws Exception
376 {
377 this.ended = true;
378 this.c = c;
379 this.time = System.nanoTime();
380 }
381
382 void participateFailure(Throwable t)
383 {
384 this.participateFailure = t;
385 }
386 }
387}