Fix the tests so that they work with OpenJDK

Switches VogarArgsRule to use TestRule instead of the deprecated
MethodRule.

Adds target in Android.mk to build vogar tests with comment on
how to run them and makes test work when ANDROID_BUILD_TOP is
set as it will be when the tests are run from the command line.

Makes org.junit.Assert more consistent with standard JUnit class
so that the tests can be run from the command line.

Added AllAndroidTests suite.

Change-Id: I0a5084451a796992bc1d8ae2bdccf1159b84bedf
diff --git a/Android.mk b/Android.mk
index 5670bf4..0f1ae8a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -39,6 +39,32 @@
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
+# build vogar tests jar
+# ============================================================
+# Run the tests using the following command:
+# java -cp ${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/vogar-tests.jar \
+       org.junit.runner.JUnitCore vogar.AllTests
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := vogar-tests
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := $(call all-java-files-under, test/)
+
+# The order of libraries is important as there are overlapping classes.
+# vogar must come first so that it's custom implementation of JUnit classes
+# will be replaced by the standard ones.
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	vogar \
+	junit \
+	mockito-host \
+	objenesis-host
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
 # Build dependencies.
 # ============================================================
 include $(CLEAR_VARS)
diff --git a/src/org/junit/Assert.java b/src/org/junit/Assert.java
index 669a509..be8a08c 100644
--- a/src/org/junit/Assert.java
+++ b/src/org/junit/Assert.java
@@ -19,11 +19,183 @@
 //Note: this class was written without inspecting the junit code
 
 import java.util.Arrays;
+import junit.framework.AssertionFailedError;
 
-public class Assert extends junit.framework.Assert {
+public class Assert {
     protected Assert() {
     }
 
+    public static void assertEquals(String message, boolean expected, boolean actual) {
+        if (actual != expected) {
+            fail(message, "expected " + expected + " but was " + actual);
+        }
+    }
+
+    public static void assertEquals(boolean expected, boolean actual) {
+        assertEquals("", expected, actual);
+    }
+
+    public static void assertEquals(String message, byte expected, byte actual) {
+        if (actual != expected) {
+            fail(message, "expected " + expected + " but was " + actual);
+        }
+    }
+
+    public static void assertEquals(byte expected, byte actual) {
+        assertEquals("", expected, actual);
+    }
+
+    public static void assertEquals(String message, short expected, short actual) {
+        if (actual != expected) {
+            fail(message, "expected " + expected + " but was " + actual);
+        }
+    }
+
+    public static void assertEquals(short expected, short actual) {
+        assertEquals("", expected, actual);
+    }
+
+    public static void assertEquals(String message, long expected, long actual) {
+        if (actual != expected) {
+            fail(message, "expected " + expected + " but was " + actual);
+        }
+    }
+
+    public static void assertEquals(long expected, long actual) {
+        assertEquals("", expected, actual);
+    }
+
+    public static void assertEquals(String message, char expected, char actual) {
+        if (actual != expected) {
+            fail(message, "expected " + expected + " but was " + actual);
+        }
+    }
+
+    public static void assertEquals(char expected, char actual) {
+        assertEquals("", expected, actual);
+    }
+
+    public static void assertEquals(String message, Object expected, Object actual) {
+        if (expected == null && actual == null) {
+            return;
+        }
+        if (expected != null && expected.equals(actual)) {
+            return;
+        }
+        fail(message, "expected " + expected + " but was " + actual);
+    }
+
+    public static void assertEquals(Object expected, Object actual) {
+        assertEquals("", expected, actual);
+    }
+
+    // assertEquals with delta
+    static public void assertEquals(String message, double expected, double actual, double delta) {
+        if (Double.compare(expected, actual) == 0) {
+            return;
+        }
+        if (!(Math.abs(expected-actual) <= delta)) {
+            fail(message, "expected " + expected + " but was " + actual + "; delta=" + delta);
+        }
+    }
+
+    public static void assertEquals(double expected, double actual, double delta) {
+        assertEquals("", expected, actual, delta);
+    }
+
+    static public void assertEquals(String message, float expected, float actual, float delta) {
+        if (Float.compare(expected, actual) == 0) {
+            return;
+        }
+        if (!(Math.abs(expected - actual) <= delta)) {
+            fail(message, "expected " + expected + " but was " + actual + "; delta=" + delta);
+        }
+    }
+
+    public static void assertEquals(float expected, float actual, float delta) {
+        assertEquals("", expected, actual, delta);
+    }
+
+    // other asserts
+
+    public static void assertTrue(String message, boolean condition) {
+        if (!condition) {
+            throw new AssertionFailedError(message);
+        }
+    }
+
+    public static void assertTrue(boolean condition) {
+        assertTrue("", condition);
+    }
+
+    public static void assertFalse(String message, boolean condition) {
+        if (condition) {
+            throw new AssertionFailedError(message);
+        }
+    }
+
+    public static void assertFalse(boolean condition) {
+        assertFalse("", condition);
+    }
+
+    public static void assertNull(String message, Object reference) {
+        if (reference != null) {
+            throw new AssertionFailedError(message);
+        }
+    }
+
+    public static void assertNull(Object reference) {
+        assertNull("", reference);
+    }
+
+    public static void assertNotNull(String message, Object reference) {
+        if (reference == null) {
+            throw new AssertionFailedError(message);
+        }
+    }
+
+    public static void assertNotNull(Object reference) {
+        assertNotNull("", reference);
+    }
+
+    public static void assertSame(String message, Object expected, Object actual) {
+        if (expected != actual) {
+            fail(message, "expected same " + expected + ", " + actual);
+        }
+    }
+
+    public static void assertSame(Object expected, Object actual) {
+        assertSame("", expected, actual);
+    }
+
+    public static void assertNotSame(String message, Object expected, Object actual) {
+        if (expected == actual) {
+            fail(message, "expected not same " + expected + ", " + actual);
+        }
+    }
+
+    public static void assertNotSame(Object expected, Object actual) {
+        assertNotSame("", expected, actual);
+    }
+
+    // fail
+
+    public static void fail(String message) {
+        throw new AssertionFailedError(message);
+    }
+
+    public static void fail() {
+        throw new AssertionFailedError();
+    }
+
+    protected static void fail(String message, String detail) {
+        if (message == null || message.isEmpty()) {
+            throw new AssertionFailedError(detail);
+        } else {
+            throw new AssertionFailedError(message + ": " + detail);
+        }
+    }
+
     public static void assertArrayEquals(byte[] expecteds, byte[] actuals) {
         assertArrayEquals("", expecteds, actuals);
     }
diff --git a/test/vogar/AllTests.java b/test/vogar/AllTests.java
index 8827f1a..7452500 100644
--- a/test/vogar/AllTests.java
+++ b/test/vogar/AllTests.java
@@ -19,6 +19,7 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
+import vogar.android.AllAndroidTests;
 import vogar.android.DeviceRuntimeAdbTargetTest;
 import vogar.android.DeviceRuntimeSshTargetTest;
 import vogar.android.HostRuntimeLocalTargetTest;
@@ -34,9 +35,7 @@
  */
 @SuiteClasses({
         AssertTest.class,
-        DeviceRuntimeAdbTargetTest.class,
-        DeviceRuntimeSshTargetTest.class,
-        HostRuntimeLocalTargetTest.class,
+        AllAndroidTests.class,
         JUnitRunnerTest.class,
         ScriptBuilderEscapingTest.class,
         TestRunnerTest.class,
diff --git a/test/vogar/android/AllAndroidTests.java b/test/vogar/android/AllAndroidTests.java
new file mode 100644
index 0000000..5e55397
--- /dev/null
+++ b/test/vogar/android/AllAndroidTests.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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 vogar.android;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * Run the tests in this package.
+ */
+@SuiteClasses({
+        DeviceRuntimeAdbTargetTest.class,
+        DeviceRuntimeSshTargetTest.class,
+        HostRuntimeLocalTargetTest.class,
+})
+@RunWith(Suite.class)
+public class AllAndroidTests {
+}
diff --git a/test/vogar/android/HostRuntimeLocalTargetTest.java b/test/vogar/android/HostRuntimeLocalTargetTest.java
index 3556610..996b67e 100644
--- a/test/vogar/android/HostRuntimeLocalTargetTest.java
+++ b/test/vogar/android/HostRuntimeLocalTargetTest.java
@@ -16,9 +16,15 @@
 
 package vogar.android;
 
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
 import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.runners.MockitoJUnitRunner;
@@ -31,6 +37,7 @@
 import vogar.commands.VmCommandBuilder;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Test the behaviour of the {@link HostRuntime} class when run with {@link LocalTarget}.
@@ -38,6 +45,9 @@
 @RunWith(MockitoJUnitRunner.class)
 public class HostRuntimeLocalTargetTest extends AbstractModeTest {
 
+    public static final String ANDROID_BUILD_TOP_REFERENCE =
+            Matcher.quoteReplacement("${ANDROID_BUILD_TOP}/");
+
     @Override
     protected Target createTarget() {
         return new LocalTarget(console, mkdir, rm);
@@ -56,22 +66,26 @@
                 .args("-x", "a b");
         Command command = builder.build(run.target);
         List<String> args = command.getArgs();
+        args = replaceEnvironmentVariables(args);
+
         assertEquals(Arrays.asList(
                 "sh", "-c", ""
                         + "ANDROID_PRINTF_LOG=tag"
                         + " ANDROID_LOG_TAGS=*:i"
                         + " ANDROID_DATA=" + run.localFile("android-data")
-                        + " ANDROID_ROOT=out/host/linux-x86"
-                        + " LD_LIBRARY_PATH=out/host/linux-x86/lib"
-                        + " DYLD_LIBRARY_PATH=out/host/linux-x86/lib"
+                        + " ANDROID_ROOT=${ANDROID_BUILD_TOP}/out/host/linux-x86"
+                        + " LD_LIBRARY_PATH=${ANDROID_BUILD_TOP}/out/host/linux-x86/lib"
+                        + " DYLD_LIBRARY_PATH=${ANDROID_BUILD_TOP}/out/host/linux-x86/lib"
                         + " LD_USE_LOAD_BIAS=1"
-                        + " out/host/linux-x86/bin/dalvikvm32"
+                        + " ${ANDROID_BUILD_TOP}/out/host/linux-x86/bin/dalvikvm32"
                         + " -classpath classes"
                         + " -Xbootclasspath"
-                        + ":out/host/linux-x86/framework/core-libart-hostdex.jar"
-                        + ":out/host/linux-x86/framework/conscrypt-hostdex.jar"
-                        + ":out/host/linux-x86/framework/okhttp-hostdex.jar"
-                        + ":out/host/linux-x86/framework/bouncycastle-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/core-libart-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/core-oj-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/conscrypt-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/okhttp-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/bouncycastle-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/apache-xml-hostdex.jar"
                         + " -Duser.language=en"
                         + " -Duser.region=US"
                         + " -Xcheck:jni"
@@ -80,6 +94,20 @@
                         + " -x a\\ b"), args);
     }
 
+    public List<String> replaceEnvironmentVariables(List<String> args) {
+        String androidBuildTop = System.getenv("ANDROID_BUILD_TOP");
+        assertNotNull("ANDROID_BUILD_TOP not set", androidBuildTop);
+        Path path = Paths.get(androidBuildTop).normalize();
+        final String prefix = Pattern.quote(path.toString() + "/");
+        args = Lists.transform(args, new Function<String, String>() {
+            @Override
+            public String apply(String input) {
+                return input.replaceAll(prefix, ANDROID_BUILD_TOP_REFERENCE);
+            }
+        });
+        return args;
+    }
+
     @Test
     @VogarArgs({"--benchmark", "action"})
     public void testLocalTarget_Benchmark()
@@ -93,22 +121,26 @@
                 .args("-x", "a b");
         Command command = builder.build(run.target);
         List<String> args = command.getArgs();
+        args = replaceEnvironmentVariables(args);
+
         assertEquals(Arrays.asList(
                 "sh", "-c", ""
                         + "ANDROID_PRINTF_LOG=tag"
                         + " ANDROID_LOG_TAGS=*:i"
                         + " ANDROID_DATA=" + run.localFile("android-data")
-                        + " ANDROID_ROOT=out/host/linux-x86"
-                        + " LD_LIBRARY_PATH=out/host/linux-x86/lib"
-                        + " DYLD_LIBRARY_PATH=out/host/linux-x86/lib"
+                        + " ANDROID_ROOT=${ANDROID_BUILD_TOP}/out/host/linux-x86"
+                        + " LD_LIBRARY_PATH=${ANDROID_BUILD_TOP}/out/host/linux-x86/lib"
+                        + " DYLD_LIBRARY_PATH=${ANDROID_BUILD_TOP}/out/host/linux-x86/lib"
                         + " LD_USE_LOAD_BIAS=1"
-                        + " out/host/linux-x86/bin/dalvikvm32"
+                        + " ${ANDROID_BUILD_TOP}/out/host/linux-x86/bin/dalvikvm32"
                         + " -classpath classes"
                         + " -Xbootclasspath"
-                        + ":out/host/linux-x86/framework/core-libart-hostdex.jar"
-                        + ":out/host/linux-x86/framework/conscrypt-hostdex.jar"
-                        + ":out/host/linux-x86/framework/okhttp-hostdex.jar"
-                        + ":out/host/linux-x86/framework/bouncycastle-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/core-libart-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/core-oj-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/conscrypt-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/okhttp-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/bouncycastle-hostdex.jar"
+                        + ":${ANDROID_BUILD_TOP}/out/host/linux-x86/framework/apache-xml-hostdex.jar"
                         + " -Duser.language=en"
                         + " -Duser.region=US"
                         + " -Xjnigreflimit:2000"
diff --git a/test/vogar/android/VogarArgsRule.java b/test/vogar/android/VogarArgsRule.java
index cc765ec..4efaa0b 100644
--- a/test/vogar/android/VogarArgsRule.java
+++ b/test/vogar/android/VogarArgsRule.java
@@ -17,9 +17,9 @@
 package vogar.android;
 
 import junit.framework.AssertionFailedError;
-import org.junit.runners.model.FrameworkMethod;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
-import vogar.testing.UndeprecatedMethodRule;
 
 /**
  * Obtains test specific arguments from the {@link VogarArgs} annotation on the test and makes them
@@ -27,14 +27,13 @@
  *
  * @see VogarArgs
  */
-@SuppressWarnings("deprecation")
-public class VogarArgsRule implements UndeprecatedMethodRule {
+public class VogarArgsRule implements TestRule {
 
     private String[] testSpecificArgs = null;
 
     @Override
-    public Statement apply(Statement base, FrameworkMethod method, Object target) {
-        VogarArgs vogarArgs = method.getAnnotation(VogarArgs.class);
+    public Statement apply(Statement base, Description description) {
+        VogarArgs vogarArgs = description.getAnnotation(VogarArgs.class);
         if (vogarArgs == null) {
             throw new AssertionFailedError("Must specify @" + VogarArgs.class.getSimpleName());
         } else {