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: package com.sun.midp.jump.push.executive.persistence;
025:
026: import com.sun.midp.jump.push.executive.JUMPConnectionInfo;
027: import java.io.IOException;
028: import java.util.Arrays;
029: import java.util.HashMap;
030: import java.util.HashSet;
031: import java.util.Map;
032: import junit.framework.TestCase;
033:
034: public final class StoreTest extends TestCase {
035: private static final String[][] SAMPLE_CONNECTIONS = {
036: new String[] { "sms://:500", "com.sun.FooMidlet", "12?4*" },
037: new String[] { "socket://:5000", "com.sun.BarMidlet",
038: "12?4*" },
039: new String[] { "socket://", "com.sun.QuxMidlet", "12?4*" },
040: new String[] { "datagram://:239", "com.sun.QuxMidlet",
041: "???.???*" },
042: new String[] { "datagram://", "com.sun.QuuxMidlet",
043: "???.???*" },
044: new String[] { "socket://:2006", "com.sun.QuuuxMidlet", "*" },
045: new String[] { "datagram://:17", "com.sun.QuuuuxMidlet",
046: "12.34" }, };
047:
048: private static JUMPConnectionInfo createConnectionInfo(
049: final int index) {
050: final String[] info = SAMPLE_CONNECTIONS[index];
051: return new JUMPConnectionInfo(info[0], info[1], info[2]);
052: }
053:
054: private static JUMPConnectionInfo[] createConnectionInfos(
055: final int[] indices) {
056: final JUMPConnectionInfo[] cns = new JUMPConnectionInfo[indices.length];
057: for (int i = 0; i < cns.length; i++) {
058: cns[i] = createConnectionInfo(indices[i]);
059: }
060: return cns;
061: }
062:
063: private static HashSet toSet(final JUMPConnectionInfo[] cns) {
064: return new HashSet(Arrays.asList(cns));
065: }
066:
067: private static class ExpectedConnections {
068: final Map map = new HashMap();
069:
070: ExpectedConnections add(final int suiteId, final int[] indices) {
071: map.put(new Integer(suiteId),
072: toSet(createConnectionInfos(indices)));
073: return this ;
074: }
075: }
076:
077: private static class ExpectedAlarms {
078: final Map map = new HashMap();
079:
080: ExpectedAlarms add(final int suiteId, final String midlet,
081: final long time) {
082: final Integer key = new Integer(suiteId);
083: Map suiteMap = (Map) map.get(key);
084: if (suiteMap == null) {
085: suiteMap = new HashMap();
086: map.put(key, suiteMap);
087: }
088: suiteMap.put(midlet, new Long(time));
089:
090: return this ;
091: }
092: }
093:
094: static private final class Checker {
095: final StoreOperationManager storeManager;
096: final Store store;
097:
098: Checker() throws IOException {
099: final String[] DIRS = { Store.CONNECTIONS_DIR,
100: Store.ALARMS_DIR };
101: storeManager = StoreUtils.createInMemoryManager(DIRS);
102: store = new Store(storeManager);
103: }
104:
105: private void checkConnections(final Store store,
106: final Map expectedConnections) {
107: final Map actual = new HashMap();
108:
109: store.listConnections(new Store.ConnectionsConsumer() {
110: public void consume(final int suiteId,
111: final JUMPConnectionInfo[] cns) {
112: assertNull("reported twice: " + suiteId, actual
113: .put(new Integer(suiteId), toSet(cns)));
114: }
115: });
116:
117: assertEquals(expectedConnections, actual);
118: }
119:
120: private void checkAlarms(final Store store,
121: final Map expectedAlarms) {
122: final Map actual = new HashMap();
123:
124: store.listAlarms(new Store.AlarmsConsumer() {
125: public void consume(final int suiteId, final Map alarms) {
126: assertNull("reported twice: " + suiteId, actual
127: .put(new Integer(suiteId), alarms));
128: }
129: });
130:
131: assertEquals(expectedAlarms, actual);
132: }
133:
134: void checkStore(final Map expectedConnections,
135: final Map expectedAlarms) throws IOException {
136: checkConnections(store, expectedConnections);
137: checkAlarms(store, expectedAlarms);
138:
139: // And check that when the data are reread, we're ok
140: final Store fresh = new Store(storeManager);
141:
142: checkConnections(fresh, expectedConnections);
143: checkAlarms(fresh, expectedAlarms);
144: }
145:
146: void addConnection(final int suiteId, final int connectionIndex)
147: throws IOException {
148: store.addConnection(suiteId,
149: createConnectionInfo(connectionIndex));
150: }
151:
152: void removeConnection(final int suiteId,
153: final int connectionIndex) throws IOException {
154: store.removeConnection(suiteId,
155: createConnectionInfo(connectionIndex));
156: }
157:
158: void addConnections(final int suiteId, final int[] connections)
159: throws IOException {
160: store.addConnections(suiteId,
161: createConnectionInfos(connections));
162: }
163:
164: void removeConnections(final int suiteId) throws IOException {
165: store.removeConnections(suiteId);
166: }
167:
168: void addAlarm(final int suiteId, final String midlet,
169: final long time) throws IOException {
170: store.addAlarm(suiteId, midlet, time);
171: }
172:
173: void removeAlarm(final int suiteId, final String midlet)
174: throws IOException {
175: store.removeAlarm(suiteId, midlet);
176: }
177: }
178:
179: public void testCtor() throws IOException {
180: try {
181: new Store(null);
182: fail("should throw IllegalArgumentException");
183: } catch (IllegalArgumentException _) {
184: }
185: }
186:
187: private static final Map EMPTY_MAP = new HashMap();
188:
189: public void testEmptyStore() throws Exception {
190: final Checker checker = new Checker();
191: // No mutations
192: checker.checkStore(EMPTY_MAP, EMPTY_MAP);
193: }
194:
195: public void testAddOneConnection() throws Exception {
196: final Checker checker = new Checker();
197:
198: checker.addConnection(0, 0);
199: checker.checkStore(new ExpectedConnections().add(0,
200: new int[] { 0 }).map, EMPTY_MAP);
201: }
202:
203: public void testAddAndRemoveConnection() throws Exception {
204: final Checker checker = new Checker();
205:
206: checker.addConnection(1, 1);
207: checker.removeConnection(1, 1);
208:
209: checker.checkStore(EMPTY_MAP, EMPTY_MAP);
210: }
211:
212: private static final int suiteId = 1;
213: private static final int[] cns = { 1, 3, 4 };
214: private static final Map ec = new ExpectedConnections().add(
215: suiteId, cns).map;
216:
217: public void testAddConnections() throws Exception {
218: final Checker checker = new Checker();
219:
220: checker.addConnections(suiteId, cns);
221:
222: checker.checkStore(ec, EMPTY_MAP);
223: }
224:
225: public void testRemoveConnectionsCleansUp() throws Exception {
226: final Checker checker = new Checker();
227:
228: checker.addConnections(suiteId, cns);
229: checker.removeConnections(suiteId);
230:
231: checker.checkStore(EMPTY_MAP, EMPTY_MAP);
232: }
233:
234: public void testReaddConnections() throws Exception {
235: final Checker checker = new Checker();
236:
237: checker.addConnections(suiteId, cns);
238: checker.removeConnections(suiteId);
239: checker.addConnections(suiteId, cns);
240:
241: checker.checkStore(ec, EMPTY_MAP);
242: }
243:
244: private static final int suite0 = 11;
245: private static final int suite1 = 239;
246: private static final int suite2 = 1977;
247: private static final int suite3 = 2006;
248: private static final int suite4 = 1024;
249:
250: // NB: No connections for suites 2 and 4
251: private static final Map ecRealistic = new ExpectedConnections()
252: .add(suite0, new int[] { 0, 1 }).add(suite1,
253: new int[] { 2 }).add(suite3, new int[] { 3, 4 }).map;
254:
255: public void testRealisticOneConnection() throws Exception {
256: final Checker checker = new Checker();
257:
258: // {}, {}, {}, {}, {}
259: checker.addConnection(suite0, 0);
260: // { 0 }, {}, {}, {}, {}
261: checker.addConnection(suite1, 5); // to be removed (1)
262: // { 0 }, { 5 }, {}, {}, {}
263: checker.addConnection(suite2, 6); // to be removed (2)
264: // { 0 }, { 5 }, { 6 }, {}, {}
265: checker.addConnections(suite3, new int[] { 4, 3 });
266: // { 0 }, { 5 }, { 6 }, { 3, 4 }, {}
267: checker.addConnection(suite0, 2); // to be removed (3)
268: // { 0, 2 }, { 5 }, { 6 }, { 3, 4 }, {}
269: checker.removeConnection(suite0, 2); // see above (3)
270: // { 0 }, { 5 }, { 6 }, { 3, 4 }, {}
271: checker.addConnection(suite1, 2);
272: // { 0 }, { 2, 5 }, { 6 }, { 3, 4 }, {}
273: checker.removeConnections(suite2); // see above (2) suite2 is done
274: // { 0 }, { 2, 5 }, {}, { 3, 4 }, {}
275: checker.removeConnection(suite1, 5); // see above (1) suite1 is done
276: // { 0 }, { 2 }, {}, { 3, 4 }, {}
277: checker.addConnection(suite0, 1); // suite0 is done
278: // { 0, 1 }, { 2 }, {}, { 3, 4 }, {}
279:
280: checker.checkStore(ecRealistic, EMPTY_MAP);
281: }
282:
283: public void testRealisticSeveralConnections() throws Exception {
284: final Checker checker = new Checker();
285:
286: // {}, {}, {}, {}, {}
287: checker.addConnection(suite0, 0);
288: // { 0 }, {}, {}, {}, {}
289: checker.addConnection(suite1, 5); // to be removed (1)
290: // { 0 }, { 5 }, {}, {}, {}
291: checker.addConnection(suite2, 6); // to be removed (2)
292: // { 0 }, { 5 }, { 6 }, {}, {}
293: checker.addConnection(suite3, 4);
294: // { 0 }, { 5 }, { 6 }, { 4 }, {}
295: checker.addConnection(suite0, 3); // to be removed (3)
296: // { 0, 3 }, { 5 }, { 6 }, { 4 }, {}
297: checker.removeConnection(suite0, 3); // see above (3)
298: // { 0 }, { 5 }, { 6 }, { 4 }, {}
299: checker.addConnection(suite1, 2);
300: // { 0 }, { 2, 5 }, { 6 }, { 4 }, {}
301: checker.removeConnection(suite3, 4); // to be restored (4)
302: // { 0 }, { 2, 5 }, { 6 }, {}, {}
303: checker.removeConnection(suite2, 6); // see above (2) suite2 is done
304: // { 0 }, { 2, 5 }, {}, {}, {}
305: checker.removeConnection(suite1, 5); // see above (1) suite1 is done
306: // { 0 }, { 2 }, {}, {}, {}
307: checker.addConnection(suite0, 1); // suite0 is done
308: // { 0, 1 }, { 2 }, {}, {}, {}
309: checker.addConnection(suite3, 4);
310: // { 0, 1 }, { 2 }, {}, { 4 }, {}
311: checker.addConnection(suite3, 3); // suite3 is done
312: // { 0, 1 }, { 2 }, {}, { 3, 4 }, {}
313:
314: checker.checkStore(ecRealistic, EMPTY_MAP);
315: }
316:
317: private static final String midlet = "com.sun.foo";
318: private static final long time = 239L;
319: private static final String midlet2 = "com.sun.bar";
320: private static final long time2 = 1977L;
321: private static final int suiteId2 = 239;
322: private static final String midlet3 = "com.sun.qux";
323: private static final long time3 = 2007L;
324:
325: private static final Map ea = new ExpectedAlarms().add(suiteId,
326: midlet, time).map;
327:
328: private static final Map ea3 = new ExpectedAlarms().add(suiteId,
329: midlet2, time3).add(suiteId2, midlet, time2).map;
330:
331: public void testAddOneAlarm() throws Exception {
332: final Checker checker = new Checker();
333:
334: checker.addAlarm(suiteId, midlet, time);
335:
336: checker.checkStore(EMPTY_MAP, ea);
337: }
338:
339: public void testAddAndRemoveOneAlarm() throws Exception {
340: final Checker checker = new Checker();
341:
342: checker.addAlarm(suiteId, midlet, time);
343: checker.removeAlarm(suiteId, midlet);
344:
345: checker.checkStore(EMPTY_MAP, EMPTY_MAP);
346: }
347:
348: public void testReaddOneAlarm() throws Exception {
349: final Checker checker = new Checker();
350:
351: checker.addAlarm(suiteId, midlet, time);
352: checker.removeAlarm(suiteId, midlet);
353: checker.addAlarm(suiteId, midlet, time);
354:
355: checker.checkStore(EMPTY_MAP, ea);
356: }
357:
358: public void testRemoveSecondAlarm() throws Exception {
359: final Checker checker = new Checker();
360:
361: checker.addAlarm(suiteId, midlet2, time);
362: checker.addAlarm(suiteId, midlet, time);
363: checker.removeAlarm(suiteId, midlet2);
364:
365: checker.checkStore(EMPTY_MAP, ea);
366: }
367:
368: public void testRemoveSecondAlarmImmediately() throws Exception {
369: final Checker checker = new Checker();
370:
371: checker.addAlarm(suiteId, midlet, time);
372: checker.addAlarm(suiteId, midlet2, time);
373: checker.removeAlarm(suiteId, midlet2);
374:
375: checker.checkStore(EMPTY_MAP, ea);
376: }
377:
378: public void testAddTwoAlarms() throws Exception {
379: final Checker checker = new Checker();
380:
381: checker.addAlarm(suiteId, midlet, time);
382: checker.addAlarm(suiteId, midlet2, time2);
383:
384: final ExpectedAlarms ea = new ExpectedAlarms().add(suiteId,
385: midlet, time).add(suiteId, midlet2, time2);
386:
387: checker.checkStore(EMPTY_MAP, ea.map);
388: }
389:
390: public void testAddTwoAlarmsWithRemoval() throws Exception {
391: final Checker checker = new Checker();
392:
393: checker.addAlarm(suiteId2, midlet2, time);
394: checker.addAlarm(suiteId2, midlet, time2);
395: checker.addAlarm(suiteId, midlet2, time3);
396: checker.removeAlarm(suiteId2, midlet2);
397:
398: checker.checkStore(EMPTY_MAP, ea3);
399: }
400:
401: public void testRealisticAll() throws Exception {
402: final Checker checker = new Checker();
403:
404: // {}, {}, {}, {}, {}
405: checker.addConnection(suite0, 0);
406: // { 0 }, {}, {}, {}, {}
407: checker.addConnection(suite1, 5); // to be removed (1)
408: // { 0 }, { 5 }, {}, {}, {}
409:
410: checker.addAlarm(suiteId2, midlet2, time);
411:
412: checker.addConnection(suite2, 6); // to be removed (2)
413: // { 0 }, { 5 }, { 6 }, {}, {}
414: checker.addConnections(suite3, new int[] { 4, 3 });
415: // { 0 }, { 5 }, { 6 }, { 3, 4 }, {}
416: checker.addConnection(suite0, 2); // to be removed (3)
417: // { 0, 2 }, { 5 }, { 6 }, { 3, 4 }, {}
418: checker.removeConnection(suite0, 2); // see above (3)
419: // { 0 }, { 5 }, { 6 }, { 3, 4 }, {}
420:
421: checker.addAlarm(suiteId2, midlet, time2);
422: checker.addAlarm(suiteId, midlet2, time3);
423:
424: checker.addConnection(suite1, 2);
425: // { 0 }, { 2, 5 }, { 6 }, { 3, 4 }, {}
426: checker.removeConnections(suite2); // see above (2) suite2 is done
427: // { 0 }, { 2, 5 }, {}, { 3, 4 }, {}
428: checker.removeConnection(suite1, 5); // see above (1) suite1 is done
429: // { 0 }, { 2 }, {}, { 3, 4 }, {}
430:
431: checker.removeAlarm(suiteId2, midlet2);
432:
433: checker.addConnection(suite0, 1); // suite0 is done
434: // { 0, 1 }, { 2 }, {}, { 3, 4 }, {}
435:
436: checker.checkStore(ecRealistic, ea3);
437: }
438: }
|