Bug 903528 - Part 2: Land and build Fennec JUnit 3 tests. r=rnewman
authorNick Alexander <nalexander@mozilla.com>
Mon, 24 Feb 2014 18:24:46 -0800
changeset 170856 51c20dd62b11d9f1e10c501b101890af41a6f4c3
parent 170855 b57e246db50b3795ad6da671b711caf50720fa12
child 170857 9d6e281584dc6462a6f8e0df9a3952d45a54a666
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersrnewman
bugs903528
milestone30.0a1
Bug 903528 - Part 2: Land and build Fennec JUnit 3 tests. r=rnewman
mobile/android/tests/browser/junit3/AndroidManifest.xml.in
mobile/android/tests/browser/junit3/Makefile.in
mobile/android/tests/browser/junit3/moz.build
mobile/android/tests/browser/junit3/res/drawable-hdpi/icon.png
mobile/android/tests/browser/junit3/res/drawable-ldpi/icon.png
mobile/android/tests/browser/junit3/res/drawable-mdpi/icon.png
mobile/android/tests/browser/junit3/res/layout/main.xml
mobile/android/tests/browser/junit3/res/values/strings.xml
mobile/android/tests/browser/junit3/src/harness/BrowserInstrumentationTestRunner.java
mobile/android/tests/browser/junit3/src/harness/BrowserTestListener.java
mobile/android/tests/browser/junit3/src/tests/BrowserTestCase.java
mobile/android/tests/browser/junit3/src/tests/TestJarReader.java
mobile/android/tests/browser/moz.build
mobile/android/tests/moz.build
toolkit/mozapps/installer/packager.mk
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/AndroidManifest.xml.in
@@ -0,0 +1,26 @@
+#filter substitution
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="@ANDROID_BROWSER_TEST_PACKAGE_NAME@"
+    sharedUserId="@MOZ_ANDROID_SHARED_ID@"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk android:minSdkVersion="8"
+              android:targetSdkVersion="16" />
+
+    <uses-permission android:name="@ANDROID_BROWSER_TARGET_PACKAGE_NAME@.permissions.BROWSER_PROVIDER"/>
+    <uses-permission android:name="@ANDROID_BROWSER_TARGET_PACKAGE_NAME@.permissions.FORMHISTORY_PROVIDER"/>
+    <uses-permission android:name="@ANDROID_BROWSER_TARGET_PACKAGE_NAME@.permissions.PASSWORD_PROVIDER"/>
+
+    <application
+        android:icon="@drawable/icon"
+        android:label="@ANDROID_BROWSER_APP_DISPLAYNAME@">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:label="@string/app_name"
+        android:name="org.mozilla.browser.harness.BrowserInstrumentationTestRunner"
+        android:targetPackage="@ANDROID_BROWSER_TARGET_PACKAGE_NAME@" />
+</manifest>
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/Makefile.in
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ANDROID_APK_NAME := browser-junit3-debug
+
+ANDROID_EXTRA_JARS += \
+	browser-junit3.jar \
+  $(NULL)
+
+PP_TARGETS += manifest
+manifest := AndroidManifest.xml.in
+manifest_FLAGS += \
+  -DANDROID_BROWSER_TARGET_PACKAGE_NAME='$(ANDROID_PACKAGE_NAME)' \
+  -DANDROID_BROWSER_TEST_PACKAGE_NAME='org.mozilla.gecko.browser.tests' \
+  -DANDROID_BROWSER_APP_DISPLAYNAME='$(MOZ_APP_DISPLAYNAME) Browser Tests' \
+  -DMOZ_ANDROID_SHARED_ID='$(ANDROID_PACKAGE_NAME).sharedID' \
+  $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+tools:: $(ANDROID_APK_NAME).apk
+
+# The test APK needs to know the contents of the target APK while not
+# being linked against them.  This is a best effort to avoid getting
+# out of sync with base's build config.
+JARS_DIR := $(DEPTH)/mobile/android/base
+JAVA_BOOTCLASSPATH := $(JAVA_BOOTCLASSPATH):$(subst $(NULL) ,:,$(wildcard $(JARS_DIR)/*.jar))
+# We also want to re-compile classes.dex when the associated base
+# content changes.
+classes.dex: $(wildcard $(JARS_DIR)/*.jar)
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEFINES['ANDROID_PACKAGE_NAME'] = CONFIG['ANDROID_PACKAGE_NAME']
+
+jar = add_java_jar('browser-junit3')
+jar.sources += [
+    'src/harness/BrowserInstrumentationTestRunner.java',
+    'src/harness/BrowserTestListener.java',
+    'src/tests/BrowserTestCase.java',
+    'src/tests/TestJarReader.java',
+]
+jar.generated_sources = [] # None yet -- try to keep it this way.
+jar.javac_flags += ['-Xlint:all,-unchecked']
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5c6a89f801c19b84469c7a609fca180c07e8bd41
GIT binary patch
literal 7834
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
MWuRHEZWHnU0FzMS2mk;8
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7e383f14932ff0635f6bcf0807a2ce97c6a49c41
GIT binary patch
literal 3279
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f2d917b905cb81ca29a8d528b4f0c33823332623
GIT binary patch
literal 4738
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
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/res/layout/main.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/app_name" />
+
+</LinearLayout>
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/res/values/strings.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">Gecko Browser Tests</string>
+
+</resources>
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/src/harness/BrowserInstrumentationTestRunner.java
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.browser.harness;
+
+import android.os.Bundle;
+import android.test.AndroidTestRunner;
+import android.test.InstrumentationTestRunner;
+import android.util.Log;
+
+/**
+ * A test runner that installs a special test listener.
+ * <p>
+ * In future, this listener will turn JUnit 3 test events into log messages in
+ * the format that Mochitest parsers understand.
+ */
+public class BrowserInstrumentationTestRunner extends InstrumentationTestRunner {
+    private static final String LOG_TAG = "BInstTestRunner";
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        Log.d(LOG_TAG, "onCreate");
+        super.onCreate(arguments);
+    }
+
+    @Override
+    protected AndroidTestRunner getAndroidTestRunner() {
+        Log.d(LOG_TAG, "getAndroidTestRunner");
+        AndroidTestRunner testRunner = super.getAndroidTestRunner();
+        testRunner.addTestListener(new BrowserTestListener());
+        return testRunner;
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/src/harness/BrowserTestListener.java
@@ -0,0 +1,42 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.browser.harness;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import android.util.Log;
+
+/**
+ * BrowserTestListener turns JUnit 3 test events into log messages in the format
+ * that Mochitest parsers understand.
+ * <p>
+ * The idea is that, on infrastructure, we'll be able to use the same test
+ * parsing code for Browser JUnit 3 tests as we do for Robocop tests.
+ * <p>
+ * In future, that is!
+ */
+public class BrowserTestListener implements TestListener {
+    public static final String LOG_TAG = "BTestListener";
+
+    @Override
+    public void startTest(Test test) {
+        Log.d(LOG_TAG, "startTest: " + test);
+    }
+
+    @Override
+    public void endTest(Test test) {
+        Log.d(LOG_TAG, "endTest: " + test);
+    }
+
+    @Override
+    public void addFailure(Test test, AssertionFailedError t) {
+        Log.d(LOG_TAG, "addFailure: " + test);
+    }
+
+    @Override
+    public void addError(Test test, Throwable t) {
+        Log.d(LOG_TAG, "addError: " + test);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/src/tests/BrowserTestCase.java
@@ -0,0 +1,37 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.browser.tests;
+
+import org.mozilla.gecko.AppConstants;
+
+import android.app.Activity;
+import android.content.Context;
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * BrowserTestCase provides helper methods for testing.
+ */
+public class BrowserTestCase extends ActivityInstrumentationTestCase2<Activity> {
+    private static String LOG_TAG = "BrowserTestCase";
+
+    private static final String LAUNCHER_ACTIVITY = AppConstants.ANDROID_PACKAGE_NAME + ".App";
+
+    private final static Class<Activity> sLauncherActivityClass;
+
+    static {
+        try {
+            sLauncherActivityClass = (Class<Activity>) Class.forName(LAUNCHER_ACTIVITY);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public BrowserTestCase() {
+        super(sLauncherActivityClass);
+    }
+
+    public Context getApplicationContext() {
+        return this.getInstrumentation().getTargetContext().getApplicationContext();
+    }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/tests/browser/junit3/src/tests/TestJarReader.java
@@ -0,0 +1,45 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+package org.mozilla.gecko.browser.tests;
+
+import java.io.InputStream;
+
+import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.util.GeckoJarReader;
+
+/**
+ * A basic jar reader test. Tests reading a png from fennec's apk, as well as
+ * loading some invalid jar urls.
+ */
+public class TestJarReader extends BrowserTestCase {
+    public void testJarReader() {
+        String appPath = getActivity().getApplication().getPackageResourcePath();
+        assertNotNull(appPath);
+
+        // Test reading a file from a jar url that looks correct.
+        String url = "jar:file://" + appPath + "!/" + AppConstants.OMNIJAR_NAME;
+        InputStream stream = GeckoJarReader.getStream("jar:" + url + "!/chrome/chrome/content/branding/favicon32.png");
+        assertNotNull(stream);
+
+        // Test looking for an non-existent file in a jar.
+        url = "jar:file://" + appPath + "!/" + AppConstants.OMNIJAR_NAME;
+        stream = GeckoJarReader.getStream("jar:" + url + "!/chrome/chrome/content/branding/nonexistent_file.png");
+        assertNull(stream);
+
+        // Test looking for a file that doesn't exist in the APK.
+        url = "jar:file://" + appPath + "!/" + "BAD" + AppConstants.OMNIJAR_NAME;
+        stream = GeckoJarReader.getStream("jar:" + url + "!/chrome/chrome/content/branding/favicon32.png");
+        assertNull(stream);
+
+        // Test looking for an jar with an invalid url.
+        url = "jar:file://" + appPath + "!" + "!/" + AppConstants.OMNIJAR_NAME;
+        stream = GeckoJarReader.getStream("jar:" + url + "!/chrome/chrome/content/branding/nonexistent_file.png");
+        assertNull(stream);
+
+        // Test looking for a file that doesn't exist on disk.
+        url = "jar:file://" + appPath + "BAD" + "!/" + AppConstants.OMNIJAR_NAME;
+        stream = GeckoJarReader.getStream("jar:" + url + "!/chrome/chrome/content/branding/favicon32.png");
+        assertNull(stream);
+    }
+}
copy from mobile/android/tests/moz.build
copy to mobile/android/tests/browser/moz.build
--- a/mobile/android/tests/moz.build
+++ b/mobile/android/tests/browser/moz.build
@@ -1,9 +1,9 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 TEST_DIRS += [
-    'background',
+    'junit3',
 ]
--- a/mobile/android/tests/moz.build
+++ b/mobile/android/tests/moz.build
@@ -1,9 +1,10 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 TEST_DIRS += [
     'background',
+    'browser',
 ]
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -376,20 +376,25 @@ ROBOCOP_PATH = $(abspath $(_ABS_DIST)/..
 # $(NSINSTALL) is relative.
 INNER_ROBOCOP_PACKAGE= \
   cp $(GECKO_APP_AP_PATH)/fennec_ids.txt $(_ABS_DIST) && \
   $(call RELEASE_SIGN_ANDROID_APK,$(ROBOCOP_PATH)/robocop-debug-unsigned-unaligned.apk,$(_ABS_DIST)/robocop.apk)
 
 BACKGROUND_TESTS_PATH = $(abspath $(_ABS_DIST)/../mobile/android/tests/background/junit3)
 INNER_BACKGROUND_TESTS_PACKAGE= \
   $(call RELEASE_SIGN_ANDROID_APK,$(BACKGROUND_TESTS_PATH)/background-junit3-debug-unsigned-unaligned.apk,$(_ABS_DIST)/background-junit3.apk)
+
+BROWSER_TESTS_PATH = $(abspath $(_ABS_DIST)/../mobile/android/tests/browser/junit3)
+INNER_BROWSER_TESTS_PACKAGE= \
+  $(call RELEASE_SIGN_ANDROID_APK,$(BROWSER_TESTS_PATH)/browser-junit3-debug-unsigned-unaligned.apk,$(_ABS_DIST)/browser-junit3.apk)
 endif
 else
 INNER_ROBOCOP_PACKAGE=echo 'Testing is disabled - No Android Robocop for you'
 INNER_BACKGROUND_TESTS_PACKAGE=echo 'Testing is disabled - No Android Background JUnit 3 tests for you'
+INNER_BROWSER_TESTS_PACKAGE=echo 'Testing is disabled - No Android Browser JUnit 3tests for you'
 endif
 
 # Create geckoview_library/geckoview_{assets,library}.zip for third-party GeckoView consumers.
 ifdef NIGHTLY_BUILD
 ifndef MOZ_DISABLE_GECKOVIEW
 INNER_MAKE_GECKOVIEW_LIBRARY= \
   $(MAKE) -C ../mobile/android/geckoview_library package
 else
@@ -472,16 +477,17 @@ INNER_MAKE_PACKAGE	= \
   rm -f $(_ABS_DIST)/gecko.apk && \
   cp $(_ABS_DIST)/gecko.ap_ $(_ABS_DIST)/gecko.apk && \
   $(ZIP) -j0 $(_ABS_DIST)/gecko.apk $(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/classes.dex && \
   cp $(_ABS_DIST)/gecko.apk $(_ABS_DIST)/gecko-unsigned-unaligned.apk && \
   $(RELEASE_JARSIGNER) $(_ABS_DIST)/gecko.apk && \
   $(ZIPALIGN) -f -v 4 $(_ABS_DIST)/gecko.apk $(PACKAGE) && \
   $(INNER_ROBOCOP_PACKAGE) && \
   $(INNER_BACKGROUND_TESTS_PACKAGE) && \
+  $(INNER_BROWSER_TESTS_PACKAGE) && \
   $(INNER_MAKE_GECKOVIEW_LIBRARY)
 
 # Language repacks root the resources contained in assets/omni.ja
 # under assets/, but the repacks expect them to be rooted at /.
 # Therefore, we we move the omnijar back to / so the resources are
 # under the root here, in INNER_UNMAKE_PACKAGE. See comments about
 # OMNIJAR_NAME earlier in this file and in configure.in.