add new test class for JUnit tests on device.
Bug: 8538755

(cherry picked from commit 0228105151e8940bbee795604d1355f91a9172fe)

Change-Id: I73ac883c07e3b55e7c9d54ce070d02557bcc5b8f
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
index 516d4ba..7e14f97 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -40,5 +40,5 @@
 						-n $(PRIVATE_LIBRARY) \
 						-p $(PRIVATE_TEST_PACKAGE) \
 						-e $(CTS_EXPECTATIONS) \
-						-x "runtime_args->$(PRIVATE_RUNTIME_ARGS)" \
+						-x "runtimeArgs->$(PRIVATE_RUNTIME_ARGS)" \
 						-o $@
diff --git a/tools/junit/Android.mk b/tools/junit/Android.mk
new file mode 100644
index 0000000..b581149
--- /dev/null
+++ b/tools/junit/Android.mk
@@ -0,0 +1,23 @@
+# Copyright (C) 2014 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES :=  $(call all-java-files-under, src)
+LOCAL_MODULE := cts-junit
+LOCAL_MODULE_TAGS := optional
+LOCAL_STATIC_JAVA_LIBRARIES := junit4-target
+LOCAL_DEX_PREOPT := false
+include $(BUILD_JAVA_LIBRARY)
diff --git a/tools/junit/src/com/android/cts/junit/SingleJUnitTestRunListener.java b/tools/junit/src/com/android/cts/junit/SingleJUnitTestRunListener.java
new file mode 100644
index 0000000..06e9bc46
--- /dev/null
+++ b/tools/junit/src/com/android/cts/junit/SingleJUnitTestRunListener.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 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.cts.junit;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class SingleJUnitTestRunListener extends RunListener {
+    private static class Prefixes {
+        @SuppressWarnings("unused")
+        private static final String INFORMATIONAL_MARKER = "[----------]";
+        private static final String START_TEST_RUN_MARKER = "[==========] Running";
+        private static final String TEST_RUN_MARKER = "[==========]";
+        private static final String START_TEST_MARKER = "[ RUN      ]";
+        private static final String OK_TEST_MARKER = "[       OK ]";
+        private static final String FAILED_TEST_MARKER = "[  FAILED  ]";
+    }
+
+    @Override
+    public void testRunStarted(Description description) throws Exception {
+    }
+
+    @Override
+    public void testRunFinished(Result result) throws Exception {
+        String status = result.wasSuccessful() ? Prefixes.OK_TEST_MARKER
+                : Prefixes.FAILED_TEST_MARKER;
+        System.out.println(status);
+    }
+
+    @Override
+    public void testStarted(Description description) throws Exception {
+        System.out.println(String.format("%s %s.%s", Prefixes.START_TEST_MARKER,
+                description.getClassName(), description.getMethodName()));
+    }
+
+    @Override
+    public void testFinished(Description description) throws Exception {
+    }
+
+    @Override
+    public void testFailure(Failure failure) throws Exception {
+    }
+
+    @Override
+    public void testAssumptionFailure(Failure failure) {
+    }
+
+    @Override
+    public void testIgnored(Description description) throws Exception {
+    }
+}
diff --git a/tools/junit/src/com/android/cts/junit/SingleJUnitTestRunner.java b/tools/junit/src/com/android/cts/junit/SingleJUnitTestRunner.java
new file mode 100644
index 0000000..2eb9f3a
--- /dev/null
+++ b/tools/junit/src/com/android/cts/junit/SingleJUnitTestRunner.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 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.cts.junit;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+
+/**
+ * Test runner to run a single JUnit test. It will output either [PASSED] or [FAILED] at the end.
+ */
+public class SingleJUnitTestRunner {
+    private static String mUsage = "Usage: java -cp <classpath> SingleJUnitTestRunner" +
+            " class#testmethod";
+    private static final String PASSED_TEST_MARKER = "[ PASSED ]";
+    private static final String FAILED_TEST_MARKER = "[ FAILED ]";
+
+    public static void main(String... args) throws ClassNotFoundException {
+        if (args.length != 1) {
+            throw new IllegalArgumentException(mUsage);
+        }
+        String[] classAndMethod = args[0].split("#");
+        if (classAndMethod.length != 2) {
+            throw new IllegalArgumentException(mUsage);
+        }
+        Request request = Request.method(Class.forName(classAndMethod[0]),
+                classAndMethod[1]);
+        JUnitCore jUnitCore = new JUnitCore();
+        Result result = jUnitCore.run(request);
+        String status = result.wasSuccessful() ? PASSED_TEST_MARKER : FAILED_TEST_MARKER;
+        System.out.println(String.format("%s %s.%s", status,
+                classAndMethod[0], classAndMethod[1]));
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JUnitDeviceTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JUnitDeviceTest.java
new file mode 100644
index 0000000..4adcb0b
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JUnitDeviceTest.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 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.cts.tradefed.testtype;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.util.AbiFormatter;
+import com.android.tradefed.util.ArrayUtil;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * {@link Test} for running CTS JUnit tests on the device.
+ */
+public class JUnitDeviceTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
+
+    private static final String TMP_DIR = "/data/local/tmp/";
+
+    @Option(name = AbiFormatter.FORCE_ABI_STRING, description = AbiFormatter.FORCE_ABI_DESCRIPTION,
+            importance = Importance.IF_UNSET)
+    private String mForceAbi = null;
+
+    @Option(name = "junit-device-runtime",
+            description = "The name of the runtime to use on the device",
+            importance = Importance.ALWAYS)
+    private String mRuntimePath = "dalvikvm|#ABI#|";
+
+    @Option(name = "junit-device-tmpdir", description = "Device path where to store the test jars."
+            , importance = Importance.IF_UNSET)
+    private String mDeviceTestTmpPath = TMP_DIR;
+
+
+
+    // default to no timeout
+    private long mMaxTimeToOutputResponse = 0;
+
+    private ITestDevice mDevice;
+    private String mRunName;
+    private Collection<TestIdentifier> mTests;
+    private CtsBuildHelper mCtsBuild = null;
+
+    private List<String> mJarPaths = new ArrayList<String>();
+
+    private String mRuntimeArgs;
+
+
+
+    private static final String JUNIT_JAR = "cts-junit.jar";
+
+    private Set<String> mTestJars = new HashSet<String>(Arrays.asList(JUNIT_JAR));
+
+    @Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+
+    @Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    public void addTestJarFileName(String jarFileName) {
+        mTestJars.add(jarFileName);
+    }
+
+    public void setRunName(String runName) {
+        mRunName = runName;
+    }
+
+    public void setTests(Collection<TestIdentifier> tests) {
+        mTests = tests;
+    }
+
+    public Collection<TestIdentifier> getTests() {
+        return mTests;
+    }
+
+    @Override
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        addTestJarFileName(JUNIT_JAR);
+        checkFields();
+        long startTime = System.currentTimeMillis();
+        listener.testRunStarted(mRunName, mTests.size());
+        try {
+            installJars();
+            String jarPath = ArrayUtil.join(":", mJarPaths);
+            for (TestIdentifier testId : mTests) {
+                SingleJUnitTestResultParser resultParser = new SingleJUnitTestResultParser(
+                        testId, listener);
+                String cmdLine = String.format("ANDROID_DATA=%s %s -cp %s %s " +
+                        "com.android.cts.junit.SingleJUnitTestRunner %s#%s",
+                        mDeviceTestTmpPath, mRuntimePath, jarPath, mRuntimeArgs,
+                        testId.getClassName(), testId.getTestName());
+                String cmd = AbiFormatter.formatCmdForAbi(cmdLine, mForceAbi);
+                CLog.d("Running %s", cmd);
+                listener.testStarted(testId);
+                mDevice.executeShellCommand(cmd, resultParser, mMaxTimeToOutputResponse,
+                        TimeUnit.MILLISECONDS, 0);
+            }
+        } finally {
+            listener.testRunEnded(System.currentTimeMillis() - startTime,
+                    Collections.<String, String> emptyMap());
+            // Remove jar files from device
+            removeJars();
+        }
+    }
+
+    /**
+     * Installs the jar files on the device under test.
+     *
+     * @throws DeviceNotAvailableException
+     */
+    protected void installJars() throws DeviceNotAvailableException {
+        for (String f : mTestJars) {
+            CLog.d("Installing %s on %s", f, getDevice().getSerialNumber());
+            File jarFile;
+            try {
+                String fullJarPath = String.format("%s%s", mDeviceTestTmpPath, f);
+                jarFile = mCtsBuild.getTestApp(f);
+                boolean result = getDevice().pushFile(jarFile, fullJarPath);
+                Assert.assertTrue(String.format("Failed to push file to %s", fullJarPath), result);
+                mJarPaths.add(fullJarPath);
+            } catch (FileNotFoundException e) {
+                Assert.fail(String.format("Could not find file %s", f));
+            }
+        }
+    }
+
+    /**
+     * Cleans up the jar files from the device under test.
+     *
+     * @throws DeviceNotAvailableException
+     */
+    protected void removeJars() throws DeviceNotAvailableException {
+        for (String f : mTestJars) {
+            String fullJarPath = String.format("%s%s", mDeviceTestTmpPath, f);
+            CLog.d("Uninstalling %s on %s", fullJarPath, getDevice().getSerialNumber());
+            getDevice().executeShellCommand(String.format("rm %s", fullJarPath));
+        }
+    }
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    /**
+     * Checks that all mandatory member fields has been set.
+     */
+    protected void checkFields() {
+        if (mRunName == null) {
+            throw new IllegalArgumentException("run name has not been set");
+        }
+        if (mDevice == null) {
+            throw new IllegalArgumentException("Device has not been set");
+        }
+        if (mTestJars.isEmpty()) {
+            throw new IllegalArgumentException("No test jar has been set");
+        }
+        if (mTests == null) {
+            throw new IllegalArgumentException("tests has not been set");
+        }
+        if (mCtsBuild == null) {
+            throw new IllegalArgumentException("build has not been set");
+        }
+        for (String f : mTestJars) {
+            try {
+
+                mCtsBuild.getTestApp(f);
+            } catch (FileNotFoundException e) {
+                throw new IllegalArgumentException(String.format(
+                        "Could not find jar %s in CTS build %s", f,
+                        mCtsBuild.getRootDir().getAbsolutePath()));
+            }
+        }
+    }
+
+    /**
+     * Add runtime arguments to run the tests with.
+     *
+     * @param mRunTimeArgs
+     */
+    public void addRunTimeArgs(String mRunTimeArgs) {
+        mRuntimeArgs = mRunTimeArgs;
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/SingleJUnitTestResultParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/SingleJUnitTestResultParser.java
new file mode 100644
index 0000000..117a974
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/SingleJUnitTestResultParser.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 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.cts.tradefed.testtype;
+
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.testrunner.ITestRunListener;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Parses the test results from {@link com.android.cts.junit.SingleJUnitTestRunner}
+ */
+public class SingleJUnitTestResultParser extends MultiLineReceiver {
+
+    private static final String PASSED_TEST_MARKER = "[ PASSED ]";
+    private static final String FAILED_TEST_MARKER = "[ FAILED ]";
+    private final TestIdentifier mTestId;
+    private final Collection<ITestRunListener> mTestListeners;
+    private StringBuilder mStackTrace = new StringBuilder();
+
+    public SingleJUnitTestResultParser(TestIdentifier testId, Collection<ITestRunListener> listeners) {
+        mTestId = testId;
+        mTestListeners = new ArrayList<ITestRunListener>(listeners);
+    }
+
+    public SingleJUnitTestResultParser(TestIdentifier testId, ITestRunListener listener) {
+        mTestId = testId;
+        mTestListeners = new ArrayList<ITestRunListener>(1);
+        mTestListeners.add(listener);
+    }
+
+    @Override
+    public boolean isCancelled() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void processNewLines(String[] lines) {
+        for (String line : lines) {
+            parse(line);
+        }
+    }
+
+    /**
+     * Parses a given string.
+     * @param line
+     */
+    private void parse(String line) {
+        if (line.startsWith(PASSED_TEST_MARKER)) {
+            doTestEnded(true);
+        } else if (line.startsWith(FAILED_TEST_MARKER)) {
+            doTestEnded(false);
+        } else {
+            // Store everything in case there is a failure.
+            mStackTrace.append("\n");
+            mStackTrace.append(line);
+        }
+    }
+
+    /**
+     * Handle cases when test ends.
+     * @param testPassed whether or not the test passed.
+     */
+    private void doTestEnded(boolean testPassed) {
+        // If test failed.
+        if (!testPassed) {
+            for (ITestRunListener listener : mTestListeners) {
+                listener.testFailed(ITestRunListener.TestFailure.FAILURE, mTestId,
+                        mStackTrace.toString());
+            }
+        }
+        Map<String, String> emptyMap = Collections.emptyMap();
+        for (ITestRunListener listener : mTestListeners) {
+            listener.testEnded(mTestId, emptyMap);
+        }
+        mStackTrace = new StringBuilder();
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index 994da0b..307cb3a 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -55,6 +55,7 @@
     public static final String DISPLAY_TEST =
             "com.android.cts.tradefed.testtype.DisplayTestRunner";
     public static final String UIAUTOMATOR_TEST = "uiAutomator";
+    public static final String JUNIT_DEVICE_TEST = "jUnitDeviceTest";
 
     private static final String SIGNATURE_TEST_METHOD = "testSignature";
     private static final String SIGNATURE_TEST_CLASS = "android.tests.sigtest.SignatureTest";
@@ -65,6 +66,7 @@
     private String mRunner = null;
     private String mTestType = null;
     private String mJarPath = null;
+    private String mRunTimeArgs = null;
     private boolean mIsSignatureTest = false;
     private String mTestPackageName = null;
     private String mDigest = null;
@@ -98,6 +100,14 @@
         return mUri;
     }
 
+    void setRunTimeArgs(String runTimeArgs) {
+        mRunTimeArgs = runTimeArgs;
+    }
+
+    String getRunTimeArgs() {
+        return mRunTimeArgs;
+    }
+
     void setAppNameSpace(String appNameSpace) {
         mAppNameSpace = appNameSpace;
     }
@@ -261,6 +271,15 @@
             instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
             mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
             return instrTest;
+        } else if (JUNIT_DEVICE_TEST.equals(mTestType)){
+            CLog.d("Creating JUnit device test %s", mName);
+            JUnitDeviceTest jUnitDeviceTest = new JUnitDeviceTest();
+            jUnitDeviceTest.setRunName(getUri());
+            jUnitDeviceTest.addTestJarFileName(mJarPath);
+            jUnitDeviceTest.addRunTimeArgs(mRunTimeArgs);
+            jUnitDeviceTest.setTests(mTests);
+            mDigest = generateDigest(testCaseDir, mJarPath);
+            return jUnitDeviceTest;
         } else {
             CLog.d("Creating instrumentation test for %s", mName);
             InstrumentationApkTest instrTest = new InstrumentationApkTest();
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
index bd67f78..5d10dfc 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageXmlParser.java
@@ -75,6 +75,7 @@
                 final String javaPackageFilter = attributes.getValue("javaPackageFilter");
                 final String targetBinaryName = attributes.getValue("targetBinaryName");
                 final String targetNameSpace = attributes.getValue("targetNameSpace");
+                final String runTimeArgs = attributes.getValue("runtimeArgs");
 
                 mPackageDef = new TestPackageDef();
                 mPackageDef.setUri(entryUriValue);
@@ -84,6 +85,7 @@
                 mPackageDef.setTestType(getTestType(attributes));
                 mPackageDef.setJarPath(jarPath);
                 mPackageDef.setIsSignatureCheck(parseBoolean(signatureCheck));
+                mPackageDef.setRunTimeArgs(runTimeArgs);
                 if (!"".equals(javaPackageFilter)) {
                     mPackageDef.setTestPackageName(javaPackageFilter);
                 }
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index db30d77..0f74a81 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -105,59 +105,47 @@
 
     plan = tools.TestPlan(packages)
     plan.Exclude('android\.performance.*')
-    # Temporarily exclude jdwp tests until framework to run them is available.
-    # b/15860343
-    plan.Exclude('android\.jdwp.*')
     self.__WritePlan(plan, 'CTS')
     self.__WritePlan(plan, 'CTS-TF')
 
     plan = tools.TestPlan(packages)
     plan.Exclude('android\.performance.*')
-    plan.Exclude('android\.jdwp.*')
     plan.Exclude('android\.media\.cts\.StreamingMediaPlayerTest.*')
     # Test plan to not include media streaming tests
     self.__WritePlan(plan, 'CTS-No-Media-Stream')
 
     plan = tools.TestPlan(packages)
     plan.Exclude('android\.performance.*')
-    plan.Exclude('android\.jdwp.*')
     self.__WritePlan(plan, 'SDK')
 
     plan.Exclude(r'android\.tests\.sigtest')
-    plan.Exclude('android\.jdwp.*')
     plan.Exclude(r'android\.core.*')
     self.__WritePlan(plan, 'Android')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude('android\.jdwp.*')
     plan.Include(r'android\.core\.tests.*')
     plan.Exclude(r'android\.core\.tests\.libcore.\package.\harmony*')
     self.__WritePlan(plan, 'Java')
 
     # TODO: remove this once the tests are fixed and merged into Java plan above.
     plan = tools.TestPlan(packages)
-    plan.Exclude('android\.jdwp.*')
     plan.Include(r'android\.core\.tests\.libcore.\package.\harmony*')
     self.__WritePlan(plan, 'Harmony')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude('android\.jdwp.*')
     plan.Include(r'android\.core\.vm-tests-tf')
     self.__WritePlan(plan, 'VM-TF')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude('android\.jdwp.*')
     plan.Include(r'android\.tests\.sigtest')
     self.__WritePlan(plan, 'Signature')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude('android\.jdwp.*')
     plan.Include(r'android\.tests\.appsecurity')
     self.__WritePlan(plan, 'AppSecurity')
 
     # hard-coded white list for PDK plan
     plan.Exclude('.*')
-    plan.Exclude('android\.jdwp.*')
     plan.Include('android\.aadb')
     plan.Include('android\.bluetooth')
     plan.Include('android\.graphics.*')
@@ -176,7 +164,6 @@
 
     # CTS Stable plan
     plan = tools.TestPlan(packages)
-    plan.Exclude('android\.jdwp.*')
     plan.Exclude(r'android\.display')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
@@ -185,7 +172,6 @@
     # CTS Flaky plan - inversion of CTS Stable
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
-    plan.Exclude('android\.jdwp.*')
     plan.Include(r'android\.display')
     for package, test_list in flaky_tests.iteritems():
       plan.Include(package)