Add CTS test target.
Bug: 8538755
Change-Id: Icaa86509f2984bd415440ca3edd602f939b31df5
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 2860c73..d878d63 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -156,6 +156,9 @@
 cts_device_executables := \
     print-instrument
 
+cts_target_junit_tests := \
+    CtsJdwp
+
 # All the files that will end up under the repository/testcases
 # directory of the final CTS distribution.
 CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
@@ -163,6 +166,7 @@
     $(call cts-get-native-paths,$(cts_native_exes)) \
     $(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
     $(call cts-get-ui-lib-paths,$(cts_device_jars)) \
+    $(call cts-get-ui-lib-paths,$(cts_target_junit_tests)) \
     $(call cts-get-executable-paths,$(cts_device_executables))
 
 # All the XMLs that will end up under the repository/testcases
@@ -170,6 +174,7 @@
 CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
     $(call cts-get-test-xmls,$(cts_test_packages)) \
     $(call cts-get-test-xmls,$(cts_native_exes)) \
+    $(call cts-get-test-xmls,$(cts_target_junit_tests)) \
     $(call cts-get-test-xmls,$(cts_ui_tests))
 
 # The following files will be placed in the tools directory of the CTS distribution
diff --git a/build/config.mk b/build/config.mk
index b737ef7..e127e90 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -16,4 +16,5 @@
 BUILD_CTS_PACKAGE := cts/build/test_package.mk
 BUILD_CTS_GTEST_PACKAGE := cts/build/test_gtest_package.mk
 BUILD_CTS_HOST_JAVA_LIBRARY := cts/build/test_host_java_library.mk
+BUILD_CTS_TARGET_JAVA_LIBRARY := cts/build/test_target_java_library.mk
 BUILD_CTS_UI_JAVA_LIBRARY := cts/build/test_uiautomator.mk
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
new file mode 100644
index 0000000..516d4ba
--- /dev/null
+++ b/build/test_target_java_library.mk
@@ -0,0 +1,44 @@
+# 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.
+
+#
+# Builds a host library and defines a rule to generate the associated test
+# package XML needed by CTS.
+#
+# Disable by default so "m cts" will work in emulator builds
+LOCAL_DEX_PREOPT := false
+include $(BUILD_JAVA_LIBRARY)
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE) | $(ACP)
+	$(copy-file-to-target)
+
+cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
+$(cts_library_xml): $(cts_library_jar)
+$(cts_library_xml): PRIVATE_PATH := $(LOCAL_PATH)/src
+$(cts_library_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
+$(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
+$(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
+$(cts_library_xml): PRIVATE_RUNTIME_ARGS := $(LOCAL_CTS_TARGET_RUNTIME_ARGS)
+$(cts_library_xml): $(TARGET_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+	$(hide) echo Generating test description for target library $(PRIVATE_LIBRARY)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+	$(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
+						-d $(CTS_JAVA_TEST_SCANNER_DOCLET) | \
+			$(CTS_XML_GENERATOR) -t jUnitDeviceTest \
+						-j $(PRIVATE_JAR_PATH) \
+						-n $(PRIVATE_LIBRARY) \
+						-p $(PRIVATE_TEST_PACKAGE) \
+						-e $(CTS_EXPECTATIONS) \
+						-x "runtime_args->$(PRIVATE_RUNTIME_ARGS)" \
+						-o $@
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
index c5b253a..1cf5a7e 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
@@ -24,7 +24,9 @@
 
 import java.io.File;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -36,7 +38,7 @@
         System.err.println("Arguments: " + Arrays.asList(args));
         System.err.println("Usage: cts-xml-generator -p PACKAGE_NAME -n NAME [-t TEST_TYPE]"
                 + " [-j JAR_PATH] [-i INSTRUMENTATION] [-m MANIFEST_FILE] [-e EXPECTATION_FILE]"
-                + " [-o OUTPUT_FILE]");
+                + " [-o OUTPUT_FILE] [-a APP_NAME_SPACE] [-x ADDITIONAL_ATTRIBUTE_KEY->VALUE]");
         System.exit(1);
     }
 
@@ -51,6 +53,7 @@
         String jarPath = null;
         String appNameSpace = null;
         String targetNameSpace = null;
+        Map<String, String> additionalAttributes = new HashMap<String, String>();
 
         for (int i = 0; i < args.length; i++) {
             if ("-p".equals(args[i])) {
@@ -74,6 +77,20 @@
                 appNameSpace =  getArg(args, ++i, "Missing value for app name space");
             } else if ("-r".equals(args[i])) {
                 targetNameSpace =  getArg(args, ++i, "Missing value for target name space");
+            } else if ("-x".equals(args[i])) {
+                String value = getArg(args, ++i, "Missing value for additional attribute");
+                String[] tokens = value.split("->");
+                if (tokens.length != 2) {
+                    System.err.println(
+                            "For specifying additional attributes; use the format KEY->VALUE");
+                    usage(args);
+                }
+                if (additionalAttributes.containsKey(tokens[0])) {
+                    System.err.println(String.format(
+                            "Additional attribute %s has already been specified", tokens[0]));
+                    usage(args);
+                }
+                additionalAttributes.put(tokens[0], tokens[1]);
             } else {
                 System.err.println("Unsupported flag: " + args[i]);
                 usage(args);
@@ -103,7 +120,8 @@
 
         ExpectationStore store = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
         XmlGenerator generator = new XmlGenerator(store, appNameSpace, appPackageName,
-                name, runner, instrumentation, targetNameSpace, jarPath, testType, outputPath);
+                name, runner, instrumentation, targetNameSpace, jarPath, testType, outputPath,
+                additionalAttributes);
         generator.writePackageXml();
     }
 
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
index 7b1996d..b1a006e 100644
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
+++ b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
@@ -27,6 +27,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Map;
 import java.util.List;
 
 /**
@@ -72,9 +73,12 @@
     /** ExpectationStore to filter out known failures. */
     private final ExpectationStore mExpectations;
 
+    private final Map<String, String> mAdditionalAttributes;
+
     XmlGenerator(ExpectationStore expectations, String appNameSpace, String appPackageName,
             String name, String runner, String targetBinaryName, String targetNameSpace,
-            String jarPath, String testType, String outputPath) {
+            String jarPath, String testType, String outputPath,
+            Map<String, String> additionalAttributes) {
         mAppNamespace = appNameSpace;
         mAppPackageName = appPackageName;
         mName = name;
@@ -85,6 +89,7 @@
         mTestType = testType;
         mOutputPath = outputPath;
         mExpectations = expectations;
+        mAdditionalAttributes = additionalAttributes;
     }
 
     public void writePackageXml() throws IOException {
@@ -133,6 +138,10 @@
             writer.append(" jarPath=\"").append(mJarPath).append("\"");
         }
 
+        for (Map.Entry<String, String> entry : mAdditionalAttributes.entrySet()) {
+            writer.append(String.format(" %s=\"%s\"", entry.getKey(), entry.getValue()));
+        }
+
         writer.println(" version=\"1.0\">");
 
         TestListParser parser = new TestListParser();