summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasu Nori <vnori@google.com>2010-08-04 13:31:48 -0700
committerVasu Nori <vnori@google.com>2010-08-04 13:34:34 -0700
commit0c9e14aa4aa1370e01872dc05238f822f2dd552c (patch)
tree881d1ab617e7b83a3b3d011755a1cb61bd3d414d
parent0d523e09bdc6373cba3c3c45ae84ffacfcfcf3b1 (diff)
downloadframeworks_base-0c9e14aa4aa1370e01872dc05238f822f2dd552c.zip
frameworks_base-0c9e14aa4aa1370e01872dc05238f822f2dd552c.tar.gz
frameworks_base-0c9e14aa4aa1370e01872dc05238f822f2dd552c.tar.bz2
add shutdown() to ContentProvider & call in ProviderTestCase*.tearDown
Change-Id: I3dd69b6907d68b7c1184139f22297ab92337f043
-rw-r--r--core/java/android/content/ContentProvider.java33
-rw-r--r--test-runner/src/android/test/ProviderTestCase.java12
-rw-r--r--test-runner/src/android/test/ProviderTestCase2.java12
3 files changed, 57 insertions, 0 deletions
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 9b9f796..a3252ed 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -32,6 +32,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.os.Process;
+import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
@@ -76,6 +77,8 @@ import java.util.ArrayList;
* cross-process calls.</p>
*/
public abstract class ContentProvider implements ComponentCallbacks {
+ private static final String TAG = "ContentProvider";
+
/*
* Note: if you add methods to ContentProvider, you must add similar methods to
* MockContentProvider.
@@ -831,4 +834,34 @@ public abstract class ContentProvider implements ComponentCallbacks {
public Bundle call(String method, String request, Bundle args) {
return null;
}
+
+ /**
+ * Shuts down this instance of the ContentProvider. It is useful when writing tests that use
+ * the ContentProvider.
+ * <p>
+ * If a unittest starts the ContentProvider in its test(..() methods, it could run into sqlite
+ * errors "disk I/O error" or "corruption" in the following scenario:
+ * <ul>
+ * <li>Say, there are 2 test methods in the unittest</li>
+ * <li>test1() (or setUp()) causes ContentProvider object to be initialized and
+ * assume it opens a database connection to "foo.db"</li>
+ * <li>est1() completes and test2() starts</li>
+ * <li>During the execution of test2() there will be 2 connections to "foo.db"</li>
+ * <li>Different threads in the ContentProvider may have one of these two connection
+ * handles. This is not a problem per se</li>
+ * <li>But if the two threads with 2 database connections don't interact correctly,
+ * there could be unexpected errors from sqlite</li>
+ * <li>Some of those unexpected errros are "disk I/O error" or "corruption" error</li>
+ * <li>Common practice in tearDown() is to delete test directory (and the database files)</li>
+ * <li>If this is done while some threads are still holding unclosed database connections,
+ * sqlite quite easily gets into corruption and disk I/O errors</li>
+ * </ul>
+ * <p>
+ * tearDown() in the unittests should call this method to have ContentProvider gracefully
+ * shutdown all database connections.
+ */
+ public void shutdown() {
+ Log.w(TAG, "implement ContentProvider shutdown() to make sure all database " +
+ "connections are gracefully shutdown");
+ }
}
diff --git a/test-runner/src/android/test/ProviderTestCase.java b/test-runner/src/android/test/ProviderTestCase.java
index e1172cf..1ffda26 100644
--- a/test-runner/src/android/test/ProviderTestCase.java
+++ b/test-runner/src/android/test/ProviderTestCase.java
@@ -73,6 +73,18 @@ public abstract class ProviderTestCase<T extends ContentProvider>
mResolver.addProvider(mProviderAuthority, getProvider());
}
+ /**
+ * Tears down the environment for the test fixture.
+ * <p>
+ * Calls {@link android.content.ContentProvider#shutdown()} on the
+ * {@link android.content.ContentProvider} represented by {@link #mProvider}
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ mProvider.shutdown();
+ super.tearDown();
+ }
+
public MockContentResolver getMockContentResolver() {
return mResolver;
}
diff --git a/test-runner/src/android/test/ProviderTestCase2.java b/test-runner/src/android/test/ProviderTestCase2.java
index 1fb5538..feb5ef4 100644
--- a/test-runner/src/android/test/ProviderTestCase2.java
+++ b/test-runner/src/android/test/ProviderTestCase2.java
@@ -141,6 +141,18 @@ public abstract class ProviderTestCase2<T extends ContentProvider> extends Andro
}
/**
+ * Tears down the environment for the test fixture.
+ * <p>
+ * Calls {@link android.content.ContentProvider#shutdown()} on the
+ * {@link android.content.ContentProvider} represented by {@link #mProvider}.
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ mProvider.shutdown();
+ super.tearDown();
+ }
+
+ /**
* Gets the {@link MockContentResolver} created by this class during initialization. You
* must use the methods of this resolver to access the provider under test.
*