summaryrefslogtreecommitdiffstats
path: root/tests/src/com/android/providers/contacts/PhotoStoreTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/com/android/providers/contacts/PhotoStoreTest.java')
-rw-r--r--tests/src/com/android/providers/contacts/PhotoStoreTest.java198
1 files changed, 198 insertions, 0 deletions
diff --git a/tests/src/com/android/providers/contacts/PhotoStoreTest.java b/tests/src/com/android/providers/contacts/PhotoStoreTest.java
new file mode 100644
index 0000000..9b7c50d
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/PhotoStoreTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2011 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.providers.contacts;
+
+import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
+import com.android.providers.contacts.tests.R;
+
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.PhotoFiles;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.android.providers.contacts.ContactsActor.PACKAGE_GREY;
+
+/**
+ * Tests for {@link PhotoStore}.
+ */
+@LargeTest
+public class PhotoStoreTest extends PhotoLoadingTestCase {
+
+ private ContactsActor mActor;
+ private SynchronousContactsProvider2 mProvider;
+ private SQLiteDatabase mDb;
+
+ // The object under test.
+ private PhotoStore mPhotoStore;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActor = new ContactsActor(getContext(), PACKAGE_GREY, SynchronousContactsProvider2.class,
+ ContactsContract.AUTHORITY);
+ mProvider = ((SynchronousContactsProvider2) mActor.provider);
+ mPhotoStore = mProvider.getPhotoStore();
+ mProvider.wipeData();
+ mDb = mProvider.getDatabaseHelper(getContext()).getReadableDatabase();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ mPhotoStore.clear();
+ }
+
+ public void testStoreThumbnailPhoto() throws IOException {
+ byte[] photo = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL);
+
+ // Since the photo is already thumbnail-sized, no file will be stored.
+ assertEquals(0, mPhotoStore.insert(new PhotoProcessor(photo, 256, 96)));
+ }
+
+ public void testStoreMediumPhoto() throws IOException {
+ runStorageTestForResource(R.drawable.earth_normal);
+ }
+
+ public void testStoreLargePhoto() throws IOException {
+ runStorageTestForResource(R.drawable.earth_large);
+ }
+
+ public void testStoreHugePhoto() throws IOException {
+ runStorageTestForResource(R.drawable.earth_huge);
+ }
+
+ /**
+ * Runs the following steps:
+ * - Loads the given photo resource.
+ * - Inserts it into the photo store.
+ * - Checks that the photo has a photo file ID.
+ * - Loads the expected display photo for the resource.
+ * - Gets the photo entry from the photo store.
+ * - Loads the photo entry's file content from disk.
+ * - Compares the expected photo content to the disk content.
+ * - Queries the contacts provider for the photo file entry, checks for its
+ * existence, and matches it up against the expected metadata.
+ * - Checks that the total storage taken up by the photo store is equal to
+ * the size of the photo.
+ * @param resourceId The resource ID of the photo file to test.
+ */
+ public void runStorageTestForResource(int resourceId) throws IOException {
+ byte[] photo = loadPhotoFromResource(resourceId, PhotoSize.ORIGINAL);
+ long photoFileId = mPhotoStore.insert(new PhotoProcessor(photo, 256, 96));
+ assertTrue(photoFileId != 0);
+
+ byte[] expectedStoredVersion = loadPhotoFromResource(resourceId, PhotoSize.DISPLAY_PHOTO);
+ File storedFile = new File(mPhotoStore.get(photoFileId).path);
+ assertTrue(storedFile.exists());
+ byte[] storedVersion = readInputStreamFully(new FileInputStream(storedFile));
+ assertEquals(Hex.encodeHex(expectedStoredVersion, false),
+ Hex.encodeHex(storedVersion, false));
+
+ Cursor c = mDb.query(Tables.PHOTO_FILES,
+ new String[]{PhotoFiles.HEIGHT, PhotoFiles.WIDTH, PhotoFiles.FILESIZE},
+ PhotoFiles._ID + "=?", new String[]{String.valueOf(photoFileId)}, null, null, null);
+ try {
+ assertEquals(1, c.getCount());
+ c.moveToFirst();
+ assertEquals(256, c.getInt(0));
+ assertEquals(256, c.getInt(1));
+ assertEquals(expectedStoredVersion.length, c.getInt(2));
+ } finally {
+ c.close();
+ }
+
+ assertEquals(expectedStoredVersion.length, mPhotoStore.getTotalSize());
+ }
+
+ public void testRemoveEntry() throws IOException {
+ byte[] photo = loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL);
+ long photoFileId = mPhotoStore.insert(new PhotoProcessor(photo, 256, 96));
+ PhotoStore.Entry entry = mPhotoStore.get(photoFileId);
+ assertTrue(new File(entry.path).exists());
+
+ mPhotoStore.remove(photoFileId);
+
+ // Check that the file has been deleted.
+ assertFalse(new File(entry.path).exists());
+
+ // Check that the database record has also been removed.
+ Cursor c = mDb.query(Tables.PHOTO_FILES, new String[]{PhotoFiles._ID},
+ PhotoFiles._ID + "=?", new String[]{String.valueOf(photoFileId)}, null, null, null);
+ try {
+ assertEquals(0, c.getCount());
+ } finally {
+ c.close();
+ }
+ }
+
+ public void testCleanup() throws IOException {
+ // Load some photos into the store.
+ Set<Long> photoFileIds = new HashSet<Long>();
+ Map<Integer, Long> resourceIdToPhotoMap = new HashMap<Integer, Long>();
+ int[] resourceIds = new int[] {
+ R.drawable.earth_normal, R.drawable.earth_large, R.drawable.earth_huge
+ };
+ for (int resourceId : resourceIds) {
+ long photoFileId = mPhotoStore.insert(
+ new PhotoProcessor(loadPhotoFromResource(resourceId, PhotoSize.ORIGINAL),
+ 256, 96));
+ resourceIdToPhotoMap.put(resourceId, photoFileId);
+ photoFileIds.add(photoFileId);
+ }
+ assertFalse(photoFileIds.contains(0L));
+ assertEquals(3, photoFileIds.size());
+
+ // Run cleanup with the indication that only the large and huge photos are in use, along
+ // with a bogus photo file ID that isn't in the photo store.
+ long bogusPhotoFileId = 42;
+ Set<Long> photoFileIdsInUse = new HashSet<Long>();
+ photoFileIdsInUse.add(resourceIdToPhotoMap.get(R.drawable.earth_large));
+ photoFileIdsInUse.add(resourceIdToPhotoMap.get(R.drawable.earth_huge));
+ photoFileIdsInUse.add(bogusPhotoFileId);
+
+ Set<Long> photoIdsToCleanup = mPhotoStore.cleanup(photoFileIdsInUse);
+
+ // The set of photo IDs to clean up should consist of the bogus photo file ID.
+ assertEquals(1, photoIdsToCleanup.size());
+ assertTrue(photoIdsToCleanup.contains(bogusPhotoFileId));
+
+ // The entry for the normal-sized photo should have been cleaned up, since it isn't being
+ // used.
+ long normalPhotoId = resourceIdToPhotoMap.get(R.drawable.earth_normal);
+ assertNull(mPhotoStore.get(normalPhotoId));
+
+ // Check that the database record has also been removed.
+ Cursor c = mDb.query(Tables.PHOTO_FILES, new String[]{PhotoFiles._ID},
+ PhotoFiles._ID + "=?", new String[]{String.valueOf(normalPhotoId)},
+ null, null, null);
+ try {
+ assertEquals(0, c.getCount());
+ } finally {
+ c.close();
+ }
+ }
+}