diff options
Diffstat (limited to 'tests/AndroidTests/src')
14 files changed, 1332 insertions, 165 deletions
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java index 3daa8ab..fb1b9ad 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java @@ -507,7 +507,7 @@ public class AppCacheTest extends AndroidTestCase { try { // Spin lock waiting for call back synchronized(r) { - getPm().freeStorage(idealStorageSize, pi); + getPm().freeStorage(idealStorageSize, pi.getIntentSender()); long waitTime = 0; while(!r.isDone() && (waitTime < MAX_WAIT_TIME)) { r.wait(WAIT_TIME_INCR); diff --git a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java index a935247..c5562b3 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/BitwiseStreamsTest.java @@ -25,6 +25,8 @@ import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import java.util.Random; + public class BitwiseStreamsTest extends AndroidTestCase { private final static String LOG_TAG = "BitwiseStreamsTest"; @@ -39,7 +41,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { BitwiseInputStream inStream = new BitwiseInputStream(outBuf); byte[] inBufDup = new byte[inBuf.length]; inStream.skip(offset); - for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8); assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } @@ -53,7 +55,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); inStream.skip(offset); byte[] inBufDup = new byte[inBuf.length]; - for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8); assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } @@ -67,7 +69,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); inStream.skip(offset); byte[] inBufDup = new byte[inBuf.length]; - for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8); assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } @@ -84,12 +86,33 @@ public class BitwiseStreamsTest extends AndroidTestCase { BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); inStream.skip(offset); byte[] inBufDup = new byte[inBuf.length]; - for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8); assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } @SmallTest public void testFive() throws Exception { + Random random = new Random(); + int iterations = 10000; + int[] sizeArr = new int[iterations]; + int[] valueArr = new int[iterations]; + BitwiseOutputStream outStream = new BitwiseOutputStream(iterations * 4); + for (int i = 0; i < iterations; i++) { + int x = random.nextInt(); + int size = (x & 0x07) + 1; + int value = x & (-1 >>> (32 - size)); + sizeArr[i] = size; + valueArr[i] = value; + outStream.write(size, value); + } + BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); + for (int i = 0; i < iterations; i++) { + assertEquals(valueArr[i], inStream.read(sizeArr[i])); + } + } + + @SmallTest + public void testSix() throws Exception { int num_runs = 10; long start = android.os.SystemClock.elapsedRealtime(); for (int run = 0; run < num_runs; run++) { @@ -104,7 +127,7 @@ public class BitwiseStreamsTest extends AndroidTestCase { BitwiseInputStream inStream = new BitwiseInputStream(outStream.toByteArray()); inStream.skip(offset); byte[] inBufDup = new byte[inBuf.length]; - for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = inStream.read(8); + for (int i = 0; i < inBufDup.length; i++) inBufDup[i] = (byte)inStream.read(8); assertEquals(HexDump.toHexString(inBuf), HexDump.toHexString(inBufDup)); } long end = android.os.SystemClock.elapsedRealtime(); diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java index b3e88e1..f0ba573 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java @@ -30,10 +30,12 @@ import android.test.suitebuilder.annotation.SmallTest; import java.util.Iterator; +import java.lang.Integer; + import android.util.Log; public class CdmaSmsTest extends AndroidTestCase { - private final static String LOG_TAG = "Cdma_Sms_Test"; + private final static String LOG_TAG = "CDMA"; @SmallTest public void testUserData7bitGsm() throws Exception { @@ -103,6 +105,24 @@ public class CdmaSmsTest extends AndroidTestCase { assertEquals(userData.msgEncoding, revBearerData.userData.msgEncoding); assertEquals(userData.payloadStr.length(), revBearerData.userData.numFields); assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); + userData.payloadStr = "More @ testing\nis great^|^~woohoo"; + revBearerData = BearerData.decode(BearerData.encode(bearerData)); + assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = 0xEE; + concatRef.msgCount = 2; + concatRef.seqNumber = 2; + concatRef.isEightBits = true; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); + userData.userDataHeader = smsHeader; + revBearerData = BearerData.decode(BearerData.encode(bearerData)); + assertEquals(userData.payloadStr, revBearerData.userData.payloadStr); + SmsHeader decodedHeader = revBearerData.userData.userDataHeader; + assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); + assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); + assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); } @SmallTest @@ -136,6 +156,212 @@ public class CdmaSmsTest extends AndroidTestCase { } @SmallTest + public void testMonolithicOne() throws Exception { + String pdu = "0003200010010410168d2002010503060812011101590501c706069706180000000701c108" + + "01c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566"; + BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); + assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT); + assertEquals(bearerData.messageId, 1); + assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY); + assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL); + assertEquals(bearerData.userAckReq, true); + assertEquals(bearerData.readAckReq, true); + assertEquals(bearerData.deliveryAckReq, true); + assertEquals(bearerData.reportReq, false); + assertEquals(bearerData.numberOfMessages, 3); + assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO); + assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW); + assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); + assertEquals(bearerData.callbackNumber.numberMode, + CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); + assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN); + assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN); + assertEquals(bearerData.callbackNumber.numberOfDigits, 7); + assertEquals(bearerData.callbackNumber.address, "3598271"); + assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER); + assertEquals(bearerData.depositIndex, 1382); + assertEquals(bearerData.userResponseCode, 5); + assertEquals(bearerData.msgCenterTimeStamp.year, 2008); + assertEquals(bearerData.msgCenterTimeStamp.month, 11); + assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1); + assertEquals(bearerData.msgCenterTimeStamp.hour, 11); + assertEquals(bearerData.msgCenterTimeStamp.minute, 1); + assertEquals(bearerData.msgCenterTimeStamp.second, 59); + assertEquals(bearerData.validityPeriodAbsolute, null); + assertEquals(bearerData.validityPeriodRelative, 193); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0); + assertEquals(bearerData.deferredDeliveryTimeRelative, 199); + assertEquals(bearerData.hasUserDataHeader, false); + assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII); + assertEquals(bearerData.userData.numFields, 2); + assertEquals(bearerData.userData.payloadStr, "hi"); + } + + @SmallTest + public void testMonolithicTwo() throws Exception { + String pdu = "0003200010010410168d200201050306081201110159050192060697061800000007013d0" + + "801c00901800a01e00b01030c01c00d01070e05039acc13880f018011020566"; + BearerData bearerData = BearerData.decode(HexDump.hexStringToByteArray(pdu)); + assertEquals(bearerData.messageType, BearerData.MESSAGE_TYPE_SUBMIT); + assertEquals(bearerData.messageId, 1); + assertEquals(bearerData.priority, BearerData.PRIORITY_EMERGENCY); + assertEquals(bearerData.privacy, BearerData.PRIVACY_CONFIDENTIAL); + assertEquals(bearerData.userAckReq, true); + assertEquals(bearerData.readAckReq, true); + assertEquals(bearerData.deliveryAckReq, true); + assertEquals(bearerData.reportReq, false); + assertEquals(bearerData.numberOfMessages, 3); + assertEquals(bearerData.alert, BearerData.ALERT_HIGH_PRIO); + assertEquals(bearerData.language, BearerData.LANGUAGE_HEBREW); + assertEquals(bearerData.callbackNumber.digitMode, CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF); + assertEquals(bearerData.callbackNumber.numberMode, + CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK); + assertEquals(bearerData.callbackNumber.ton, CdmaSmsAddress.TON_UNKNOWN); + assertEquals(bearerData.callbackNumber.numberPlan, CdmaSmsAddress.NUMBERING_PLAN_UNKNOWN); + assertEquals(bearerData.callbackNumber.numberOfDigits, 7); + assertEquals(bearerData.callbackNumber.address, "3598271"); + assertEquals(bearerData.displayMode, BearerData.DISPLAY_MODE_USER); + assertEquals(bearerData.depositIndex, 1382); + assertEquals(bearerData.userResponseCode, 5); + assertEquals(bearerData.msgCenterTimeStamp.year, 2008); + assertEquals(bearerData.msgCenterTimeStamp.month, 11); + assertEquals(bearerData.msgCenterTimeStamp.monthDay, 1); + assertEquals(bearerData.msgCenterTimeStamp.hour, 11); + assertEquals(bearerData.msgCenterTimeStamp.minute, 1); + assertEquals(bearerData.msgCenterTimeStamp.second, 59); + assertEquals(bearerData.validityPeriodAbsolute, null); + assertEquals(bearerData.validityPeriodRelative, 61); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.year, 1997); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.month, 5); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.monthDay, 18); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.hour, 0); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.minute, 0); + assertEquals(bearerData.deferredDeliveryTimeAbsolute.second, 0); + assertEquals(bearerData.deferredDeliveryTimeRelative, 146); + assertEquals(bearerData.hasUserDataHeader, false); + assertEquals(bearerData.userData.msgEncoding, UserData.ENCODING_7BIT_ASCII); + assertEquals(bearerData.userData.numFields, 2); + assertEquals(bearerData.userData.payloadStr, "hi"); + } + + @SmallTest + public void testUserDataHeaderConcatRefFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 55; + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = 0xEE; + concatRef.msgCount = 2; + concatRef.seqNumber = 2; + concatRef.isEightBits = true; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); + SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); + assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); + assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); + assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); + assertEquals(decodedHeader.portAddrs, null); + UserData userData = new UserData(); + userData.payloadStr = "User Data Header (UDH) feedback test"; + userData.userDataHeader = smsHeader; + bearerData.userData = userData; + byte[] encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + decodedHeader = revBearerData.userData.userDataHeader; + assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); + assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); + assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); + assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); + assertEquals(decodedHeader.portAddrs, null); + } + + @SmallTest + public void testUserDataHeaderIllegalConcatRef() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 55; + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = 0x10; + concatRef.msgCount = 0; + concatRef.seqNumber = 2; + concatRef.isEightBits = true; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); + SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef, null); + concatRef.isEightBits = false; + encodedHeader = SmsHeader.toByteArray(smsHeader); + decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef, null); + concatRef.msgCount = 1; + concatRef.seqNumber = 2; + encodedHeader = SmsHeader.toByteArray(smsHeader); + decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef, null); + concatRef.msgCount = 1; + concatRef.seqNumber = 0; + encodedHeader = SmsHeader.toByteArray(smsHeader); + decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef, null); + concatRef.msgCount = 2; + concatRef.seqNumber = 1; + encodedHeader = SmsHeader.toByteArray(smsHeader); + decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef.msgCount, 2); + assertEquals(decodedHeader.concatRef.seqNumber, 1); + } + + @SmallTest + public void testUserDataHeaderMixedFeedback() throws Exception { + BearerData bearerData = new BearerData(); + bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; + bearerData.messageId = 42; + SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); + concatRef.refNumber = 0x34; + concatRef.msgCount = 5; + concatRef.seqNumber = 2; + concatRef.isEightBits = false; + SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs(); + portAddrs.destPort = 88; + portAddrs.origPort = 66; + portAddrs.areEightBits = false; + SmsHeader smsHeader = new SmsHeader(); + smsHeader.concatRef = concatRef; + smsHeader.portAddrs = portAddrs; + byte[] encodedHeader = SmsHeader.toByteArray(smsHeader); + SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader); + assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); + assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); + assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); + assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); + assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort); + assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort); + assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits); + UserData userData = new UserData(); + userData.payloadStr = "User Data Header (UDH) feedback test"; + userData.userDataHeader = smsHeader; + bearerData.userData = userData; + byte[] encodedSms = BearerData.encode(bearerData); + BearerData revBearerData = BearerData.decode(encodedSms); + decodedHeader = revBearerData.userData.userDataHeader; + assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber); + assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount); + assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber); + assertEquals(decodedHeader.concatRef.isEightBits, concatRef.isEightBits); + assertEquals(decodedHeader.portAddrs.destPort, portAddrs.destPort); + assertEquals(decodedHeader.portAddrs.origPort, portAddrs.origPort); + assertEquals(decodedHeader.portAddrs.areEightBits, portAddrs.areEightBits); + } + + @SmallTest public void testReplyOption() throws Exception { String pdu1 = "0003104090011648b6a794e0705476bf77bceae934fe5f6d94d87450080a0180"; BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); @@ -298,22 +524,6 @@ public class CdmaSmsTest extends AndroidTestCase { } @SmallTest - public void testMsgCenterTimeStampFeedback() throws Exception { - BearerData bearerData = new BearerData(); - bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER; - bearerData.messageId = 0; - bearerData.hasUserDataHeader = false; - UserData userData = new UserData(); - userData.payloadStr = "test message center timestamp"; - bearerData.userData = userData; - bearerData.timeStamp = HexDump.hexStringToByteArray("112233445566"); - byte []encodedSms = BearerData.encode(bearerData); - BearerData revBearerData = BearerData.decode(encodedSms); - assertEquals(HexDump.toHexString(bearerData.timeStamp), - HexDump.toHexString(revBearerData.timeStamp)); - } - - @SmallTest public void testPrivacyIndicator() throws Exception { String pdu1 = "0003104090010c485f4194dfea34becf61b840090140"; BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); @@ -486,4 +696,15 @@ public class CdmaSmsTest extends AndroidTestCase { assertEquals(revBearerData.displayModeSet, true); assertEquals(revBearerData.displayMode, bearerData.displayMode); } + + @SmallTest + public void testIs91() throws Exception { + String pdu1 = "000320001001070c2039acc13880"; + BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1)); + assertEquals(bd1.callbackNumber.address, "3598271"); + String pdu4 = "000320001001080c283c314724b34e"; + BearerData bd4 = BearerData.decode(HexDump.hexStringToByteArray(pdu4)); + assertEquals(bd4.userData.payloadStr, "ABCDEFG"); + } + } diff --git a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java index d775dc2..0991e8c 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/DatabaseGeneralTest.java @@ -175,6 +175,7 @@ public class DatabaseGeneralTest extends TestCase implements PerformanceTestCase assertEquals("+" + PHONE_NUMBER, number); c.close(); + /* c = mDatabase.query("phones", null, "PHONE_NUMBERS_EQUAL(num, '5551212')", null, null, null, null); assertNotNull(c); @@ -183,6 +184,7 @@ public class DatabaseGeneralTest extends TestCase implements PerformanceTestCase number = c.getString(c.getColumnIndexOrThrow("num")); assertEquals("+" + PHONE_NUMBER, number); c.close(); + */ c = mDatabase.query("phones", null, "PHONE_NUMBERS_EQUAL(num, '011" + PHONE_NUMBER + "')", null, null, null, null); @@ -203,85 +205,97 @@ public class DatabaseGeneralTest extends TestCase implements PerformanceTestCase c.close(); } + + private void phoneNumberCompare(String phone1, String phone2, boolean equal) + throws Exception { + String[] temporalPhoneNumbers = new String[2]; + temporalPhoneNumbers[0] = phone1; + temporalPhoneNumbers[1] = phone2; + + Cursor cursor = mDatabase.rawQuery( + "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", + temporalPhoneNumbers); + try { + assertNotNull(cursor); + assertTrue(cursor.moveToFirst()); + if (equal) { + assertEquals(String.format("Unexpectedly, \"%s != %s\".", phone1, phone2), + "equal", cursor.getString(0)); + } else { + assertEquals(String.format("Unexpectedly, \"%s\" == \"%s\".", phone1, phone2), + "not equal", cursor.getString(0)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + private void assertPhoneNumberEqual(String phone1, String phone2) throws Exception { + phoneNumberCompare(phone1, phone2, true); + } + + private void assertPhoneNumberNotEqual(String phone1, String phone2) throws Exception { + phoneNumberCompare(phone1, phone2, false); + } + /** * Tests international matching issues for the PHONE_NUMBERS_EQUAL function. * * @throws Exception */ + @SmallTest public void testPhoneNumbersEqualInternationl() throws Exception { - Cursor c; - String[] phoneNumbers = new String[2]; + assertPhoneNumberEqual("1", "1"); + assertPhoneNumberEqual("123123", "123123"); + assertPhoneNumberNotEqual("123123", "923123"); + assertPhoneNumberNotEqual("123123", "123129"); + assertPhoneNumberNotEqual("123123", "1231234"); + assertPhoneNumberNotEqual("123123", "0123123"); + assertPhoneNumberEqual("650-253-0000", "6502530000"); + assertPhoneNumberEqual("650-253-0000", "650 253 0000"); + assertPhoneNumberEqual("650 253 0000", "6502530000"); + assertPhoneNumberEqual("+1 650-253-0000", "6502530000"); + assertPhoneNumberEqual("001 650-253-0000", "6502530000"); + assertPhoneNumberEqual("0111 650-253-0000", "6502530000"); // Russian trunk digit - phoneNumbers[0] = "+79161234567"; // globablly dialable number - phoneNumbers[1] = "89161234567"; // in-country dialable number - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("equal", c.getString(0)); - c.close(); + assertPhoneNumberEqual("+79161234567", "89161234567"); // French trunk digit - phoneNumbers[0] = "+33123456789"; // globablly dialable number - phoneNumbers[1] = "0123456789"; // in-country dialable number - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("equal", c.getString(0)); - c.close(); - + assertPhoneNumberEqual("+33123456789", "0123456789"); // Trunk digit for city codes in the Netherlands - phoneNumbers[0] = "+31771234567"; // globablly dialable number - phoneNumbers[1] = "0771234567"; // in-country dialable number - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("equal", c.getString(0)); - c.close(); + assertPhoneNumberEqual("+31771234567", "0771234567"); // Test broken caller ID seen on call from Thailand to the US - phoneNumbers[0] = "+66811234567"; // in address book - phoneNumbers[1] = "166811234567"; // came in from the network - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("equal", c.getString(0)); - c.close(); + assertPhoneNumberEqual("+66811234567", "166811234567"); // Test the same in-country number with different country codes - phoneNumbers[0] = "+33123456789"; - phoneNumbers[1] = "+1123456789"; - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("not equal", c.getString(0)); - c.close(); + assertPhoneNumberNotEqual("+33123456789", "+1123456789"); // Test one number with country code and the other without - phoneNumbers[0] = "5125551212"; - phoneNumbers[1] = "+15125551212"; - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("equal", c.getString(0)); - c.close(); + assertPhoneNumberEqual("5125551212", "+15125551212"); // Test two NANP numbers that only differ in the area code - phoneNumbers[0] = "5125551212"; - phoneNumbers[1] = "6505551212"; - c = mDatabase.rawQuery( - "SELECT CASE WHEN PHONE_NUMBERS_EQUAL(?, ?) THEN 'equal' ELSE 'not equal' END", - phoneNumbers); - assertTrue(c.moveToFirst()); - assertEquals("not equal", c.getString(0)); - c.close(); + assertPhoneNumberNotEqual("5125551212", "6505551212"); + + // Japanese phone numbers + assertPhoneNumberEqual("090-1234-5678", "+819012345678"); + assertPhoneNumberEqual("090(1234)5678", "+819012345678"); + assertPhoneNumberEqual("090-1234-5678", "+81-90-1234-5678"); + + // Equador + assertPhoneNumberEqual("+593(800)123-1234", "8001231234"); + assertPhoneNumberEqual("+593-2-1234-123", "21234123"); + + // Two continuous 0 at the beginning of the phone string should not be + // treated as trunk prefix. + assertPhoneNumberNotEqual("008001231234", "8001231234"); + + // Confirm that the bug found before does not re-appear. + assertPhoneNumberNotEqual("080-1234-5678", "+819012345678"); } @MediumTest @@ -509,9 +523,14 @@ public class DatabaseGeneralTest extends TestCase implements PerformanceTestCase Cursor c; mDatabase.execSQL("CREATE TABLE tokens (" + "token TEXT COLLATE unicode," + - "source INTEGER " + + "source INTEGER," + + "token_index INTEGER," + + "tag TEXT" + + ");"); + mDatabase.execSQL("CREATE TABLE tokens_no_index (" + + "token TEXT COLLATE unicode," + + "source INTEGER" + ");"); - String[] cols = new String[]{"token", "source"}; Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, "SELECT _TOKENIZE(NULL, NULL, NULL, NULL)", null)); @@ -523,60 +542,152 @@ public class DatabaseGeneralTest extends TestCase implements PerformanceTestCase "SELECT _TOKENIZE('tokens', 10, 'some string', NULL)", null)); Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase, - "SELECT _TOKENIZE('tokens', 1, 'some string ok', ' ')", null)); - + "SELECT _TOKENIZE('tokens', 11, 'some string ok', ' ', 1, 'foo')", null)); + Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, + "SELECT _TOKENIZE('tokens', 11, 'second field', ' ', 1, 'bar')", null)); + + Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase, + "SELECT _TOKENIZE('tokens_no_index', 20, 'some string ok', ' ')", null)); + Assert.assertEquals(3, DatabaseUtils.longForQuery(mDatabase, + "SELECT _TOKENIZE('tokens_no_index', 21, 'foo bar baz', ' ', 0)", null)); + // test Chinese String chinese = new String("\u4eac\u4ec5 \u5c3d\u5f84\u60ca"); Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, - "SELECT _TOKENIZE('tokens', 1,'" + chinese + "', ' ')", null)); + "SELECT _TOKENIZE('tokens', 12,'" + chinese + "', ' ', 1)", null)); String icustr = new String("Fr\u00e9d\u00e9ric Hj\u00f8nnev\u00e5g"); Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, - "SELECT _TOKENIZE('tokens', 1, '" + icustr + "', ' ')", null)); + "SELECT _TOKENIZE('tokens', 13, '" + icustr + "', ' ', 1)", null)); - Assert.assertEquals(7, DatabaseUtils.longForQuery(mDatabase, + Assert.assertEquals(9, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens;", null)); String key = DatabaseUtils.getHexCollationKey("Frederic Hjonneva"); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(13, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); key = DatabaseUtils.getHexCollationKey("Hjonneva"); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(13, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); key = DatabaseUtils.getHexCollationKey("some string ok"); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals("foo", DatabaseUtils.stringForQuery(mDatabase, + "SELECT tag from tokens where token GLOB '" + key + "*'", null)); key = DatabaseUtils.getHexCollationKey("string"); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals("foo", DatabaseUtils.stringForQuery(mDatabase, + "SELECT tag from tokens where token GLOB '" + key + "*'", null)); key = DatabaseUtils.getHexCollationKey("ok"); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); - + Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(2, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals("foo", DatabaseUtils.stringForQuery(mDatabase, + "SELECT tag from tokens where token GLOB '" + key + "*'", null)); + + key = DatabaseUtils.getHexCollationKey("second field"); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals("bar", DatabaseUtils.stringForQuery(mDatabase, + "SELECT tag from tokens where token GLOB '" + key + "*'", null)); + key = DatabaseUtils.getHexCollationKey("field"); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(11, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals("bar", DatabaseUtils.stringForQuery(mDatabase, + "SELECT tag from tokens where token GLOB '" + key + "*'", null)); + key = DatabaseUtils.getHexCollationKey(chinese); String[] a = new String[1]; a[0] = key; Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token= ?", a)); + Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token= ?", a)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token= ?", a)); a[0] += "*"; Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB ?", a)); + Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB ?", a)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB ?", a)); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token= '" + key + "'", null)); + Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token= '" + key + "'", null)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token= '" + key + "'", null)); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); key = DatabaseUtils.getHexCollationKey("\u4eac\u4ec5"); Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); + key = DatabaseUtils.getHexCollationKey("\u5c3d\u5f84\u60ca"); + Log.d("DatabaseGeneralTest", "key = " + key); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT count(*) from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(12, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens where token GLOB '" + key + "*'", null)); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT token_index from tokens where token GLOB '" + key + "*'", null)); Assert.assertEquals(0, DatabaseUtils.longForQuery(mDatabase, "SELECT count(*) from tokens where token GLOB 'ab*'", null)); + + key = DatabaseUtils.getHexCollationKey("some string ok"); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT count(*) from tokens_no_index where token GLOB '" + key + "*'", null)); + Assert.assertEquals(20, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens_no_index where token GLOB '" + key + "*'", null)); + + key = DatabaseUtils.getHexCollationKey("bar"); + Assert.assertEquals(1, DatabaseUtils.longForQuery(mDatabase, + "SELECT count(*) from tokens_no_index where token GLOB '" + key + "*'", null)); + Assert.assertEquals(21, DatabaseUtils.longForQuery(mDatabase, + "SELECT source from tokens_no_index where token GLOB '" + key + "*'", null)); } @MediumTest diff --git a/tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java b/tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java new file mode 100644 index 0000000..2bdf1dd --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/NeighboringCellInfoTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.unit_tests; + +import android.test.AndroidTestCase; +import android.telephony.NeighboringCellInfo; +import android.test. suitebuilder.annotation.SmallTest; + +public class NeighboringCellInfoTest extends AndroidTestCase { + @SmallTest + public void testConstructor() { + NeighboringCellInfo empty = new NeighboringCellInfo(); + assertEquals(NeighboringCellInfo.UNKNOWN_RSSI, empty.getRssi()); + assertEquals(NeighboringCellInfo.UNKNOWN_CID, empty.getCid()); + + int rssi = 31; + int cid = 0xffffffff; + NeighboringCellInfo max = new NeighboringCellInfo(rssi, cid); + assertEquals(rssi, max.getRssi()); + assertEquals(cid, max.getCid()); + } + + @SmallTest + public void testGetAndSet() { + int rssi = 16; + int cid = 0x12345678; + NeighboringCellInfo nc = new NeighboringCellInfo(); + nc.setRssi(rssi); + nc.setCid(cid); + assertEquals(rssi, nc.getRssi()); + assertEquals(cid, nc.getCid()); + } + + @SmallTest + public void testToString() { + NeighboringCellInfo empty = new NeighboringCellInfo(); + assertEquals("[/ at /]", empty.toString()); + + NeighboringCellInfo nc = new NeighboringCellInfo(16, 0x12345678); + assertEquals("[12345678 at 16]", nc.toString()); + } +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/SMSTest.java b/tests/AndroidTests/src/com/android/unit_tests/SMSTest.java index 360352b..9d44fd9 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/SMSTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/SMSTest.java @@ -69,10 +69,15 @@ public class SMSTest extends AndroidTestCase { SmsHeader header = sms.getUserDataHeader(); assertNotNull(header); - - Iterator<SmsHeader.Element> elements = header.getElements().iterator(); - assertNotNull(elements); - + assertNotNull(header.concatRef); + assertEquals(header.concatRef.refNumber, 42); + assertEquals(header.concatRef.msgCount, 2); + assertEquals(header.concatRef.seqNumber, 1); + assertEquals(header.concatRef.isEightBits, true); + assertNotNull(header.portAddrs); + assertEquals(header.portAddrs.destPort, 2948); + assertEquals(header.portAddrs.origPort, 9200); + assertEquals(header.portAddrs.areEightBits, false); pdu = "07914140279510F6440A8111110301003BF56080207130238A3B0B05040B8423F" + "000032A0202362E3130322E3137312E3135302F524E453955304A6D7135514141" @@ -81,9 +86,15 @@ public class SMSTest extends AndroidTestCase { header = sms.getUserDataHeader(); assertNotNull(header); - - elements = header.getElements().iterator(); - assertNotNull(elements); + assertNotNull(header.concatRef); + assertEquals(header.concatRef.refNumber, 42); + assertEquals(header.concatRef.msgCount, 2); + assertEquals(header.concatRef.seqNumber, 2); + assertEquals(header.concatRef.isEightBits, true); + assertNotNull(header.portAddrs); + assertEquals(header.portAddrs.destPort, 2948); + assertEquals(header.portAddrs.origPort, 9200); + assertEquals(header.portAddrs.areEightBits, false); /* * UCS-2 encoded SMS diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java index f3c1542..c4f1ab6 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java @@ -23,7 +23,10 @@ import android.app.ISearchManager; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; +import android.os.Bundle; +import android.os.RemoteException; import android.os.ServiceManager; +import android.server.search.SearchableInfo; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; @@ -37,12 +40,11 @@ import android.util.AndroidRuntimeException; * com.android.unit_tests/android.test.InstrumentationTestRunner */ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalActivity> { - - // If non-zero, enable a set of tests that start and stop the search manager. - // This is currently disabled because it's causing an unwanted jump from the unit test - // activity into the contacts activity. We'll put this back after we disable that jump. - private static final int TEST_SEARCH_START = 0; - + + private ComponentName SEARCHABLE_ACTIVITY = + new ComponentName("com.android.unit_tests", + "com.android.unit_tests.SearchableActivity"); + /* * Bug list of test ideas. * @@ -88,7 +90,30 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct super.setUp(); Activity testActivity = getActivity(); - mContext = (Context)testActivity; + mContext = testActivity; + } + + private ISearchManager getSearchManagerService() { + return ISearchManager.Stub.asInterface( + ServiceManager.getService(Context.SEARCH_SERVICE)); + } + + // Checks that the search UI is visible. + private void assertSearchVisible() { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + assertTrue("SearchManager thinks search UI isn't visible when it should be", + searchManager.isVisible()); + } + + // Checks that the search UI is not visible. + // This checks both the SearchManager and the SearchManagerService, + // since SearchManager keeps a local variable for the visibility. + private void assertSearchNotVisible() { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + assertFalse("SearchManager thinks search UI is visible when it shouldn't be", + searchManager.isVisible()); } /** @@ -97,29 +122,7 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct */ @MediumTest public void testSearchManagerInterfaceAvailable() { - ISearchManager searchManager1 = ISearchManager.Stub.asInterface( - ServiceManager.getService(Context.SEARCH_SERVICE)); - assertNotNull(searchManager1); - } - - /** - * The goal of this test is to confirm that we can *only* obtain a search manager - * interface from an Activity context. - */ - @MediumTest - public void testSearchManagerContextRestrictions() { - SearchManager searchManager1 = (SearchManager) - mContext.getSystemService(Context.SEARCH_SERVICE); - assertNotNull(searchManager1); - - Context applicationContext = mContext.getApplicationContext(); - // this should fail, because you can't get a SearchManager from a non-Activity context - try { - applicationContext.getSystemService(Context.SEARCH_SERVICE); - assertFalse("Shouldn't retrieve SearchManager from a non-Activity context", true); - } catch (AndroidRuntimeException e) { - // happy here - we should catch this. - } + assertNotNull(getSearchManagerService()); } /** @@ -135,38 +138,129 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct SearchManager searchManager2 = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); assertNotNull(searchManager2); - assertSame( searchManager1, searchManager2 ); + assertSame(searchManager1, searchManager2 ); } - + + @MediumTest + public void testSearchables() { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + SearchableInfo si; + + si = searchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, false); + assertNotNull(si); + assertFalse(searchManager.isDefaultSearchable(si)); + si = searchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, true); + assertNotNull(si); + assertTrue(searchManager.isDefaultSearchable(si)); + si = searchManager.getSearchableInfo(null, true); + assertNotNull(si); + assertTrue(searchManager.isDefaultSearchable(si)); + } + + /** + * Tests that rapid calls to start-stop-start doesn't cause problems. + */ + @MediumTest + public void testSearchManagerFastInvocations() throws Exception { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + assertNotNull(searchManager); + assertSearchNotVisible(); + + searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false); + searchManager.stopSearch(); + assertSearchNotVisible(); + } + + /** + * Tests that startSearch() is idempotent. + */ + @MediumTest + public void testStartSearchIdempotent() throws Exception { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + assertNotNull(searchManager); + assertSearchNotVisible(); + + searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false); + searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + assertSearchNotVisible(); + } + + /** + * Tests that stopSearch() is idempotent and can be called when the search UI is not visible. + */ + @MediumTest + public void testStopSearchIdempotent() throws Exception { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + assertNotNull(searchManager); + assertSearchNotVisible(); + searchManager.stopSearch(); + assertSearchNotVisible(); + + searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + searchManager.stopSearch(); + assertSearchNotVisible(); + } + /** * The goal of this test is to confirm that we can start and then * stop a simple search. */ - - @MediumTest - public void testSearchManagerInvocations() { + @MediumTest + public void testSearchManagerInvocations() throws Exception { SearchManager searchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); assertNotNull(searchManager); - - // TODO: make a real component name, or remove this need - final ComponentName cn = new ComponentName("", ""); - - if (TEST_SEARCH_START != 0) { - // These tests should simply run to completion w/o exceptions - searchManager.startSearch(null, false, cn, null, false); - searchManager.stopSearch(); - - searchManager.startSearch("", false, cn, null, false); - searchManager.stopSearch(); - - searchManager.startSearch("test search string", false, cn, null, false); - searchManager.stopSearch(); - - searchManager.startSearch("test search string", true, cn, null, false); - searchManager.stopSearch(); - } - } + assertSearchNotVisible(); -} + // These tests should simply run to completion w/o exceptions + searchManager.startSearch(null, false, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + assertSearchNotVisible(); + + searchManager.startSearch("", false, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + assertSearchNotVisible(); + + searchManager.startSearch("test search string", false, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + assertSearchNotVisible(); + searchManager.startSearch("test search string", true, SEARCHABLE_ACTIVITY, null, false); + assertSearchVisible(); + searchManager.stopSearch(); + assertSearchNotVisible(); + } + + @MediumTest + public void testSearchDialogState() throws Exception { + SearchManager searchManager = (SearchManager) + mContext.getSystemService(Context.SEARCH_SERVICE); + assertNotNull(searchManager); + + Bundle searchState; + + // search dialog not visible, so no state should be stored + searchState = searchManager.saveSearchDialog(); + assertNull(searchState); + + searchManager.startSearch("test search string", true, SEARCHABLE_ACTIVITY, null, false); + searchState = searchManager.saveSearchDialog(); + assertNotNull(searchState); + searchManager.stopSearch(); + } + +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchableActivity.java b/tests/AndroidTests/src/com/android/unit_tests/SearchableActivity.java new file mode 100644 index 0000000..53f40e9 --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/SearchableActivity.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.unit_tests; + +import android.app.Activity; +import android.os.Bundle; + +public class SearchableActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + finish(); + } + +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java index bdf67ba..ecc8dfe 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java @@ -20,6 +20,7 @@ import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; @@ -71,19 +72,19 @@ public class SearchablesTest extends AndroidTestCase { * TODO: The metadata source needs to be mocked out because adding * searchability metadata via this test is causing it to leak into the * real system. So for now I'm just going to test for existence of the - * GoogleSearch app (which is searchable). + * GlobalSearch app (which is searchable). */ - public void testSearchableGoogleSearch() { + public void testSearchableGlobalSearch() { // test basic array & hashmap Searchables searchables = new Searchables(mContext); searchables.buildSearchableList(); // test linkage from another activity // TODO inject this via mocking into the package manager. - // TODO for now, just check for searchable GoogleSearch app (this isn't really a unit test) + // TODO for now, just check for searchable GlobalSearch app (this isn't really a unit test) ComponentName thisActivity = new ComponentName( - "com.android.googlesearch", - "com.android.googlesearch.GoogleSearch"); + "com.android.globalsearch", + "com.android.globalsearch.GlobalSearch"); SearchableInfo si = searchables.getSearchableInfo(thisActivity); assertNotNull(si); @@ -92,7 +93,7 @@ public class SearchablesTest extends AndroidTestCase { Context appContext = si.getActivityContext(mContext); assertNotNull(appContext); MoreAsserts.assertNotEqual(appContext, mContext); - assertEquals("Google Search", appContext.getString(si.getHintId())); + assertEquals("Android Search", appContext.getString(si.getHintId())); assertEquals("Google", appContext.getString(si.getLabelId())); } @@ -306,6 +307,14 @@ public class SearchablesTest extends AndroidTestCase { throws PackageManager.NameNotFoundException { return mRealContext.createPackageContext(packageName, flags); } + + /** + * Message broadcast. Pass through for now. + */ + @Override + public void sendBroadcast(Intent intent) { + mRealContext.sendBroadcast(intent); + } } /** @@ -361,7 +370,8 @@ public class SearchablesTest extends AndroidTestCase { @Override public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) { assertNotNull(intent); - assertEquals(intent.getAction(), Intent.ACTION_SEARCH); + assertTrue(intent.getAction().equals(Intent.ACTION_SEARCH) + || intent.getAction().equals(Intent.ACTION_WEB_SEARCH)); switch (mSearchablesMode) { case SEARCHABLES_PASSTHROUGH: return mRealPackageManager.queryIntentActivities(intent, flags); @@ -375,7 +385,8 @@ public class SearchablesTest extends AndroidTestCase { @Override public ResolveInfo resolveActivity(Intent intent, int flags) { assertNotNull(intent); - assertEquals(intent.getAction(), SearchManager.INTENT_ACTION_GLOBAL_SEARCH); + assertTrue(intent.getAction().equals(Intent.ACTION_WEB_SEARCH) + || intent.getAction().equals(SearchManager.INTENT_ACTION_GLOBAL_SEARCH)); switch (mSearchablesMode) { case SEARCHABLES_PASSTHROUGH: return mRealPackageManager.resolveActivity(intent, flags); @@ -438,6 +449,29 @@ public class SearchablesTest extends AndroidTestCase { throw new UnsupportedOperationException(); } } + + /** + * Get the activity information for a particular activity. + * + * @param name The name of the activity to find. + * @param flags Additional option flags. + * + * @return ActivityInfo Information about the activity, if found, else null. + */ + @Override + public ActivityInfo getActivityInfo(ComponentName name, int flags) + throws NameNotFoundException { + assertNotNull(name); + MoreAsserts.assertNotEqual(name, ""); + switch (mSearchablesMode) { + case SEARCHABLES_PASSTHROUGH: + return mRealPackageManager.getActivityInfo(name, flags); + case SEARCHABLES_MOCK_ZERO: + throw new NameNotFoundException(); + default: + throw new UnsupportedOperationException(); + } + } } } diff --git a/tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java b/tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java new file mode 100644 index 0000000..bc61e27 --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/SuggestionProvider.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.unit_tests; + +import android.app.SearchManager; +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Intent; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; + +/** Simple test provider that runs in the local process. + * + * Used by {@link SearchManagerTest}. + */ +public class SuggestionProvider extends ContentProvider { + private static final String TAG = "SuggestionProvider"; + + private static final int SEARCH_SUGGESTIONS = 1; + + private static final UriMatcher sURLMatcher = new UriMatcher( + UriMatcher.NO_MATCH); + + static { + sURLMatcher.addURI("*", SearchManager.SUGGEST_URI_PATH_QUERY, + SEARCH_SUGGESTIONS); + sURLMatcher.addURI("*", SearchManager.SUGGEST_URI_PATH_QUERY + "/*", + SEARCH_SUGGESTIONS); + } + + private static final String[] COLUMNS = new String[] { + "_id", + SearchManager.SUGGEST_COLUMN_TEXT_1, + SearchManager.SUGGEST_COLUMN_INTENT_ACTION, + SearchManager.SUGGEST_COLUMN_QUERY + }; + + public SuggestionProvider() { + } + + @Override + public boolean onCreate() { + return true; + } + + @Override + public Cursor query(Uri url, String[] projectionIn, String selection, + String[] selectionArgs, String sort) { + int match = sURLMatcher.match(url); + switch (match) { + case SEARCH_SUGGESTIONS: + String query = url.getLastPathSegment(); + MatrixCursor cursor = new MatrixCursor(COLUMNS); + String[] suffixes = { "", "a", " foo", "XXXXXXXXXXXXXXXXX" }; + for (String suffix : suffixes) { + addRow(cursor, query + suffix); + } + return cursor; + default: + throw new IllegalArgumentException("Unknown URL: " + url); + } + } + + private void addRow(MatrixCursor cursor, String string) { + long id = cursor.getCount(); + cursor.newRow().add(id).add(string).add(Intent.ACTION_SEARCH).add(string); + } + + @Override + public String getType(Uri url) { + int match = sURLMatcher.match(url); + switch (match) { + case SEARCH_SUGGESTIONS: + return SearchManager.SUGGEST_MIME_TYPE; + default: + throw new IllegalArgumentException("Unknown URL: " + url); + } + } + + @Override + public int update(Uri url, ContentValues values, String where, String[] whereArgs) { + throw new UnsupportedOperationException("update not supported"); + } + + @Override + public Uri insert(Uri url, ContentValues initialValues) { + throw new UnsupportedOperationException("insert not supported"); + } + + @Override + public int delete(Uri url, String where, String[] whereArgs) { + throw new UnsupportedOperationException("delete not supported"); + } +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/TextUtilsTest.java b/tests/AndroidTests/src/com/android/unit_tests/TextUtilsTest.java index 51e841c..7720041 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/TextUtilsTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/TextUtilsTest.java @@ -276,6 +276,7 @@ public class TextUtilsTest extends TestCase { Spannable s3 = new SpannableString(s1); s3.setSpan(new StyleSpan(0), 5, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); TextPaint p = new TextPaint(); + p.setFlags(p.getFlags() & ~p.DEV_KERN_TEXT_FLAG); for (int i = 0; i < 100; i++) { for (int j = 0; j < 3; j++) { diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/MemoryFileProvider.java b/tests/AndroidTests/src/com/android/unit_tests/content/MemoryFileProvider.java new file mode 100644 index 0000000..b31ce18 --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/content/MemoryFileProvider.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.unit_tests.content; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.UriMatcher; +import android.content.res.AssetFileDescriptor; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.net.Uri; +import android.os.MemoryFile; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; + +/** Simple test provider that runs in the local process. */ +public class MemoryFileProvider extends ContentProvider { + private static final String TAG = "MemoryFileProvider"; + + private static final String DATA_FILE = "data.bin"; + + // some random data + public static final byte[] TEST_BLOB = new byte[] { + -12, 127, 0, 3, 1, 2, 3, 4, 5, 6, 1, -128, -1, -54, -65, 35, + -53, -96, -74, -74, -55, -43, -69, 3, 52, -58, + -121, 127, 87, -73, 16, -13, -103, -65, -128, -36, + 107, 24, 118, -17, 97, 97, -88, 19, -94, -54, + 53, 43, 44, -27, -124, 28, -74, 26, 35, -36, + 16, -124, -31, -31, -128, -79, 108, 116, 43, -17 }; + + private SQLiteOpenHelper mOpenHelper; + + private static final int DATA_ID_BLOB = 1; + private static final int HUGE = 2; + private static final int FILE = 3; + + private static final UriMatcher sURLMatcher = new UriMatcher( + UriMatcher.NO_MATCH); + + static { + sURLMatcher.addURI("*", "data/#/blob", DATA_ID_BLOB); + sURLMatcher.addURI("*", "huge", HUGE); + sURLMatcher.addURI("*", "file", FILE); + } + + private static class DatabaseHelper extends SQLiteOpenHelper { + private static final String DATABASE_NAME = "local.db"; + private static final int DATABASE_VERSION = 1; + + public DatabaseHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE data (" + + "_id INTEGER PRIMARY KEY," + + "_blob TEXT, " + + "integer INTEGER);"); + + // insert alarms + ContentValues values = new ContentValues(); + values.put("_id", 1); + values.put("_blob", TEST_BLOB); + values.put("integer", 100); + db.insert("data", null, values); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { + Log.w(TAG, "Upgrading test database from version " + + oldVersion + " to " + currentVersion + + ", which will destroy all old data"); + db.execSQL("DROP TABLE IF EXISTS data"); + onCreate(db); + } + } + + + public MemoryFileProvider() { + } + + @Override + public boolean onCreate() { + mOpenHelper = new DatabaseHelper(getContext()); + try { + OutputStream out = getContext().openFileOutput(DATA_FILE, Context.MODE_PRIVATE); + out.write(TEST_BLOB); + out.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + return true; + } + + @Override + public Cursor query(Uri url, String[] projectionIn, String selection, + String[] selectionArgs, String sort) { + throw new UnsupportedOperationException("query not supported"); + } + + @Override + public String getType(Uri url) { + int match = sURLMatcher.match(url); + switch (match) { + case DATA_ID_BLOB: + return "application/octet-stream"; + case FILE: + return "application/octet-stream"; + default: + throw new IllegalArgumentException("Unknown URL"); + } + } + + @Override + public AssetFileDescriptor openAssetFile(Uri url, String mode) throws FileNotFoundException { + int match = sURLMatcher.match(url); + switch (match) { + case DATA_ID_BLOB: + String sql = "SELECT _blob FROM data WHERE _id=" + url.getPathSegments().get(1); + return getBlobColumnAsAssetFile(url, mode, sql); + case HUGE: + try { + MemoryFile memoryFile = new MemoryFile(null, 5000000); + memoryFile.writeBytes(TEST_BLOB, 0, 1000000, TEST_BLOB.length); + memoryFile.deactivate(); + return AssetFileDescriptor.fromMemoryFile(memoryFile); + } catch (IOException ex) { + throw new FileNotFoundException("Error reading " + url + ":" + ex.toString()); + } + case FILE: + File file = getContext().getFileStreamPath(DATA_FILE); + ParcelFileDescriptor fd = + ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); + return new AssetFileDescriptor(fd, 0, AssetFileDescriptor.UNKNOWN_LENGTH); + default: + throw new FileNotFoundException("No files supported by provider at " + url); + } + } + + private AssetFileDescriptor getBlobColumnAsAssetFile(Uri url, String mode, String sql) + throws FileNotFoundException { + if (!"r".equals(mode)) { + throw new FileNotFoundException("Mode " + mode + " not supported for " + url); + } + try { + SQLiteDatabase db = mOpenHelper.getReadableDatabase(); + MemoryFile file = simpleQueryForBlobMemoryFile(db, sql); + if (file == null) throw new FileNotFoundException("No such entry: " + url); + AssetFileDescriptor afd = AssetFileDescriptor.fromMemoryFile(file); + file.deactivate(); + // need to dup and then close? openFileHelper() doesn't do that though + return afd; + } catch (IOException ex) { + throw new FileNotFoundException("Error reading " + url + ":" + ex.toString()); + } + } + + private MemoryFile simpleQueryForBlobMemoryFile(SQLiteDatabase db, String sql) throws IOException { + Cursor cursor = db.rawQuery(sql, null); + try { + if (!cursor.moveToFirst()) { + return null; + } + byte[] bytes = cursor.getBlob(0); + MemoryFile file = new MemoryFile(null, bytes.length); + file.writeBytes(bytes, 0, 0, bytes.length); + return file; + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + @Override + public int update(Uri url, ContentValues values, String where, String[] whereArgs) { + throw new UnsupportedOperationException("update not supported"); + } + + @Override + public Uri insert(Uri url, ContentValues initialValues) { + throw new UnsupportedOperationException("insert not supported"); + } + + @Override + public int delete(Uri url, String where, String[] whereArgs) { + throw new UnsupportedOperationException("delete not supported"); + } +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/MemoryFileProviderTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/MemoryFileProviderTest.java new file mode 100644 index 0000000..f88a9da --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/content/MemoryFileProviderTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.unit_tests.content; + +import android.content.ContentResolver; +import android.net.Uri; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.MediumTest; + +import java.io.InputStream; +import java.util.Arrays; + +/** + * Tests reading a MemoryFile-based AssestFile from a ContentProvider running + * in a different process. + */ +public class MemoryFileProviderTest extends AndroidTestCase { + + // reads from a cross-process AssetFileDescriptor for a MemoryFile + @MediumTest + public void testRead() throws Exception { + ContentResolver resolver = getContext().getContentResolver(); + Uri uri = Uri.parse("content://com.android.unit_tests.content.MemoryFileProvider/data/1/blob"); + byte[] buf = new byte[MemoryFileProvider.TEST_BLOB.length]; + InputStream in = resolver.openInputStream(uri); + assertNotNull(in); + int count = in.read(buf); + assertEquals(buf.length, count); + assertEquals(-1, in.read()); + in.close(); + assertTrue(Arrays.equals(MemoryFileProvider.TEST_BLOB, buf)); + } + + // tests that we don't leak file descriptors or virtual address space + @MediumTest + public void testClose() throws Exception { + ContentResolver resolver = getContext().getContentResolver(); + // open enough file descriptors that we will crash something if we leak FDs + // or address space + for (int i = 0; i < 1025; i++) { + Uri uri = Uri.parse("content://com.android.unit_tests.content.MemoryFileProvider/huge"); + InputStream in = resolver.openInputStream(uri); + assertNotNull("Failed to open stream number " + i, in); + assertEquals(1000000, in.skip(1000000)); + byte[] buf = new byte[MemoryFileProvider.TEST_BLOB.length]; + int count = in.read(buf); + assertEquals(buf.length, count); + assertTrue(Arrays.equals(MemoryFileProvider.TEST_BLOB, buf)); + in.close(); + } + } + + // tests that we haven't broken AssestFileDescriptors for normal files. + @MediumTest + public void testFile() throws Exception { + ContentResolver resolver = getContext().getContentResolver(); + Uri uri = Uri.parse("content://com.android.unit_tests.content.MemoryFileProvider/file"); + byte[] buf = new byte[MemoryFileProvider.TEST_BLOB.length]; + InputStream in = resolver.openInputStream(uri); + assertNotNull(in); + int count = in.read(buf); + assertEquals(buf.length, count); + assertEquals(-1, in.read()); + in.close(); + assertTrue(Arrays.equals(MemoryFileProvider.TEST_BLOB, buf)); + } + +} diff --git a/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java b/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java index 508afcf..18b3d63 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/os/MemoryFileTest.java @@ -17,18 +17,21 @@ package com.android.unit_tests.os; import android.os.MemoryFile; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; -import junit.framework.TestCase; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.IOException; - -import java.util.List; import java.util.ArrayList; +import java.util.List; -public class MemoryFileTest extends TestCase { +public class MemoryFileTest extends AndroidTestCase { private void compareBuffers(byte[] buffer1, byte[] buffer2, int length) throws Exception { for (int i = 0; i < length; i++) { @@ -94,6 +97,187 @@ public class MemoryFileTest extends TestCase { file.close(); } + // Tests for the IndexOutOfBoundsException cases in read(). + + private void readIndexOutOfBoundsException(int offset, int count, String msg) + throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", testString.length); + try { + file.writeBytes(testString, 0, 0, testString.length); + InputStream is = file.getInputStream(); + byte[] buffer = new byte[testString.length + 10]; + try { + is.read(buffer, offset, count); + fail(msg); + } catch (IndexOutOfBoundsException ex) { + // this is what should happen + } finally { + is.close(); + } + } finally { + file.close(); + } + } + + @SmallTest + public void testReadNegativeOffset() throws Exception { + readIndexOutOfBoundsException(-1, 5, + "read() with negative offset should throw IndexOutOfBoundsException"); + } + + @SmallTest + public void testReadNegativeCount() throws Exception { + readIndexOutOfBoundsException(5, -1, + "read() with negative length should throw IndexOutOfBoundsException"); + } + + @SmallTest + public void testReadOffsetOverflow() throws Exception { + readIndexOutOfBoundsException(testString.length + 10, 5, + "read() with offset outside buffer should throw IndexOutOfBoundsException"); + } + + @SmallTest + public void testReadOffsetCountOverflow() throws Exception { + readIndexOutOfBoundsException(testString.length, 11, + "read() with offset + count outside buffer should throw IndexOutOfBoundsException"); + } + + // Test behavior of read() at end of file + @SmallTest + public void testReadEOF() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", testString.length); + try { + file.writeBytes(testString, 0, 0, testString.length); + InputStream is = file.getInputStream(); + try { + byte[] buffer = new byte[testString.length + 10]; + // read() with count larger than data should succeed, and return # of bytes read + assertEquals(testString.length, is.read(buffer)); + compareBuffers(testString, buffer, testString.length); + // Read at EOF should return -1 + assertEquals(-1, is.read()); + } finally { + is.close(); + } + } finally { + file.close(); + } + } + + // Tests that close() is idempotent + @SmallTest + public void testCloseClose() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", 1000000); + byte[] data = new byte[512]; + file.writeBytes(data, 0, 0, 128); + file.close(); + file.close(); + } + + // Tests that we can't read from a closed memory file + @SmallTest + public void testCloseRead() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", 1000000); + file.close(); + + try { + byte[] data = new byte[512]; + assertEquals(128, file.readBytes(data, 0, 0, 128)); + fail("readBytes() after close() did not throw IOException."); + } catch (IOException e) { + // this is what should happen + } + } + + // Tests that we can't write to a closed memory file + @SmallTest + public void testCloseWrite() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", 1000000); + file.close(); + + try { + byte[] data = new byte[512]; + file.writeBytes(data, 0, 0, 128); + fail("writeBytes() after close() did not throw IOException."); + } catch (IOException e) { + // this is what should happen + } + } + + // Tests that we can't call allowPurging() after close() + @SmallTest + public void testCloseAllowPurging() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", 1000000); + byte[] data = new byte[512]; + file.writeBytes(data, 0, 0, 128); + file.close(); + + try { + file.allowPurging(true); + fail("allowPurging() after close() did not throw IOException."); + } catch (IOException e) { + // this is what should happen + } + } + + // Tests that we don't leak file descriptors or mmap areas + @LargeTest + public void testCloseLeak() throws Exception { + // open enough memory files that we should run out of + // file descriptors or address space if we leak either. + for (int i = 0; i < 1025; i++) { + MemoryFile file = new MemoryFile("MemoryFileTest", 5000000); + file.writeBytes(testString, 0, 0, testString.length); + file.close(); + } + } + + @SmallTest + public void testIsMemoryFile() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", 1000000); + FileDescriptor fd = file.getFileDescriptor(); + assertNotNull(fd); + assertTrue(fd.valid()); + assertTrue(MemoryFile.isMemoryFile(fd)); + file.close(); + + assertFalse(MemoryFile.isMemoryFile(FileDescriptor.in)); + assertFalse(MemoryFile.isMemoryFile(FileDescriptor.out)); + assertFalse(MemoryFile.isMemoryFile(FileDescriptor.err)); + + File tempFile = File.createTempFile("MemoryFileTest",".tmp", getContext().getFilesDir()); + assertNotNull(file); + FileOutputStream out = null; + try { + out = new FileOutputStream(tempFile); + FileDescriptor fileFd = out.getFD(); + assertNotNull(fileFd); + assertFalse(MemoryFile.isMemoryFile(fileFd)); + } finally { + if (out != null) { + out.close(); + } + tempFile.delete(); + } + } + + @SmallTest + public void testFileDescriptor() throws Exception { + MemoryFile file = new MemoryFile("MemoryFileTest", 1000000); + MemoryFile ref = new MemoryFile(file.getFileDescriptor(), file.length(), "r"); + byte[] buffer; + + // write to original, read from reference + file.writeBytes(testString, 0, 2000, testString.length); + buffer = new byte[testString.length]; + ref.readBytes(buffer, 2000, 0, testString.length); + compareBuffers(testString, buffer, testString.length); + + file.close(); + ref.close(); // Doesn't actually do anything, since the file descriptor is not dup(2):ed + } + private static final byte[] testString = new byte[] { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5, 0, 2, 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9, 3, 7, 5, 1, 0, 5, 8, 2, 0, 9, 7, 4, 9, 4, 4, 5, 9, 2, 3, 0, 7, 8, 1, 6, 4, 0, 6, 2, 8, 6, 2, 0, 8, 9, 9, 8, 6, 2, 8, 0, 3, 4, 8, 2, 5, 3, 4, 2, 1, 1, 7, 0, 6, 7, 9, 8, 2, 1, 4, 8, 0, 8, 6, 5, 1, 3, 2, 8, 2, 3, 0, 6, 6, 4, 7, 0, 9, 3, 8, 4, 4, 6, 0, 9, 5, 5, 0, 5, 8, 2, 2, 3, 1, 7, 2, |