001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.j2me.payment;
028:
029: import com.sun.midp.midlet.MIDletStateHandler;
030: import com.sun.midp.midlet.MIDletSuite;
031: import com.sun.midp.midletsuite.MIDletSuiteImpl;
032: import com.sun.midp.util.DummyMIDlet;
033: import javax.microedition.midlet.MIDlet;
034: import javax.microedition.payment.*;
035: import com.sun.midp.security.SecurityToken;
036: import com.sun.midp.i3test.*;
037: import com.sun.j2me.payment.*;
038: import java.io.IOException;
039:
040: /**
041: * TestTransactionStore is a class for Transaction store testing
042: *
043: * @version 1.0
044: */
045: public class TestTransactionStore extends TestCase {
046:
047: /**
048: * number of application to be simulated
049: */
050: private static final int numOfApp = 15;
051:
052: /**
053: * Store to be tested
054: */
055: private TransactionStore store;
056:
057: /**
058: * Dummy transaction processor
059: */
060: private TransactionProcessor transProc;
061:
062: /**
063: * Dummy transaction module
064: */
065: private TransactionModuleImpl transMod;
066:
067: /**
068: * SecurityToken for file operation
069: */
070: private SecurityToken token;
071:
072: /**
073: * Maximum records per application
074: */
075: private static int maxRecPerApp = CldcTransactionStoreImpl.MISSED_TRANSACTIONS_LIMIT;
076:
077: /**
078: * Stored transaction for verification
079: */
080: private Transaction[][] transVector = new Transaction[numOfApp][maxRecPerApp];
081:
082: /**
083: * maximum number of simulated application
084: */
085: private int maxNumOfApp = numOfApp;
086:
087: /**
088: * Array of application IDs
089: */
090: private int[] appIDArr = new int[numOfApp];
091:
092: /**
093: * Try to init CldcTransactionStore
094: *
095: * @throws Exception if it is impossible to init CldcTransactionStore
096: */
097: private void PrepareEnv() throws Exception {
098: token = getSecurityToken();
099:
100: MIDletStateHandler msHandler = MIDletStateHandler
101: .getMidletStateHandler();
102: MIDletSuite suite = msHandler.getMIDletSuite();
103: suite.setTempProperty(token, MIDletSuiteImpl.SUITE_NAME_PROP,
104: "DummySuite");
105:
106: // add dummy payment info for CldcTransactionModuleImpl init
107: suite.setTempProperty(token, "Pay-Version", "1.0");
108: suite.setTempProperty(token, "Pay-Adapters", "PPSMS");
109: suite.setTempProperty(token, "MIDlet-Permissions",
110: "javax.microedition.payment.process.jpp");
111: suite.setTempProperty(token, "Pay-Update-Stamp",
112: "2004-11-15 02:00+01:00");
113: suite.setTempProperty(token, "Pay-Update-URL",
114: "http://127.0.0.1/thisgame.manifest.jpp");
115: suite.setTempProperty(token, "Pay-Providers", "SMS1");
116: suite.setTempProperty(token, "Pay-Cache", "no");
117: suite.setTempProperty(token, "Pay-Feature-0", "0");
118: suite.setTempProperty(token, "Pay-SMS1-Info", "PPSMS, EUR,"
119: + System.getProperty("payment.mcc") + ","
120: + System.getProperty("payment.mnc"));
121: suite.setTempProperty(token, "Pay-SMS1-Tag-0",
122: "1.20, 9990000, 0x0cba98765400");
123:
124: // Start a new instance of DummyMIDlet
125: msHandler.startMIDlet("com.sun.midp.util.DummyMIDlet",
126: "DummyMIDlet");
127:
128: // Wait for async request to be processed
129: int i = 1000;
130: while (DummyMIDlet.midlet == null && i > 0) {
131: try {
132: Thread.sleep(100);
133: i--;
134: } catch (InterruptedException ie) {
135: }
136: }
137:
138: if (DummyMIDlet.midlet == null)
139: throw new Exception("Cann't create DummyMIDlet");
140:
141: // PPSMS adapter accepts null cinfiguration string
142: transProc = PPSMSAdapter.getInstance(null);
143: transMod = (TransactionModuleImpl) new CldcTransactionModuleImpl(
144: DummyMIDlet.midlet);
145: store = new CldcTransactionStoreImpl(token);
146: store.cleanUp();
147: }
148:
149: /**
150: * Starts N threads to test
151: * <code>reserve</code> and <code>addTransaction</code>
152: * functions simultaneously
153: *
154: * @throws Exception if something goes wrong with store
155: */
156: private void WriteTest() throws Exception {
157: int i = 0;
158: TestThread[] write2app = new TestThread[numOfApp];
159: for (i = 0; i < numOfApp; i++) {
160: /* Start thread to open Transaction store */
161: write2app[i] = new TestThread(this , i);
162: write2app[i].start();
163: }
164:
165: // Make sure all thread are done before proceeding to the next test.
166: for (i = 0; i < numOfApp; i++) {
167: write2app[i].join();
168: }
169: }
170:
171: /**
172: * Written data verification
173: *
174: * @throws Exception if something goes wrong with store
175: */
176: private void Verification() throws Exception {
177: store = null;
178:
179: // for future tests. For now it is not important
180: System.gc();
181: store = new CldcTransactionStoreImpl(token);
182: TransactionRecord[] transRec;
183: int transID = 0;
184: int appID;
185: Transaction trans = null;
186:
187: // checking for stored records and setDelivering functions
188: for (int i = 0; i < maxNumOfApp; i++) {
189: appID = appIDArr[i];
190: transRec = store.getMissedTransactions(appID);
191: assertEquals(
192: "Number of stored records is different from expected one",
193: transRec.length, maxRecPerApp);
194: for (int j = 0; j < maxRecPerApp; j++) {
195: trans = transVector[i][j];
196: assertEquals("Critical error: FeatureId is different",
197: transRec[j].getFeatureID(), trans
198: .getFeatureID());
199: assertEquals(
200: "Critical error: TransactionID is different",
201: transRec[j].getTransactionID(), trans
202: .getTransactionID());
203: assertEquals("Critical error: State is different",
204: transRec[j].getState(), trans.getState());
205:
206: // NOTE: max number of record to store is
207: // PASSED_TRANSACTIONS_LIMIT
208: store.setDelivered(transRec[j].getTransactionID());
209: }
210: }
211:
212: // should we notify about it?
213: // fail("Payload was not stored");
214:
215: // checking for passed records and functions
216: int passedNum = 0;
217: int appSize;
218: for (int i = 0; i < maxNumOfApp; i++) {
219: appID = appIDArr[i];
220: assertNull("Problem with setDelivered", store
221: .getMissedTransactions(appID));
222: transRec = store.getPassedTransactions(appID);
223: if (transRec != null) {
224: passedNum += transRec.length;
225: for (int j = 0; j < transRec.length; j++) {
226: assertTrue("Passed transaction was not delivered",
227: transRec[j].wasMissed() != true);
228: }
229: }
230: appSize = store.getSizeUsedByApplication(appID);
231: store.removeApplicationRecords(appID);
232: assertTrue("Problem with removeApplicationREcords",
233: appSize == store.getSizeUsedByApplication(appID));
234: }
235:
236: if (passedNum > CldcTransactionStoreImpl.PASSED_TRANSACTIONS_LIMIT) {
237: fail("passedNum is greater then "
238: + "CldcTransactionStoreImpl.PASSED_TRANSACTIONS_LIMIT");
239: } else if (passedNum > maxNumOfApp * maxRecPerApp) {
240: fail("passedNum is less then maxNumOfApp * maxRecPerApp");
241: }
242: store.cleanUp();
243: }
244:
245: /**
246: * Written data verification. removeMissedTransaction test
247: *
248: * @throws Exception if something goes wrong with store
249: */
250: private void Verification2() throws Exception {
251: CldcTransactionStoreImpl store = new CldcTransactionStoreImpl(
252: token);
253: TransactionRecord[] transRec, transRec2;
254: int transID = 0;
255: int appID;
256: Transaction trans = null;
257:
258: // checking for stored records and setDelivering functions
259: for (int i = 0; i < maxNumOfApp; i++) {
260: appID = appIDArr[i];
261: transRec = store.getMissedTransactions(appID);
262: assertEquals(
263: "Number of stored records is different from expected one",
264: transRec.length, maxRecPerApp);
265: store.removeMissedTransaction(appID);
266: transRec2 = store.getMissedTransactions(appID);
267: assertNull("Problem with removeMissedTransaction()",
268: transRec2);
269: }
270: store.cleanUp();
271: }
272:
273: /**
274: * Local thread to perform addTransaction operation for single application
275: */
276: private class TestThread extends Thread {
277: /** reference to the calling class */
278: private TestTransactionStore master;
279: /** application Number */
280: private int appNum;
281:
282: /**
283: * Constructs thread for RMS polling
284: *
285: * @param master the reference to Transaction Store
286: */
287: TestThread(TestTransactionStore master, int appNum) {
288: this .master = master;
289: this .appNum = appNum;
290: }
291:
292: /**
293: * Start thread
294: */
295: public void run() {
296: try {
297: WriteTest();
298: } catch (Exception e) {
299: }
300: }
301:
302: /**
303: * <code>reserve</code> and <code>addTransaction</code> test
304: *
305: * @throws Exception if something goes wrong with store
306: */
307: private void WriteTest() throws Exception {
308:
309: int j = 0;
310: Transaction trans = null;
311: int transID = 0;
312: byte[] payload;
313: int appID;
314: appID = master.store.getNextApplicationID();
315: master.appIDArr[appNum] = appID;
316: try {
317: for (j = 0; j < TestTransactionStore.maxRecPerApp; j++) {
318: payload = new byte[appNum * j + 1];
319: trans = new Transaction(master.transProc,
320: master.transMod, j, "Feature " + j,
321: "Description " + j, payload);
322: transID = master.store.reserve(appID, trans);
323: trans.setTransactionID(transID);
324: master.store.addTransaction(trans);
325: master.transVector[appNum][j] = trans;
326: }
327: } catch (IOException e) {
328: if (appNum == 0 && j == 0) {
329: throw e;
330: } else {
331: master.maxNumOfApp = appNum;
332: }
333: }
334: // addTransaction without reserve should throw exception
335: boolean exc = false;
336: try {
337: trans = new Transaction(master.transProc,
338: master.transMod, j, "Feature " + j,
339: "Description " + j, null);
340: trans.setTransactionID(transID + 1000);
341: master.store.addTransaction(trans);
342: } catch (IllegalStateException e) {
343: exc = true;
344: }
345: assertTrue("addTransaction without reserve", exc);
346: }
347:
348: }
349:
350: /**
351: * Run tests
352: */
353: public void runTests() {
354: boolean fail;
355: try {
356: declare("Prepare enviroment");
357: PrepareEnv();
358: assertTrue(true);
359:
360: declare("Write test");
361: WriteTest();
362: assertTrue(true);
363:
364: declare("Store verification");
365: Verification();
366: assertTrue(true);
367:
368: declare("Write test 2");
369: WriteTest();
370: assertTrue(true);
371:
372: declare("Store verification 2");
373: Verification2();
374: assertTrue(true);
375:
376: } catch (Exception e) {
377: fail("test throws exception");
378: e.printStackTrace();
379: } finally {
380: DummyMIDlet.midlet.notifyDestroyed();
381: }
382: }
383: }
|