Update provider for EMMA from CTS
The provider now accepts a "secret" request to dump EMMA coverage
data.
The commands in tests/EMMA_README were updated for the new world
order, in which the tests live in CTS rather than being one with
the provider itself. This also converts the commands from direct
execution to a shell function, and adds a second function that can
be used to de-EMMA the provider.
Bug 2361048
Change-Id: I38b494cc65a15523207f95d2e622756cc393b665
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java
index 3fb4ef7..2cdfee4 100644
--- a/src/com/android/providers/calendar/CalendarProvider2.java
+++ b/src/com/android/providers/calendar/CalendarProvider2.java
@@ -61,7 +61,9 @@
import android.util.TimeFormatException;
import android.util.TimeUtils;
+import java.io.File;
import java.lang.reflect.Array;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -2149,6 +2151,10 @@
}
id = mDbHelper.extendedPropertiesInsert(values);
break;
+ case EMMA:
+ // Special target used during code-coverage evaluation.
+ handleEmmaRequest(values);
+ break;
case EVENTS_ID:
case REMINDERS_ID:
case CALENDAR_ALERTS_ID:
@@ -2170,6 +2176,44 @@
}
/**
+ * Handles special commands related to EMMA code-coverage testing.
+ *
+ * @param values Parameters from the caller.
+ */
+ private static void handleEmmaRequest(ContentValues values) {
+ /*
+ * This is not part of the public API, so we can't share constants with the CTS
+ * test code.
+ *
+ * Bad requests, or attempting to request EMMA coverage data when the coverage libs
+ * aren't linked in, will cause an exception.
+ */
+ String cmd = values.getAsString("cmd");
+ if (cmd.equals("start")) {
+ // We'd like to reset the coverage data, but according to FAQ item 3.14 at
+ // http://emma.sourceforge.net/faq.html, this isn't possible in 2.0.
+ Log.d(TAG, "Emma coverage testing started");
+ } else if (cmd.equals("stop")) {
+ // Call com.vladium.emma.rt.RT.dumpCoverageData() to cause a data dump. We
+ // may not have been built with EMMA, so we need to do this through reflection.
+ String filename = values.getAsString("outputFileName");
+
+ File coverageFile = new File(filename);
+ try {
+ Class<?> emmaRTClass = Class.forName("com.vladium.emma.rt.RT");
+ Method dumpCoverageMethod = emmaRTClass.getMethod("dumpCoverageData",
+ coverageFile.getClass(), boolean.class, boolean.class);
+
+ dumpCoverageMethod.invoke(null, coverageFile, false /*merge*/,
+ false /*stopDataCollection*/);
+ Log.d(TAG, "Emma coverage data written to " + filename);
+ } catch (Exception e) {
+ throw new RuntimeException("Emma coverage dump failed", e);
+ }
+ }
+ }
+
+ /**
* Validates the recurrence rule, if any. We allow single- and multi-rule RRULEs.
* <p>
* TODO: Validate RDATE, EXRULE, EXDATE (possibly passing in an indication of whether we
@@ -3898,6 +3942,7 @@
private static final int PROVIDER_PROPERTIES = 28;
private static final int EXCEPTION_ID = 29;
private static final int EXCEPTION_ID2 = 30;
+ private static final int EMMA = 31;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final HashMap<String, String> sInstancesProjectionMap;
@@ -3946,6 +3991,7 @@
sUriMatcher.addURI(CalendarContract.AUTHORITY, "properties", PROVIDER_PROPERTIES);
sUriMatcher.addURI(CalendarContract.AUTHORITY, "exception/#", EXCEPTION_ID);
sUriMatcher.addURI(CalendarContract.AUTHORITY, "exception/#/#", EXCEPTION_ID2);
+ sUriMatcher.addURI(CalendarContract.AUTHORITY, "emma", EMMA);
/** Contains just BaseColumns._COUNT */
sCountProjectionMap = new HashMap<String, String>();
diff --git a/tests/EMMA_README b/tests/EMMA_README
index 1a2a35d..d3f4e89 100644
--- a/tests/EMMA_README
+++ b/tests/EMMA_README
@@ -1,27 +1,93 @@
-#TODO Modify when we move CTS tests to frameworks
+# This defines a shell function called run_emma_calp() that rebuilds
+# the Calendar provider with EMMA coverage, executes the Calendar CTS
+# tests, and generates results into ~/emmaReport/. The previous emmaReport
+# directory, if any, will be removed.
+#
+# This expects that ". build/envsetup.sh" and an appropriate "lunch"
+# command have already been issued.
+#
+# Also, since we're doing this "the hard way", it's necessary to have
+# /system/framework/emma.jar in BOOTCLASSPATH. Basic steps:
+# - edit system/core/rootdir/init.rc
+# - insert "/system/framework/emma.jar" right before framework.jar
+# - mm -j8 external/emma
+# - make -j8
+# - adb reboot-bootloader
+# - fastboot flashall
+#
+# This also defines a no_emma_calp() function that rebuilds the provider
+# without emma.
+#
+# NOTE: interrupting execution may leave you in a different directory
-#These are instructions for generating code coverage for the provider
-#for only the CalendarCts.java set of tests. This file can be sourced
-#directly from the command line to generate the coverage results in
-#your home directory.
+function run_emma_calp()
+{
+ # rebuild provider with emma coverage
+ _build_install_calp true
+ if [ $? -ne 0 ]; then
+ echo Build failed.
+ return 1
+ fi
-adb root;
-cd ${ANDROID_BUILD_TOP}/packages/providers/CalendarProvider;
-export EMMA_INSTRUMENT=true;
-rm -R ${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/CalendarProvider_intermediates
-rm -R ${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/CalendarProviderTests_intermediates
-mm;
-adb remount;
-adb push ${ANDROID_PRODUCT_OUT}/system/app/CalendarProvider.apk system/app/CalendarProvider.apk;
-adb push ${ANDROID_PRODUCT_OUT}/data/app/CalendarProviderTests.apk data/app/CalendarProviderTests.apk;
-sleep 2;
-adb shell am instrument -w -e coverage true -e class com.android.providers.calendar.CalendarCts com.android.providers.calendar.tests/android.test.InstrumentationTestRunner;
-if [ -d ~/emmaReport ]; then
- rm -R ~/emmaReport;
-fi
-mkdir ~/emmaReport;
-pushd ~/emmaReport;
-adb pull /data/user/0/com.android.providers.calendar/files/coverage.ec coverage.ec;
-java -cp ${ANDROID_BUILD_TOP}/external/emma/lib/emma.jar emma report -r html -in coverage.ec -sp ${ANDROID_BUILD_TOP}/packages/providers/CalendarProvider/src -in ${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/CalendarProvider_intermediates/coverage.em;
-popd;
-export EMMA_INSTRUMENT=false;
+ # run the CTS tests; note we can't get success/failure result in $?
+ adb shell am instrument -w -e coverage true \
+ -e class android.provider.cts.CalendarTest \
+ -w 'com.android.cts.provider/android.provider.cts.CalendarTest\$CalendarEmmaTestRunner'
+
+ # this path is hard-coded into the CalendarEmmaTestRunner
+ output=/sdcard/calendar-provider.ec
+
+ # extract and generate the report
+ rm -rf ~/emmaReport
+ mkdir ~/emmaReport
+ pushd ~/emmaReport
+ adb pull $output coverage.ec
+ adb shell rm $output
+ java -cp ${ANDROID_BUILD_TOP}/external/emma/lib/emma.jar \
+ emma report -r html -in coverage.ec \
+ -sp ${ANDROID_BUILD_TOP}/packages/providers/CalendarProvider/src \
+ -in ${ANDROID_BUILD_TOP}/out/target/common/obj/APPS/CalendarProvider_intermediates/coverage.em
+ popd
+
+ echo "Report is in $HOME/emmaReport"
+
+ return 0
+}
+
+function no_emma_calp()
+{
+ # rebuild provider without emma coverage
+ _build_install_calp false
+}
+
+function _build_install_calp()
+{
+ emma=$1
+
+ # switch to root on userdebug builds - this may take a second to finish
+ adb root
+
+ pushd $ANDROID_BUILD_TOP
+
+ # force rebuild
+ rm -rf out/target/common/obj/APPS/CalendarProvider_intermediates
+ ##rm -rf out/target/common/obj/APPS/CalendarProviderTests_intermediates
+ rm -rf out/target/common/obj/APPS/CtsProviderTestCases_intermediates
+ EMMA_INSTRUMENT=$emma mmm -j4 packages/providers/CalendarProvider \
+ && EMMA_INSTRUMENT=$emma mmm -j4 cts/tests/tests/provider
+ if [ $? -ne 0 ]; then
+ popd
+ return 1
+ fi
+
+ # copy the instrumented APKs to the device
+ adb remount
+ adb push ${ANDROID_PRODUCT_OUT}/system/app/CalendarProvider.apk /system/app/
+ ##adb push ${ANDROID_PRODUCT_OUT}/data/app/CalendarProviderTests.apk /data/app/
+ adb push ${ANDROID_PRODUCT_OUT}/data/app/CtsProviderTestCases.apk /data/app/
+ popd
+
+ # give the device a couple of seconds to install the packages
+ sleep 2
+}
+