0001: /*
0002: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0004: *
0005: * This program is free software; you can redistribute it and/or
0006: * modify it under the terms of the GNU General Public License version
0007: * 2 only, as published by the Free Software Foundation.
0008: *
0009: * This program is distributed in the hope that it will be useful, but
0010: * WITHOUT ANY WARRANTY; without even the implied warranty of
0011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0012: * General Public License version 2 for more details (a copy is
0013: * included at /legal/license.txt).
0014: *
0015: * You should have received a copy of the GNU General Public License
0016: * version 2 along with this work; if not, write to the Free Software
0017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0018: * 02110-1301 USA
0019: *
0020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0021: * Clara, CA 95054 or visit www.sun.com if you need additional
0022: * information or have any questions.
0023: */
0024:
0025: package com.sun.midp.jump.push.executive;
0026:
0027: import com.sun.midp.push.gcf.PermissionCallback;
0028: import com.sun.midp.push.gcf.ReservationDescriptorFactory;
0029: import java.util.Arrays;
0030: import java.util.Collection;
0031: import java.util.HashSet;
0032: import junit.framework.*;
0033: import com.sun.midp.push.gcf.ConnectionReservation;
0034: import com.sun.midp.push.gcf.DataAvailableListener;
0035: import com.sun.midp.push.gcf.ReservationDescriptor;
0036: import com.sun.midp.jump.push.executive.persistence.Store;
0037: import com.sun.midp.jump.push.executive.persistence.StoreUtils;
0038: import java.io.IOException;
0039: import javax.microedition.io.ConnectionNotFoundException;
0040:
0041: /*
0042: * ConnectionController tests.
0043: *
0044: * <p>
0045: * TODO: failing store tests.
0046: * </p>
0047: */
0048: public final class ConnectionControllerTest extends TestCase {
0049:
0050: public ConnectionControllerTest(final String testName) {
0051: super (testName);
0052: }
0053:
0054: /**
0055: * Delayble thread.
0056: *
0057: * Instances of this class can be scheduled for executuion,
0058: * but actual execution can be delayed with a lock.
0059: */
0060: private static abstract class DelayableThread extends Thread {
0061: private final Object lock = new Object();
0062:
0063: abstract protected void doRun();
0064:
0065: public final void run() {
0066: synchronized (lock) {
0067: doRun();
0068: }
0069: }
0070: }
0071:
0072: /**
0073: * Mock implementation of ConnectionReservation.
0074: */
0075: private static final class MockConnectionReservation implements
0076: ConnectionReservation {
0077:
0078: private final DataAvailableListener listener;
0079:
0080: private boolean isCancelled = false;
0081:
0082: private boolean hasAvailableData_ = false;
0083:
0084: MockConnectionReservation(final DataAvailableListener listener) {
0085: this .listener = listener;
0086: }
0087:
0088: /** {@inheritDoc} */
0089: public boolean hasAvailableData() {
0090: if (isCancelled) {
0091: throw new IllegalStateException("cancelled reservation");
0092: }
0093: return hasAvailableData_;
0094: }
0095:
0096: /** {@inheritDoc} */
0097: public void cancel() {
0098: if (isCancelled) {
0099: throw new IllegalStateException("double cancellation");
0100: }
0101: isCancelled = true;
0102: }
0103:
0104: /** Returns a thread that can be used to 'ping' the connection. */
0105: DelayableThread pingThread() {
0106: return new DelayableThread() {
0107: protected void doRun() {
0108: listener.dataAvailable();
0109: }
0110: };
0111: }
0112: }
0113:
0114: /**
0115: * Mock implementation of ReservationDescriptor.
0116: */
0117: private static final class MockReservationDescriptor implements
0118: ReservationDescriptor {
0119: /** connection name. */
0120: final String connectionName;
0121:
0122: /** filter. */
0123: final String filter;
0124:
0125: /** reserved flag. */
0126: boolean isReserved = false;
0127:
0128: /** connection reservation. */
0129: MockConnectionReservation connectionReservation = null;
0130:
0131: /**
0132: * Creates a mock.
0133: *
0134: * @param connectionName connection name
0135: * (cannot be <code>null</code>)
0136: *
0137: * @param filter filter
0138: * (cannot be <code>null</code>)
0139: */
0140: MockReservationDescriptor(final String connectionName,
0141: final String filter) {
0142: this .connectionName = connectionName;
0143: this .filter = filter;
0144: }
0145:
0146: /** {@inheritDoc} */
0147: public ConnectionReservation reserve(final int midletSuiteId,
0148: final String midletClassName,
0149: final DataAvailableListener dataAvailableListener)
0150: throws IOException {
0151: isReserved = true;
0152: connectionReservation = new MockConnectionReservation(
0153: dataAvailableListener);
0154: return connectionReservation;
0155: }
0156:
0157: /** {@inheritDoc} */
0158: public String getConnectionName() {
0159: return connectionName;
0160: }
0161:
0162: /** {@inheritDoc} */
0163: public String getFilter() {
0164: return filter;
0165: }
0166: }
0167:
0168: private static Store createStore() throws IOException {
0169: return StoreUtils.createInMemoryPushStore();
0170: }
0171:
0172: private final ReservationDescriptorFactory rdf = new ReservationDescriptorFactory() {
0173: public ReservationDescriptor getDescriptor(
0174: final String connectionName, final String filter,
0175: final PermissionCallback permissionCallback)
0176: throws IllegalArgumentException,
0177: ConnectionNotFoundException {
0178: if (permissionCallback == null) {
0179: throw new RuntimeException("null permission callback");
0180: }
0181: return new MockReservationDescriptor(connectionName, filter);
0182: }
0183: };
0184:
0185: private ConnectionController createConnectionController(
0186: final Store store, final LifecycleAdapter lifecycleAdapter) {
0187: /*
0188: * IMPL_NOTE: don't forget mock parameter verifier if the signature
0189: * below change
0190: */
0191: return new ConnectionController(store, rdf, lifecycleAdapter);
0192: }
0193:
0194: private ConnectionController createConnectionController(
0195: final Store store) {
0196: return createConnectionController(store,
0197: new ListingLifecycleAdapter());
0198: }
0199:
0200: private ConnectionController.ReservationHandler createFakeReservationHandler(
0201: final ConnectionController connectionController,
0202: final int midletSuiteId, final String midlet,
0203: final String connection, final String filter)
0204: throws IOException {
0205: final ReservationDescriptor descriptor = new MockReservationDescriptor(
0206: connection, filter);
0207: return connectionController.new ReservationHandler(
0208: midletSuiteId, midlet, descriptor);
0209: }
0210:
0211: private ConnectionController.ReservationHandler createFakeReservationHandler(
0212: final int midletSuiteId, final String midlet,
0213: final String connection, final String filter)
0214: throws IOException {
0215: final ReservationDescriptor descriptor = new MockReservationDescriptor(
0216: connection, filter);
0217: return createConnectionController(createStore()).new ReservationHandler(
0218: midletSuiteId, midlet, descriptor);
0219: }
0220:
0221: public void testReservationHandlerCtor() throws IOException {
0222: final int midletSuiteId = 123;
0223: final String midlet = "com.sun.Foo";
0224: final String connection = "foo://bar";
0225: final String filter = "*.123";
0226:
0227: final ConnectionController.ReservationHandler h = createFakeReservationHandler(
0228: midletSuiteId, midlet, connection, filter);
0229:
0230: assertEquals(midletSuiteId, h.getSuiteId());
0231: assertEquals(midlet, h.getMidlet());
0232: assertEquals(connection, h.getConnectionName());
0233: assertEquals(filter, h.getFilter());
0234: }
0235:
0236: private void assertSetsEqual(final Object[] expected,
0237: final Collection actual) {
0238: assertEquals(new HashSet(Arrays.asList(expected)), new HashSet(
0239: actual));
0240: }
0241:
0242: private void assertSetsEqual(final Object[] expected,
0243: final Object[] actual) {
0244: assertSetsEqual(expected, Arrays.asList(actual));
0245: }
0246:
0247: private void checkCollectionHasSingleHandler(
0248: final Collection reservations,
0249: final ConnectionController.ReservationHandler handler) {
0250: assertEquals(1, reservations.size());
0251: assertSame(handler, reservations.iterator().next());
0252: }
0253:
0254: public void testQueryByConnection() throws IOException {
0255: final int midletSuiteId = 123;
0256: final String midlet = "com.sun.Foo";
0257: final String connection = "foo://bar";
0258: final String filter = "*.123";
0259:
0260: final ConnectionController.ReservationHandler h = createFakeReservationHandler(
0261: midletSuiteId, midlet, connection, filter);
0262:
0263: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0264: reservations.add(h);
0265:
0266: assertSame(h, reservations.queryByConnectionName(connection));
0267: checkCollectionHasSingleHandler(reservations
0268: .getAllReservations(), h);
0269: }
0270:
0271: public void testQueryByConnectionMissing() throws IOException {
0272: final int midletSuiteId = 123;
0273: final String midlet = "com.sun.Foo";
0274: final String connection = "foo://bar";
0275: final String filter = "*.123";
0276:
0277: final ConnectionController.ReservationHandler h = createFakeReservationHandler(
0278: midletSuiteId, midlet, connection, filter);
0279:
0280: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0281: reservations.add(h);
0282:
0283: assertNull(reservations.queryByConnectionName(connection
0284: + "qux"));
0285: checkCollectionHasSingleHandler(reservations
0286: .getAllReservations(), h);
0287: }
0288:
0289: public void testQueryBySuite() throws IOException {
0290: final int midletSuiteId = 123;
0291: final String midlet = "com.sun.Foo";
0292: final String connection = "foo://bar";
0293: final String filter = "*.123";
0294:
0295: final ConnectionController.ReservationHandler h = createFakeReservationHandler(
0296: midletSuiteId, midlet, connection, filter);
0297:
0298: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0299: reservations.add(h);
0300:
0301: checkCollectionHasSingleHandler(reservations
0302: .queryBySuiteID(midletSuiteId), h);
0303: checkCollectionHasSingleHandler(reservations
0304: .getAllReservations(), h);
0305: }
0306:
0307: public void testQueryBySuiteMissing() throws IOException {
0308: final int midletSuiteId = 123;
0309: final String midlet = "com.sun.Foo";
0310: final String connection = "foo://bar";
0311: final String filter = "*.123";
0312:
0313: final ConnectionController.ReservationHandler h = createFakeReservationHandler(
0314: midletSuiteId, midlet, connection, filter);
0315:
0316: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0317: reservations.add(h);
0318:
0319: assertTrue(reservations.queryBySuiteID(midletSuiteId + 1)
0320: .isEmpty());
0321: checkCollectionHasSingleHandler(reservations
0322: .getAllReservations(), h);
0323: }
0324:
0325: public void testEmptyReservations() {
0326: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0327:
0328: assertNull(reservations.queryByConnectionName("foo://bar"));
0329: assertTrue(reservations.queryBySuiteID(13).isEmpty());
0330: assertTrue(reservations.getAllReservations().isEmpty());
0331: }
0332:
0333: public void testAddAndRemove() throws IOException {
0334: final int midletSuiteId = 123;
0335: final String midlet = "com.sun.Foo";
0336: final String connection = "foo://bar";
0337: final String filter = "*.123";
0338:
0339: final ConnectionController.ReservationHandler h = createFakeReservationHandler(
0340: midletSuiteId, midlet, connection, filter);
0341:
0342: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0343: reservations.add(h);
0344: reservations.remove(h);
0345:
0346: assertNull(reservations.queryByConnectionName(connection));
0347: assertTrue(reservations.queryBySuiteID(midletSuiteId).isEmpty());
0348: assertTrue(reservations.getAllReservations().isEmpty());
0349: }
0350:
0351: public void testTwoHandlersReservations() throws IOException {
0352: final int midletSuiteId1 = 123;
0353: final String midlet1 = "com.sun.Foo";
0354: final String connection1 = "foo://bar";
0355: final String filter1 = "*.123";
0356:
0357: final ConnectionController.ReservationHandler h1 = createFakeReservationHandler(
0358: midletSuiteId1, midlet1, connection1, filter1);
0359:
0360: final int midletSuiteId2 = 321;
0361: final String midlet2 = "com.sun.Bar";
0362: final String connection2 = "qux://bar";
0363: final String filter2 = "*";
0364:
0365: final ConnectionController.ReservationHandler h2 = createFakeReservationHandler(
0366: midletSuiteId2, midlet2, connection2, filter2);
0367:
0368: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0369: reservations.add(h1);
0370: reservations.add(h2);
0371:
0372: assertSame(h1, reservations.queryByConnectionName(connection1));
0373: assertSame(h2, reservations.queryByConnectionName(connection2));
0374: checkCollectionHasSingleHandler(reservations
0375: .queryBySuiteID(midletSuiteId1), h1);
0376: checkCollectionHasSingleHandler(reservations
0377: .queryBySuiteID(midletSuiteId2), h2);
0378: assertSetsEqual(new Object[] { h1, h2 }, reservations
0379: .getAllReservations());
0380: }
0381:
0382: public void testClear() throws IOException {
0383: final int midletSuiteId1 = 123;
0384: final String midlet1 = "com.sun.Foo";
0385: final String connection1 = "foo://bar";
0386: final String filter1 = "*.123";
0387:
0388: final ConnectionController.ReservationHandler h1 = createFakeReservationHandler(
0389: midletSuiteId1, midlet1, connection1, filter1);
0390:
0391: final int midletSuiteId2 = 321;
0392: final String midlet2 = "com.sun.Bar";
0393: final String connection2 = "qux://bar";
0394: final String filter2 = "*";
0395:
0396: final ConnectionController.ReservationHandler h2 = createFakeReservationHandler(
0397: midletSuiteId2, midlet2, connection2, filter2);
0398:
0399: final ConnectionController.Reservations reservations = new ConnectionController.Reservations();
0400: reservations.add(h1);
0401: reservations.add(h2);
0402: reservations.clear();
0403:
0404: assertNull(reservations.queryByConnectionName(connection1));
0405: assertNull(reservations.queryByConnectionName(connection2));
0406: assertTrue(reservations.queryBySuiteID(midletSuiteId1)
0407: .isEmpty());
0408: assertTrue(reservations.queryBySuiteID(midletSuiteId2)
0409: .isEmpty());
0410: assertTrue(reservations.getAllReservations().isEmpty());
0411: }
0412:
0413: private void checkStoreEmpty(final Store store) {
0414: store.listConnections(new Store.ConnectionsConsumer() {
0415: public void consume(final int id,
0416: final JUMPConnectionInfo[] infos) {
0417: fail("store must be empty");
0418: }
0419: });
0420: }
0421:
0422: private void checkStoreHasSingleRecord(final Store store,
0423: final int midletSuiteId, final String midlet,
0424: final String connection, final String filter) {
0425: final JUMPConnectionInfo info = new JUMPConnectionInfo(
0426: connection, midlet, filter);
0427:
0428: store.listConnections(new Store.ConnectionsConsumer() {
0429: public void consume(final int id,
0430: final JUMPConnectionInfo[] infos) {
0431: assertEquals(id, midletSuiteId);
0432: assertEquals(1, infos.length);
0433: assertEquals(info, infos[0]);
0434: }
0435: });
0436: }
0437:
0438: private void checkSingletonConnectionList(
0439: final ConnectionController cc, final int midletSuiteId,
0440: final String connection) {
0441: final String[] cns = cc.listConnections(midletSuiteId, false);
0442: assertEquals(1, cns.length);
0443: assertEquals(connection, cns[0]);
0444: }
0445:
0446: public void testRegisterConnectionState() throws IOException {
0447: final int midletSuiteId = 123;
0448: final String midlet = "com.sun.Foo";
0449: final String connection = "foo://bar";
0450: final String filter = "*.123";
0451:
0452: final Store store = createStore();
0453:
0454: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
0455: connection, filter);
0456:
0457: final ConnectionController cc = createConnectionController(store);
0458:
0459: cc.registerConnection(midletSuiteId, midlet, descriptor);
0460:
0461: assertTrue(descriptor.isReserved);
0462: assertFalse(descriptor.connectionReservation.isCancelled);
0463: checkStoreHasSingleRecord(store, midletSuiteId, midlet,
0464: connection, filter);
0465: checkSingletonConnectionList(cc, midletSuiteId, connection);
0466: assertEquals(midlet, cc.getMIDlet(midletSuiteId, connection));
0467: assertEquals(filter, cc.getFilter(midletSuiteId, connection));
0468: }
0469:
0470: public void testReregistration() throws IOException {
0471: final int midletSuiteId = 123;
0472: final String midlet = "com.sun.Foo";
0473: final String connection = "foo://bar";
0474: final String filter = "*.123";
0475:
0476: final String filter2 = "*.*.*";
0477:
0478: final Store store = createStore();
0479:
0480: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0481: connection, filter);
0482:
0483: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
0484: connection, filter2);
0485:
0486: final ConnectionController cc = createConnectionController(store);
0487:
0488: cc.registerConnection(midletSuiteId, midlet, descriptor1);
0489: cc.registerConnection(midletSuiteId, midlet, descriptor2);
0490:
0491: assertTrue(descriptor1.isReserved);
0492: assertTrue(descriptor1.connectionReservation.isCancelled);
0493: assertTrue(descriptor2.isReserved);
0494: assertFalse(descriptor2.connectionReservation.isCancelled);
0495:
0496: checkStoreHasSingleRecord(store, midletSuiteId, midlet,
0497: connection, filter2);
0498: checkSingletonConnectionList(cc, midletSuiteId, connection);
0499: assertEquals(midlet, cc.getMIDlet(midletSuiteId, connection));
0500: assertEquals(filter2, cc.getFilter(midletSuiteId, connection));
0501: }
0502:
0503: public void testReregistrationOfAnotherSuite() throws IOException {
0504: final int midletSuiteId = 123;
0505: final String midlet = "com.sun.Foo";
0506: final String connection = "foo://bar";
0507: final String filter = "*.123";
0508:
0509: final int midletSuiteId2 = midletSuiteId + 17;
0510:
0511: final Store store = createStore();
0512:
0513: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0514: connection, filter);
0515:
0516: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
0517: connection, filter);
0518:
0519: final ConnectionController cc = createConnectionController(store);
0520:
0521: cc.registerConnection(midletSuiteId, midlet, descriptor1);
0522:
0523: boolean ioExceptionThrown = false;
0524: try {
0525: cc.registerConnection(midletSuiteId2, midlet, descriptor2);
0526: } catch (IOException ioex) {
0527: ioExceptionThrown = true;
0528: }
0529:
0530: assertTrue(ioExceptionThrown);
0531:
0532: assertTrue(descriptor1.isReserved);
0533: assertFalse(descriptor1.connectionReservation.isCancelled);
0534:
0535: assertFalse(descriptor2.isReserved);
0536:
0537: checkStoreHasSingleRecord(store, midletSuiteId, midlet,
0538: connection, filter);
0539:
0540: checkSingletonConnectionList(cc, midletSuiteId, connection);
0541: assertEquals(midlet, cc.getMIDlet(midletSuiteId, connection));
0542: assertEquals(filter, cc.getFilter(midletSuiteId, connection));
0543:
0544: assertEquals(0,
0545: cc.listConnections(midletSuiteId2, false).length);
0546: assertNull(cc.getMIDlet(midletSuiteId2, connection));
0547: assertNull(cc.getFilter(midletSuiteId2, connection));
0548: }
0549:
0550: public void testReregistrationOfAnotherMIDlet() throws IOException {
0551: final int midletSuiteId = 123;
0552: final String midlet = "com.sun.Foo";
0553: final String connection = "foo://bar";
0554: final String filter = "*.123";
0555:
0556: final String midlet2 = "com.sun.Bar";
0557:
0558: final Store store = createStore();
0559:
0560: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0561: connection, filter);
0562:
0563: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
0564: connection, filter);
0565:
0566: final ConnectionController cc = createConnectionController(store);
0567:
0568: cc.registerConnection(midletSuiteId, midlet, descriptor1);
0569: cc.registerConnection(midletSuiteId, midlet2, descriptor2);
0570:
0571: assertTrue(descriptor1.isReserved);
0572: assertTrue(descriptor1.connectionReservation.isCancelled);
0573:
0574: assertTrue(descriptor2.isReserved);
0575: assertFalse(descriptor2.connectionReservation.isCancelled);
0576:
0577: checkStoreHasSingleRecord(store, midletSuiteId, midlet2,
0578: connection, filter);
0579: checkSingletonConnectionList(cc, midletSuiteId, connection);
0580: assertEquals(midlet2, cc.getMIDlet(midletSuiteId, connection));
0581: assertEquals(filter, cc.getFilter(midletSuiteId, connection));
0582: }
0583:
0584: public void testRegistrationOfFailingReservation()
0585: throws IOException {
0586: final int midletSuiteId = 123;
0587: final String midlet = "com.sun.Foo";
0588: final String connection = "foo://bar";
0589: final String filter = "*.123";
0590:
0591: final Store store = createStore();
0592:
0593: final ReservationDescriptor descriptor = new ReservationDescriptor() {
0594: public ConnectionReservation reserve(
0595: final int midletSuiteId,
0596: final String midletClassName,
0597: final DataAvailableListener dataAvailableListener)
0598: throws IOException {
0599: throw new IOException("cannot be registered");
0600: }
0601:
0602: public String getConnectionName() {
0603: return connection;
0604: }
0605:
0606: public String getFilter() {
0607: return filter;
0608: }
0609: };
0610:
0611: final ConnectionController cc = createConnectionController(store);
0612:
0613: boolean ioExceptionThrown = false;
0614: try {
0615: cc.registerConnection(midletSuiteId, midlet, descriptor);
0616: } catch (IOException ioex) {
0617: ioExceptionThrown = true;
0618: }
0619:
0620: assertTrue(ioExceptionThrown);
0621:
0622: checkStoreEmpty(store);
0623: assertEquals(0, cc.listConnections(midletSuiteId, false).length);
0624: assertNull(cc.getMIDlet(midletSuiteId, connection));
0625: assertNull(cc.getFilter(midletSuiteId, connection));
0626: }
0627:
0628: public void testListConnectionsAll() throws IOException {
0629: final int midletSuiteId1 = 123;
0630:
0631: final String midlet1 = "com.sun.Foo";
0632: final String connection1 = "foo://bar";
0633: final String filter1 = "*.123";
0634:
0635: final String connection2 = "foo2://bar";
0636: final String filter2 = "*.123";
0637:
0638: final String midlet3 = "com.sun.Bar";
0639: final String connection3 = "qux://bar";
0640: final String filter3 = "*.*";
0641:
0642: final int midletSuiteId2 = midletSuiteId1 + 17;
0643:
0644: final String connection4 = "foo4://bar";
0645: final String filter4 = "4.*.123";
0646:
0647: final Store store = createStore();
0648:
0649: final ConnectionController cc = createConnectionController(store);
0650:
0651: cc.registerConnection(midletSuiteId1, midlet1,
0652: new MockReservationDescriptor(connection1, filter1));
0653: cc.registerConnection(midletSuiteId1, midlet1,
0654: new MockReservationDescriptor(connection2, filter2));
0655: cc.registerConnection(midletSuiteId1, midlet3,
0656: new MockReservationDescriptor(connection3, filter3));
0657: cc.registerConnection(midletSuiteId2, midlet1,
0658: new MockReservationDescriptor(connection4, filter4));
0659:
0660: assertSetsEqual(new String[] { connection1, connection2,
0661: connection3 }, cc
0662: .listConnections(midletSuiteId1, false));
0663:
0664: final String[] suite2cns = cc.listConnections(midletSuiteId2,
0665: false);
0666: assertEquals(1, suite2cns.length);
0667: assertEquals(connection4, suite2cns[0]);
0668: }
0669:
0670: public void testListConnectionsWithData() throws IOException {
0671: final int midletSuiteId = 123;
0672:
0673: final String midlet1 = "com.sun.Foo";
0674:
0675: final String connection1 = "foo://bar";
0676: final String filter1 = "*.123";
0677: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0678: connection1, filter1);
0679:
0680: final String connection2 = "foo2://bar";
0681: final String filter2 = "*.123";
0682: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
0683: connection2, filter2);
0684:
0685: final String midlet3 = "com.sun.Bar";
0686:
0687: final String connection3 = "qux://bar";
0688: final String filter3 = "*.*";
0689: final MockReservationDescriptor descriptor3 = new MockReservationDescriptor(
0690: connection3, filter3);
0691:
0692: final Store store = createStore();
0693:
0694: final ConnectionController cc = createConnectionController(store);
0695:
0696: cc.registerConnection(midletSuiteId, midlet1, descriptor1);
0697: cc.registerConnection(midletSuiteId, midlet1, descriptor2);
0698: cc.registerConnection(midletSuiteId, midlet3, descriptor3);
0699:
0700: descriptor1.connectionReservation.hasAvailableData_ = true;
0701: descriptor2.connectionReservation.hasAvailableData_ = false;
0702: descriptor3.connectionReservation.hasAvailableData_ = true;
0703:
0704: assertSetsEqual(new String[] { connection1, connection3 }, cc
0705: .listConnections(midletSuiteId, true));
0706: }
0707:
0708: public void testUnregisterConnectionInEmptyController()
0709: throws IOException {
0710: final int midletSuiteId = 123;
0711: final String connection = "foo://bar";
0712: final String filter = "*.123";
0713:
0714: final Store store = createStore();
0715:
0716: final ConnectionController cc = createConnectionController(store);
0717:
0718: assertFalse(cc.unregisterConnection(midletSuiteId, connection));
0719:
0720: checkStoreEmpty(store);
0721: assertEquals(0, cc.listConnections(midletSuiteId, false).length);
0722: assertNull(cc.getMIDlet(midletSuiteId, connection));
0723: assertNull(cc.getFilter(midletSuiteId, connection));
0724: }
0725:
0726: public void testUnregisterRegisteredConnection() throws IOException {
0727: final int midletSuiteId = 123;
0728: final String midlet = "com.sun.Foo";
0729: final String connection = "foo://bar";
0730: final String filter = "*.123";
0731:
0732: final Store store = createStore();
0733:
0734: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
0735: connection, filter);
0736:
0737: final ConnectionController cc = createConnectionController(store);
0738:
0739: cc.registerConnection(midletSuiteId, midlet, descriptor);
0740: assertTrue(cc.unregisterConnection(midletSuiteId, connection));
0741:
0742: assertTrue(descriptor.connectionReservation.isCancelled);
0743: checkStoreEmpty(store);
0744: assertEquals(0, cc.listConnections(midletSuiteId, false).length);
0745: assertNull(cc.getMIDlet(midletSuiteId, connection));
0746: assertNull(cc.getFilter(midletSuiteId, connection));
0747: }
0748:
0749: public void testUnregisterNotRegisteredConnection()
0750: throws IOException {
0751: final int midletSuiteId = 123;
0752: final String midlet = "com.sun.Foo";
0753: final String connection = "foo://bar";
0754: final String filter = "*.123";
0755:
0756: final String connection2 = "com.sun.Bar";
0757:
0758: final Store store = createStore();
0759:
0760: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
0761: connection, filter);
0762:
0763: final ConnectionController cc = createConnectionController(store);
0764:
0765: cc.registerConnection(midletSuiteId, midlet, descriptor);
0766:
0767: assertFalse(cc.unregisterConnection(midletSuiteId, connection2));
0768:
0769: checkStoreHasSingleRecord(store, midletSuiteId, midlet,
0770: connection, filter);
0771: checkSingletonConnectionList(cc, midletSuiteId, connection);
0772: assertEquals(midlet, cc.getMIDlet(midletSuiteId, connection));
0773: assertEquals(filter, cc.getFilter(midletSuiteId, connection));
0774: }
0775:
0776: public void testUnregisterOtherSuiteConnection() throws IOException {
0777: final int midletSuiteId = 123;
0778: final String midlet = "com.sun.Foo";
0779: final String connection = "foo://bar";
0780: final String filter = "*.123";
0781:
0782: final int midletSuiteId2 = midletSuiteId + 17;
0783:
0784: final Store store = createStore();
0785:
0786: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
0787: connection, filter);
0788:
0789: final ConnectionController cc = createConnectionController(store);
0790:
0791: cc.registerConnection(midletSuiteId, midlet, descriptor);
0792:
0793: boolean securityExceptionThrown = false;
0794: try {
0795: cc.unregisterConnection(midletSuiteId2, connection);
0796: } catch (SecurityException sex) {
0797: securityExceptionThrown = true;
0798: }
0799:
0800: assertTrue(securityExceptionThrown);
0801: checkStoreHasSingleRecord(store, midletSuiteId, midlet,
0802: connection, filter);
0803: checkSingletonConnectionList(cc, midletSuiteId, connection);
0804: assertEquals(midlet, cc.getMIDlet(midletSuiteId, connection));
0805: assertEquals(filter, cc.getFilter(midletSuiteId, connection));
0806: }
0807:
0808: public void testDataAvailableListener() throws IOException {
0809: final int midletSuiteId = 123;
0810: final String midlet = "com.sun.Foo";
0811: final String connection = "foo://bar";
0812: final String filter = "*.123";
0813:
0814: final Store store = createStore();
0815:
0816: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
0817: connection, filter);
0818:
0819: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
0820:
0821: final ConnectionController cc = createConnectionController(
0822: store, lifecycleAdapter);
0823:
0824: cc.registerConnection(midletSuiteId, midlet, descriptor);
0825: final Thread t = descriptor.connectionReservation.pingThread();
0826: t.start();
0827: try {
0828: t.join();
0829: } catch (InterruptedException ie) {
0830: fail("Unexpected InterruptedException: " + ie);
0831: }
0832:
0833: assertTrue(lifecycleAdapter.hasBeenInvokedOnceFor(
0834: midletSuiteId, midlet));
0835: }
0836:
0837: public void testConcurrentCancellation() throws IOException {
0838: final int midletSuiteId = 123;
0839: final String midlet = "com.sun.Foo";
0840: final String connection = "foo://bar";
0841: final String filter = "*.123";
0842:
0843: final Store store = createStore();
0844:
0845: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
0846: connection, filter);
0847:
0848: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
0849:
0850: final ConnectionController cc = createConnectionController(
0851: store, lifecycleAdapter);
0852:
0853: cc.registerConnection(midletSuiteId, midlet, descriptor);
0854:
0855: final DelayableThread t = descriptor.connectionReservation
0856: .pingThread();
0857:
0858: synchronized (t.lock) {
0859: // start the thread first...
0860: t.start();
0861: // ...but before listener starts, unregister connection...
0862: assertTrue(cc.unregisterConnection(midletSuiteId,
0863: connection));
0864: // ...now let listener proceed
0865: }
0866: try {
0867: t.join();
0868: } catch (InterruptedException ie) {
0869: fail("Unexpected InterruptedException: " + ie);
0870: }
0871:
0872: assertTrue(lifecycleAdapter.hasNotBeenInvoked());
0873: }
0874:
0875: public void testUninstallSuiteWithNoConnections()
0876: throws IOException {
0877: final Store store = createStore();
0878: final ConnectionController cc = createConnectionController(store);
0879: cc.removeSuiteConnections(239);
0880: checkStoreEmpty(store);
0881: }
0882:
0883: public void testUninstallWithTwoConnections() throws IOException {
0884: final int midletSuiteId = 123;
0885:
0886: final String midlet1 = "com.sun.Foo";
0887: final String midlet2 = "com.sun.Bar";
0888:
0889: final String connection1 = "foo://bar";
0890: final String filter1 = "*.123";
0891: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0892: connection1, filter1);
0893:
0894: final String connection2 = "foo://qux";
0895: final String filter2 = "*.*";
0896: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
0897: connection2, filter2);
0898:
0899: final Store store = createStore();
0900:
0901: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
0902:
0903: final ConnectionController cc = createConnectionController(
0904: store, lifecycleAdapter);
0905:
0906: cc.registerConnection(midletSuiteId, midlet1, descriptor1);
0907: cc.registerConnection(midletSuiteId, midlet2, descriptor2);
0908: cc.removeSuiteConnections(midletSuiteId);
0909:
0910: assertTrue(descriptor1.connectionReservation.isCancelled);
0911: assertTrue(descriptor2.connectionReservation.isCancelled);
0912:
0913: assertFalse(cc.unregisterConnection(midletSuiteId, connection1));
0914: assertFalse(cc.unregisterConnection(midletSuiteId, connection2));
0915:
0916: assertEquals(0, cc.listConnections(midletSuiteId, false).length);
0917: assertNull(cc.getMIDlet(midletSuiteId, connection1));
0918: assertNull(cc.getFilter(midletSuiteId, connection1));
0919: assertNull(cc.getMIDlet(midletSuiteId, connection2));
0920: assertNull(cc.getFilter(midletSuiteId, connection2));
0921:
0922: checkStoreEmpty(store);
0923: }
0924:
0925: public void testConcurrentCancellationAndUninstall()
0926: throws IOException {
0927: final int midletSuiteId = 123;
0928:
0929: final String midlet1 = "com.sun.Foo";
0930: final String midlet2 = "com.sun.Bar";
0931:
0932: final String connection1 = "foo://bar";
0933: final String filter1 = "*.123";
0934: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0935: connection1, filter1);
0936:
0937: final String connection2 = "foo://qux";
0938: final String filter2 = "*.*";
0939: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
0940: connection2, filter2);
0941:
0942: final Store store = createStore();
0943:
0944: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
0945:
0946: final ConnectionController cc = createConnectionController(
0947: store, lifecycleAdapter);
0948:
0949: cc.registerConnection(midletSuiteId, midlet1, descriptor1);
0950: cc.registerConnection(midletSuiteId, midlet2, descriptor2);
0951:
0952: final DelayableThread t1 = descriptor1.connectionReservation
0953: .pingThread();
0954: final DelayableThread t2 = descriptor2.connectionReservation
0955: .pingThread();
0956:
0957: synchronized (t1.lock) {
0958: synchronized (t2.lock) {
0959: // start the threads first...
0960: t1.start();
0961: t2.start();
0962: // ...but before listeners starts, uninstall the suite...
0963: cc.removeSuiteConnections(midletSuiteId);
0964: // ...now let listeners proceed
0965: }
0966: }
0967: try {
0968: t1.join();
0969: t2.join();
0970: } catch (InterruptedException ie) {
0971: fail("Unexpected InterruptedException: " + ie);
0972: }
0973:
0974: assertTrue(lifecycleAdapter.hasNotBeenInvoked());
0975: }
0976:
0977: private void assertSetsEqualDeep(final Object[] expected,
0978: final Object[] actual) {
0979: /**
0980: * IMPL_NOTE: haven't found better way yet. Technically
0981: * speaking it's not even quite correct: imho there is
0982: * no guarantees that "same" hash sets will produce same
0983: * toArray's, but chances are high, really
0984: */
0985: final HashSet e = new HashSet(Arrays.asList(expected));
0986: final HashSet a = new HashSet(Arrays.asList(actual));
0987: Arrays.equals(e.toArray(), a.toArray());
0988: }
0989:
0990: public void testStateAfterDispose() throws IOException {
0991: final int midletSuiteId1 = 123;
0992:
0993: final String midlet1 = "com.sun.Foo";
0994: final String connection1 = "foo://bar";
0995: final String filter1 = "*.123";
0996: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
0997: connection1, filter1);
0998:
0999: final String midlet2 = "com.sun.Bar";
1000: final String connection2 = "foo://qux";
1001: final String filter2 = "*.*";
1002: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
1003: connection2, filter2);
1004:
1005: final int midletSuiteId2 = midletSuiteId1 + 17;
1006:
1007: final String midlet3 = "com.sun.Qux";
1008: final String connection3 = "foo4://bar";
1009: final String filter3 = "4.*.123";
1010: final MockReservationDescriptor descriptor3 = new MockReservationDescriptor(
1011: connection3, filter3);
1012:
1013: final Store store = createStore();
1014:
1015: final ConnectionController cc = createConnectionController(store);
1016:
1017: cc.registerConnection(midletSuiteId1, midlet1, descriptor1);
1018: cc.registerConnection(midletSuiteId1, midlet2, descriptor2);
1019: cc.registerConnection(midletSuiteId2, midlet3, descriptor3);
1020: cc.dispose();
1021:
1022: // Check that reservations have been canceled
1023: assertTrue(descriptor1.connectionReservation.isCancelled);
1024: assertTrue(descriptor2.connectionReservation.isCancelled);
1025: assertTrue(descriptor3.connectionReservation.isCancelled);
1026:
1027: // Check that there is nothing registered
1028: assertNull(cc.getMIDlet(midletSuiteId1, connection1));
1029: assertNull(cc.getFilter(midletSuiteId1, connection1));
1030:
1031: assertNull(cc.getMIDlet(midletSuiteId1, connection2));
1032: assertNull(cc.getFilter(midletSuiteId1, connection2));
1033:
1034: assertEquals(0,
1035: cc.listConnections(midletSuiteId1, false).length);
1036:
1037: assertNull(cc.getMIDlet(midletSuiteId2, connection3));
1038: assertNull(cc.getFilter(midletSuiteId2, connection3));
1039:
1040: assertEquals(0,
1041: cc.listConnections(midletSuiteId2, false).length);
1042:
1043: // But check that all the connections reside in the persistent store
1044: store.listConnections(new Store.ConnectionsConsumer() {
1045: public void consume(final int id,
1046: final JUMPConnectionInfo[] infos) {
1047: switch (id) {
1048: case midletSuiteId1:
1049: assertSetsEqualDeep(new JUMPConnectionInfo[] {
1050: new JUMPConnectionInfo(midlet1,
1051: connection1, filter1),
1052: new JUMPConnectionInfo(midlet2,
1053: connection2, filter2), }, infos);
1054: break;
1055:
1056: case midletSuiteId2:
1057: assertSetsEqualDeep(
1058: new JUMPConnectionInfo[] { new JUMPConnectionInfo(
1059: midlet3, connection3, filter3), },
1060: infos);
1061: break;
1062:
1063: default:
1064: fail("Unexpected suite id");
1065: }
1066: }
1067: });
1068: }
1069:
1070: public void testDisposeCancellation() throws IOException {
1071: final int midletSuiteId1 = 123;
1072:
1073: final String midlet1 = "com.sun.Foo";
1074: final String connection1 = "foo://bar";
1075: final String filter1 = "*.123";
1076: final MockReservationDescriptor descriptor1 = new MockReservationDescriptor(
1077: connection1, filter1);
1078:
1079: final String midlet2 = "com.sun.Bar";
1080: final String connection2 = "foo://qux";
1081: final String filter2 = "*.*";
1082: final MockReservationDescriptor descriptor2 = new MockReservationDescriptor(
1083: connection2, filter2);
1084:
1085: final int midletSuiteId2 = midletSuiteId1 + 17;
1086:
1087: final String midlet3 = "com.sun.Qux";
1088: final String connection3 = "foo4://bar";
1089: final String filter3 = "4.*.123";
1090: final MockReservationDescriptor descriptor3 = new MockReservationDescriptor(
1091: connection3, filter3);
1092:
1093: final Store store = createStore();
1094:
1095: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
1096:
1097: final ConnectionController cc = createConnectionController(
1098: store, lifecycleAdapter);
1099:
1100: cc.registerConnection(midletSuiteId1, midlet1, descriptor1);
1101: cc.registerConnection(midletSuiteId1, midlet2, descriptor2);
1102: cc.registerConnection(midletSuiteId2, midlet3, descriptor3);
1103:
1104: final DelayableThread t1 = descriptor1.connectionReservation
1105: .pingThread();
1106: final DelayableThread t2 = descriptor2.connectionReservation
1107: .pingThread();
1108: final DelayableThread t3 = descriptor3.connectionReservation
1109: .pingThread();
1110:
1111: synchronized (t1.lock) {
1112: synchronized (t2.lock) {
1113: synchronized (t3.lock) {
1114: // start the threads first...
1115: t1.start();
1116: t2.start();
1117: t3.start();
1118: // ...but before listeners starts, dispose the controller...
1119: cc.dispose();
1120: // ...now let listeners proceed
1121: }
1122: }
1123: }
1124: try {
1125: t1.join();
1126: t2.join();
1127: t3.join();
1128: } catch (InterruptedException ie) {
1129: fail("Unexpected InterruptedException: " + ie);
1130: }
1131:
1132: // Check that nothing has been launched
1133: assertTrue(lifecycleAdapter.hasNotBeenInvoked());
1134: }
1135:
1136: private static final class Registration {
1137: private final MIDPApp app;
1138: private final String connection;
1139: private final String filter;
1140:
1141: Registration(final int midletSuiteId, final String midlet,
1142: final String connection, final String filter) {
1143: this .app = new MIDPApp(midletSuiteId, midlet);
1144: this .connection = connection;
1145: this .filter = filter;
1146: }
1147: }
1148:
1149: public void testStartup() throws IOException {
1150: final int suiteId1 = 123;
1151: final int suiteId2 = 321;
1152: final Registration[] registrations = {
1153: new Registration(suiteId1, "com.sun.Foo", "foo://bar",
1154: "*.123"),
1155: new Registration(suiteId2, "com.sun.Foo", "foo:qux",
1156: "*.*.*"),
1157: new Registration(suiteId1, "com.sun.Qux", "qux:123",
1158: "*"), };
1159:
1160: final Store store = createStore();
1161: for (int i = 0; i < registrations.length; i++) {
1162: final Registration r = registrations[i];
1163: final JUMPConnectionInfo info = new JUMPConnectionInfo(
1164: r.connection, r.app.midlet, r.filter);
1165: store.addConnection(r.app.midletSuiteID, info);
1166: }
1167:
1168: final ListingLifecycleAdapter lifecycleAdapter = new ListingLifecycleAdapter();
1169:
1170: final ConnectionController cc = createConnectionController(
1171: store, lifecycleAdapter);
1172:
1173: assertSetsEqual(new String[] { registrations[0].connection,
1174: registrations[2].connection, }, cc.listConnections(
1175: suiteId1, false));
1176: assertSetsEqual(new String[] { registrations[1].connection, },
1177: cc.listConnections(suiteId2, false));
1178:
1179: // And now check both MIDlets and filters
1180: for (int i = 0; i < registrations.length; i++) {
1181: final Registration r = registrations[i];
1182: final int id = r.app.midletSuiteID;
1183: final String c = r.connection;
1184: assertEquals(r.app.midlet, cc.getMIDlet(id, c));
1185: assertEquals(r.filter, cc.getFilter(id, c));
1186: }
1187: }
1188:
1189: public void testAccessorsForAnotherSuite() throws IOException {
1190: final int midletSuiteId = 123;
1191: final String midlet = "com.sun.Foo";
1192: final String connection = "foo://bar";
1193: final String filter = "*.123";
1194:
1195: final int midletSuiteId2 = 1001 - midletSuiteId;
1196:
1197: final ConnectionController cc = createConnectionController(createStore());
1198:
1199: cc.registerConnection(midletSuiteId, midlet,
1200: new MockReservationDescriptor(connection, filter));
1201:
1202: assertNull(cc.getMIDlet(midletSuiteId2, connection));
1203: assertNull(cc.getFilter(midletSuiteId2, connection));
1204: }
1205:
1206: public void testAccessorsForUnregistered() throws IOException {
1207: final int midletSuiteId = 123;
1208: final String connection = "foo://bar";
1209:
1210: final ConnectionController cc = createConnectionController(createStore());
1211:
1212: assertNull(cc.getMIDlet(midletSuiteId, connection));
1213: assertNull(cc.getFilter(midletSuiteId, connection));
1214: }
1215:
1216: private void pingDescriptor(
1217: final MockReservationDescriptor descriptor) {
1218: final Thread t = descriptor.connectionReservation.pingThread();
1219: t.start();
1220: try {
1221: t.join();
1222: } catch (InterruptedException ie) {
1223: fail("Unexpected InterruptedException: " + ie);
1224: }
1225: }
1226:
1227: public void testThrowingLifecycleAdapter() throws IOException {
1228: final int midletSuiteId = 123;
1229: final String midlet = "com.sun.Foo";
1230: final String connection = "foo://bar";
1231: final String filter = "*.123";
1232:
1233: final Store store = createStore();
1234:
1235: final MockReservationDescriptor descriptor = new MockReservationDescriptor(
1236: connection, filter);
1237:
1238: final ListingLifecycleAdapter listingLifecycleAdapter = new ListingLifecycleAdapter();
1239:
1240: final LifecycleAdapter throwingLifecycleAdapter = new ThrowingLifecycleAdapter();
1241:
1242: final ProxyLifecycleAdapter lifecycleAdapter = new ProxyLifecycleAdapter();
1243:
1244: final ConnectionController cc = createConnectionController(
1245: store, lifecycleAdapter);
1246:
1247: cc.registerConnection(midletSuiteId, midlet, descriptor);
1248:
1249: lifecycleAdapter.lifecycleAdapter = throwingLifecycleAdapter;
1250: pingDescriptor(descriptor);
1251:
1252: lifecycleAdapter.lifecycleAdapter = listingLifecycleAdapter;
1253: pingDescriptor(descriptor);
1254: assertTrue(listingLifecycleAdapter.hasBeenInvokedOnceFor(
1255: midletSuiteId, midlet));
1256: }
1257: }
|