001: /*
002: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package com.sun.midp.jump.push.executive;
026:
027: import com.sun.midp.jump.push.executive.persistence.StoreUtils;
028: import junit.framework.*;
029: import com.sun.midp.jump.push.executive.persistence.Store;
030: import java.io.IOException;
031: import java.util.Map;
032: import javax.microedition.io.ConnectionNotFoundException;
033:
034: public final class AlarmControllerTest extends TestCase {
035:
036: public AlarmControllerTest(String testName) {
037: super (testName);
038: }
039:
040: private static Store createStore() throws IOException {
041: return StoreUtils.createInMemoryPushStore();
042: }
043:
044: private static AlarmController createAlarmController(
045: final Store store, final LifecycleAdapter lifecycleAdapter)
046: throws IOException {
047: return new AlarmController(store, lifecycleAdapter);
048: }
049:
050: private static AlarmController createAlarmController(
051: final LifecycleAdapter lifecycleAdapter) throws IOException {
052: return createAlarmController(createStore(), lifecycleAdapter);
053: }
054:
055: private static AlarmController createAlarmController(
056: final Store store) throws IOException {
057: return createAlarmController(store,
058: new ListingLifecycleAdapter());
059: }
060:
061: private static AlarmController createAlarmController()
062: throws IOException {
063: return createAlarmController(createStore());
064: }
065:
066: private static long registerAlarmWithDelta(
067: final AlarmController alarmController,
068: final int midletSuiteID, final String midlet,
069: final long delta) throws ConnectionNotFoundException {
070: return alarmController.registerAlarm(midletSuiteID, midlet,
071: System.currentTimeMillis() + delta);
072: }
073:
074: public void testFirstRegistration() throws IOException {
075: final int DUMMY_SUITE_ID = 13;
076: final String DUMMY_MIDLET = "foo.bar.Dummy";
077:
078: final AlarmController alarmController = createAlarmController();
079: final long previous = alarmController.registerAlarm(
080: DUMMY_SUITE_ID, DUMMY_MIDLET, 239L);
081: alarmController.dispose();
082:
083: assertEquals(0L, previous);
084: }
085:
086: public void testSuiteWithNoAlarmsUninstallingA() throws IOException {
087: final int DUMMY_SUITE_ID = 13;
088:
089: final AlarmController alarmController = createAlarmController();
090: alarmController.removeSuiteAlarms(DUMMY_SUITE_ID);
091: alarmController.dispose();
092: }
093:
094: public void testSuiteWithNoAlarmsUninstallingB() throws IOException {
095: final int DUMMY_SUITE_ID = 13;
096: final String DUMMY_MIDLET = "foo.bar.Dummy";
097:
098: final int ANOTHER_SUITE_ID = 17; // should be different from DUMMY_MIDLET
099: assert DUMMY_SUITE_ID != ANOTHER_SUITE_ID;
100:
101: final AlarmController alarmController = createAlarmController();
102: alarmController.registerAlarm(DUMMY_SUITE_ID, DUMMY_MIDLET,
103: 239L);
104: alarmController.removeSuiteAlarms(ANOTHER_SUITE_ID);
105: alarmController.dispose();
106: }
107:
108: public void testSuiteWithSeveralMidletsUninstall()
109: throws IOException {
110: final int MIDLET_SUITE_ID = 17;
111: final String MIDLET_1 = "com.sun.Foo";
112: final String MIDLET_2 = "com.sun.Bar";
113: final String MIDLET_3 = "com.sun.Qux";
114:
115: final AlarmController alarmController = createAlarmController();
116:
117: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
118: MIDLET_1, 1001L);
119: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
120: MIDLET_2, 2001L);
121: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
122: MIDLET_3, 3001L);
123: alarmController.removeSuiteAlarms(MIDLET_SUITE_ID);
124: alarmController.dispose();
125: }
126:
127: public void testAlarmFired() throws IOException,
128: InterruptedException {
129: final long ALARM_DELTA = 101L; // in ms
130: final long WAIT_DELAY = 3 * ALARM_DELTA;
131:
132: final int MIDLET_SUITE_ID = 17;
133: final String MIDLET = "com.sun.Foo";
134:
135: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
136:
137: final AlarmController alarmController = createAlarmController(lifecycleAdapter);
138:
139: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
140: MIDLET, ALARM_DELTA);
141: Thread.sleep(WAIT_DELAY);
142: alarmController.dispose();
143:
144: assertTrue(lifecycleAdapter.hasBeenInvokedOnceFor(
145: MIDLET_SUITE_ID, MIDLET));
146: }
147:
148: private static class FiredChecker {
149: final ListingLifecycleAdapter lifecycleAdapter;
150: final int midletSuiteID;
151: final String midlet;
152: final AlarmController alarmController;
153:
154: FiredChecker(final int midletSuiteID, final String midlet)
155: throws IOException {
156: this .midletSuiteID = midletSuiteID;
157: this .midlet = midlet;
158: this .lifecycleAdapter = new ListingLifecycleAdapter();
159: this .alarmController = createAlarmController(lifecycleAdapter);
160: }
161:
162: FiredChecker(final Store store, final int midletSuiteID,
163: final String midlet) throws IOException {
164: this .midletSuiteID = midletSuiteID;
165: this .midlet = midlet;
166: this .lifecycleAdapter = new ListingLifecycleAdapter();
167: this .alarmController = createAlarmController(store,
168: lifecycleAdapter);
169: }
170:
171: long registerCheckedAlarm(final long delta)
172: throws ConnectionNotFoundException {
173: return registerAlarmWithDelta(alarmController,
174: midletSuiteID, midlet, delta);
175: }
176:
177: boolean hasBeenFired() {
178: return lifecycleAdapter.hasBeenInvokedOnceFor(
179: midletSuiteID, midlet);
180: }
181: }
182:
183: public void testSecondRegistration() throws IOException {
184: final int MIDLET_SUITE_ID = 17;
185: final String MIDLET = "com.sun.Foo";
186:
187: final FiredChecker firedChecker = new FiredChecker(
188: MIDLET_SUITE_ID, MIDLET);
189:
190: final AlarmController alarmController = firedChecker.alarmController;
191:
192: /*
193: * IMPL_NOTE: ALARM_TIME below must be big enough for alarm not
194: * to fire before second registration
195: */
196: final long ALARM_TIME = System.currentTimeMillis() + 10239L;
197: alarmController.registerAlarm(MIDLET_SUITE_ID, MIDLET,
198: ALARM_TIME);
199:
200: final long previous = alarmController.registerAlarm(
201: MIDLET_SUITE_ID, MIDLET, 2 * ALARM_TIME);
202: if (firedChecker.hasBeenFired()) {
203: fail("Test is not reliable: the alarm has been fired. Please, increase ALARM_TIME");
204: }
205: alarmController.dispose();
206:
207: assertEquals(ALARM_TIME, previous);
208: }
209:
210: public void testUninstall() throws IOException,
211: InterruptedException {
212: /*
213: * ALARM_DELTA should be big enough for removeSuiteAlarms to finish
214: */
215: final long ALARM_DELTA = 1001L; // in ms
216: final long WAIT_DELAY = 3 * ALARM_DELTA;
217:
218: final int MIDLET_SUITE_ID = 17;
219: final String MIDLET = "com.sun.Foo";
220:
221: final FiredChecker firedChecker = new FiredChecker(
222: MIDLET_SUITE_ID, MIDLET);
223:
224: final AlarmController alarmController = firedChecker.alarmController;
225:
226: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
227: MIDLET, ALARM_DELTA);
228: alarmController.removeSuiteAlarms(MIDLET_SUITE_ID);
229: if (firedChecker.hasBeenFired()) {
230: fail("Test is not reliable: the alarm has been fired. Please, increase ALARM_DELTA");
231: }
232: Thread.sleep(WAIT_DELAY);
233:
234: alarmController.dispose();
235:
236: assertFalse(firedChecker.hasBeenFired());
237: }
238:
239: private void registerAndWait(final FiredChecker firedChecker)
240: throws ConnectionNotFoundException, InterruptedException {
241: final long ALARM_DELTA = 101L; // in ms
242: final long WAIT_DELAY = 3 * ALARM_DELTA;
243:
244: firedChecker.registerCheckedAlarm(ALARM_DELTA);
245: Thread.sleep(WAIT_DELAY);
246: if (!firedChecker.hasBeenFired()) {
247: fail("Test is not reliable: the alarm hasn't been fired");
248: }
249: }
250:
251: public void testResetAfterFiring() throws IOException,
252: InterruptedException {
253: final FiredChecker firedChecker = new FiredChecker(17,
254: "com.sun.Foo");
255:
256: registerAndWait(firedChecker);
257: final long previous = firedChecker.registerCheckedAlarm(10001L);
258: firedChecker.alarmController.dispose();
259:
260: assertEquals(0L, previous);
261: }
262:
263: private static boolean checkNoAlarms(final Store store) {
264: final boolean noAlarms[] = { true };
265: store.listAlarms(new Store.AlarmsConsumer() {
266: public void consume(final int suiteId, final Map alarms) {
267: /*
268: * NOTE: store shouldn't report suites without alarms
269: * (empty map)
270: */
271: noAlarms[0] = false;
272: }
273: });
274: return noAlarms[0];
275: }
276:
277: public void testNoRecordAfterFiring() throws IOException,
278: InterruptedException {
279: final Store store = createStore();
280: final FiredChecker firedChecker = new FiredChecker(store, 17,
281: "com.sun.Foo");
282:
283: registerAndWait(firedChecker);
284: firedChecker.alarmController.dispose();
285:
286: assertTrue(checkNoAlarms(store));
287: }
288:
289: public void testNotFiredStored() throws IOException,
290: InterruptedException {
291: final int MIDLET_SUITE_ID = 17;
292: final String MIDLET = "com.sun.Foo";
293:
294: final Store store = createStore();
295: final FiredChecker firedChecker = new FiredChecker(store,
296: MIDLET_SUITE_ID, MIDLET);
297:
298: final long time = System.currentTimeMillis() + 1001L;
299: firedChecker.alarmController.registerAlarm(MIDLET_SUITE_ID,
300: MIDLET, time);
301: firedChecker.alarmController.dispose();
302: if (firedChecker.hasBeenFired()) {
303: fail("Test is not reliable: the alarm has been fired");
304: }
305:
306: final boolean alarmPresent[] = { false };
307: final boolean otherAlarmsPresent[] = { false };
308: store.listAlarms(new Store.AlarmsConsumer() {
309: public void consume(final int suiteId, final Map alarms) {
310: if (suiteId != MIDLET_SUITE_ID) {
311: otherAlarmsPresent[0] = true;
312: return;
313: }
314: if (alarms.size() > 1) {
315: otherAlarmsPresent[0] = true;
316: return;
317: }
318: final Long t = (Long) alarms.get(MIDLET);
319: if ((t == null) || (t.longValue() != time)) {
320: otherAlarmsPresent[0] = true;
321: return;
322: }
323: alarmPresent[0] = true;
324: }
325: });
326: assertTrue(alarmPresent[0]);
327: assertFalse(otherAlarmsPresent[0]);
328: }
329:
330: public void testAlarmRecordRead() throws IOException,
331: InterruptedException {
332: final int MIDLET_SUITE_ID = 17;
333: final String MIDLET = "com.sun.Foo";
334:
335: final Store store = createStore();
336: final long time = System.currentTimeMillis() + 501L;
337: store.addAlarm(MIDLET_SUITE_ID, MIDLET, time);
338:
339: final FiredChecker firedChecker = new FiredChecker(store,
340: MIDLET_SUITE_ID, MIDLET);
341:
342: Thread.sleep(3 * (time - System.currentTimeMillis()));
343: firedChecker.alarmController.dispose();
344: assertTrue(firedChecker.hasBeenFired());
345: }
346:
347: public void testPassedAlarmImmediatelyScheduled()
348: throws IOException, InterruptedException {
349: final int MIDLET_SUITE_ID = 17;
350: final String MIDLET = "com.sun.Foo";
351:
352: final Store store = createStore();
353: final long time = System.currentTimeMillis() - 501L;
354: store.addAlarm(MIDLET_SUITE_ID, MIDLET, time);
355:
356: final FiredChecker firedChecker = new FiredChecker(store,
357: MIDLET_SUITE_ID, MIDLET);
358:
359: Thread.sleep(101L); // just a small delta
360: firedChecker.alarmController.dispose();
361: assertTrue(firedChecker.hasBeenFired());
362: }
363:
364: public void testSuiteUninstallPersistentStore() throws IOException {
365: final int MIDLET_SUITE_ID = 17;
366: final String MIDLET_1 = "com.sun.Foo";
367: final String MIDLET_2 = "com.sun.Bar";
368:
369: final Store store = createStore();
370: final AlarmController alarmController = createAlarmController(store);
371:
372: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
373: MIDLET_1, 1001L);
374: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
375: MIDLET_2, 2001L);
376: alarmController.removeSuiteAlarms(MIDLET_SUITE_ID);
377: alarmController.dispose();
378:
379: assertTrue(checkNoAlarms(store));
380: }
381:
382: public void testSuiteUninstallPersistentStore2()
383: throws IOException, InterruptedException {
384: final int MIDLET_SUITE_ID_1 = 17;
385: final String MIDLET_11 = "com.sun.Foo";
386: final long DELTA = 47L;
387: final String MIDLET_12 = "com.sun.Bar";
388:
389: final int MIDLET_SUITE_ID_2 = 13;
390: final String MIDLET_21 = "com.sun.Qux";
391:
392: final Store store = createStore();
393: final FiredChecker firedChecker = new FiredChecker(store,
394: MIDLET_SUITE_ID_1, MIDLET_11);
395:
396: registerAlarmWithDelta(firedChecker.alarmController,
397: MIDLET_SUITE_ID_1, MIDLET_11, DELTA);
398: registerAlarmWithDelta(firedChecker.alarmController,
399: MIDLET_SUITE_ID_2, MIDLET_21, 3001L);
400: registerAlarmWithDelta(firedChecker.alarmController,
401: MIDLET_SUITE_ID_1, MIDLET_12, 2001L);
402: Thread.sleep(3 * DELTA);
403: firedChecker.alarmController.dispose();
404: if (!firedChecker.hasBeenFired()) {
405: fail("Test is not reliable: the alarm hasn't been fired");
406: }
407:
408: final boolean[] suite1ok = { false };
409: final boolean[] suite2ok = { false };
410: final boolean[] noOthers = { true };
411: store.listAlarms(new Store.AlarmsConsumer() {
412: public void consume(final int suiteId, final Map alarms) {
413: switch (suiteId) {
414: case MIDLET_SUITE_ID_1:
415: if (alarms.size() > 1) {
416: noOthers[0] = false;
417: } else if (alarms.containsKey(MIDLET_12)) {
418: suite1ok[0] = true;
419: }
420: break;
421:
422: case MIDLET_SUITE_ID_2:
423: if (alarms.size() > 1) {
424: noOthers[0] = false;
425: } else if (alarms.containsKey(MIDLET_21)) {
426: suite2ok[0] = true;
427: }
428: break;
429:
430: default:
431: noOthers[0] = false;
432: }
433: }
434: });
435: assertTrue("Suite 1 is incorrect", suite1ok[0]);
436: assertTrue("Suite 2 is incorrect", suite2ok[0]);
437: assertTrue("Unexpected registrations", noOthers[0]);
438: }
439:
440: public void testCoupleMidletFirstRegistration() throws IOException {
441: final long ALARM_DELTA = 1001L; // in ms
442:
443: final int MIDLET_SUITE_ID = 17;
444: final String MIDLET_1 = "com.sun.Foo";
445: final String MIDLET_2 = "com.sun.Bar";
446:
447: final FiredChecker firedChecker = new FiredChecker(
448: MIDLET_SUITE_ID, MIDLET_1);
449: final AlarmController alarmController = firedChecker.alarmController;
450:
451: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
452: MIDLET_1, ALARM_DELTA);
453: final long previous = registerAlarmWithDelta(alarmController,
454: MIDLET_SUITE_ID, MIDLET_2, 2 * ALARM_DELTA);
455: if (firedChecker.hasBeenFired()) {
456: fail("Test is not reliable: the alarm has been fired. Please, increase ALARM_DELTA");
457: }
458:
459: alarmController.dispose();
460:
461: assertEquals(0L, previous);
462: }
463:
464: public void testThrowingLifecycleAdapter() throws IOException,
465: InterruptedException {
466: final long ALARM_DELTA = 101L; // in ms
467: final long WAIT_DELAY = 3 * ALARM_DELTA;
468:
469: final int MIDLET_SUITE_ID = 17;
470: final String MIDLET = "com.sun.Foo";
471:
472: final ListingLifecycleAdapter listingLifecycleAdapter = new ListingLifecycleAdapter();
473:
474: final LifecycleAdapter throwingLifecycleAdapter = new ThrowingLifecycleAdapter();
475:
476: final ProxyLifecycleAdapter lifecycleAdapter = new ProxyLifecycleAdapter();
477:
478: final AlarmController alarmController = createAlarmController(lifecycleAdapter);
479:
480: lifecycleAdapter.lifecycleAdapter = throwingLifecycleAdapter;
481: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
482: MIDLET, ALARM_DELTA);
483: Thread.sleep(WAIT_DELAY);
484:
485: // And now check that everything is ok despite of previously thrown adapter
486: lifecycleAdapter.lifecycleAdapter = listingLifecycleAdapter;
487: registerAlarmWithDelta(alarmController, MIDLET_SUITE_ID,
488: MIDLET, ALARM_DELTA);
489: Thread.sleep(WAIT_DELAY);
490: alarmController.dispose();
491:
492: assertTrue(listingLifecycleAdapter.hasBeenInvokedOnceFor(
493: MIDLET_SUITE_ID, MIDLET));
494: }
495: }
|