old-cts: Add support for testng runners and libcoreoj tests

Bug: 27521545
Change-Id: I2a954401ce47604987a437a2741bcab252d32707
(cherry picked from commit f995e9586cd0aa878e1e9a0bbb89971b69db0d65)
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 1302c07..745cd6b 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -265,7 +265,8 @@
     CtsJdwpApp
 
 cts_target_junit_tests := \
-    CtsJdwp
+    CtsJdwp \
+    CtsLibcoreOj
 
 cts_deqp_test_apis := \
     egl \
diff --git a/build/config.mk b/build/config.mk
index 56d4ae6..7683214 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -48,3 +48,4 @@
 BUILD_CTS_SUPPORT_PACKAGE := cts/build/support_package.mk
 BUILD_CTS_MODULE_TEST_CONFIG := cts/build/module_test_config.mk
 BUILD_CTS_DEVICE_INFO_PACKAGE := cts/build/device_info_package.mk
+BUILD_CTS_TARGET_TESTNG_PACKAGE := cts/build/test_target_testng_package.mk
diff --git a/build/test_target_testng_package.mk b/build/test_target_testng_package.mk
new file mode 100644
index 0000000..0621109
--- /dev/null
+++ b/build/test_target_testng_package.mk
@@ -0,0 +1,53 @@
+# 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.
+
+#
+# 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)
+include $(BUILD_CTS_MODULE_TEST_CONFIG)
+
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
+	$(copy-file-to-target)
+
+CTS_DEQP_CONFIG_PATH := $(call my-dir)
+
+cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
+$(cts_library_xml): MUSTPASS_XML_FILE := $(LOCAL_CTS_TESTCASE_XML_INPUT)
+$(cts_library_xml): PRIVATE_DUMMY_CASELIST := $(CTS_DEQP_CONFIG_PATH)/deqp_dummy_test_list
+$(cts_library_xml): $(cts_library_jar)
+$(cts_library_xml): $(cts_module_test_config)
+$(cts_library_xml): $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_XML_GENERATOR) $(CTS_TESTCASE_XML_INPUT)
+	$(hide) echo Generating test description for target testng package $(PRIVATE_LIBRARY)
+	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
+
+# Query build ABIs by routing a dummy test list through xml generator and parse result. Use sed to insert the ABI string into the XML files.
+	$(hide) SUPPORTED_ABI_ATTR=`$(CTS_XML_GENERATOR) -t dummyTest \
+									-n dummyName \
+									-p invalid.dummy \
+									-e $(CTS_EXPECTATIONS) \
+									-b $(CTS_UNSUPPORTED_ABIS) \
+									-a $(CTS_TARGET_ARCH) \
+									< $(PRIVATE_DUMMY_CASELIST) \
+									| grep --only-matching -e " abis=\"[^\"]*\""` && \
+			$(SED_EXTENDED) -e "s:^(\s*)<Test ((.[^/]|[^/])*)(/?)>$$:\1<Test \2 $${SUPPORTED_ABI_ATTR}\4>:" \
+				< $(MUSTPASS_XML_FILE) \
+				> $@
+
+# Have the module name depend on the cts files; so the cts files get generated when you run mm/mmm/mma/mmma.
+$(my_register_name) : $(cts_library_jar) $(cts_library_xml) $(cts_module_test_config)
diff --git a/tests/tests/libcoreoj/Android.mk b/tests/tests/libcoreoj/Android.mk
new file mode 100644
index 0000000..4e289b8
--- /dev/null
+++ b/tests/tests/libcoreoj/Android.mk
@@ -0,0 +1,31 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(harmony_jdwp_test_src_files)
+LOCAL_STATIC_JAVA_LIBRARIES := core-ojtests-public
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := CtsLibcoreOj
+LOCAL_NO_EMMA_INSTRUMENT := true
+LOCAL_NO_EMMA_COMPILE := true
+LOCAL_CTS_TEST_PACKAGE := android.libcore.oj
+LOCAL_CTS_TARGET_RUNTIME_ARGS := cts_jdwp_test_runtime_target := dalvikvm|\#ABI\#|
+LOCAL_CTS_TESTCASE_XML_INPUT := $(LOCAL_PATH)/CtsTestPackage.xml
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+# Also include the source code as part of the jar. DO NOT REMOVE.
+# FIXME: build/core/java_library.mk:14: *** cts/tests/tests/libcoreoj: Target java libraries may not set LOCAL_ASSET_DIR.
+#LOCAL_ASSET_DIR := libcore/ojluni/src/test
+include $(BUILD_CTS_TARGET_TESTNG_PACKAGE)
diff --git a/tests/tests/libcoreoj/AndroidTest.xml b/tests/tests/libcoreoj/AndroidTest.xml
new file mode 100644
index 0000000..7bb02ad
--- /dev/null
+++ b/tests/tests/libcoreoj/AndroidTest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Base config for libcore OJ testing in CTS">
+    <include name="common-config" />
+    <!-- Removes temporary dalvik-cache directory created by JDWP tests -->
+    <option name="run-command:teardown-command" value="rm -rf /data/local/tmp/dalvik-cache" />
+</configuration>
diff --git a/tests/tests/libcoreoj/CtsTestPackage.xml b/tests/tests/libcoreoj/CtsTestPackage.xml
new file mode 100644
index 0000000..2578fb9
--- /dev/null
+++ b/tests/tests/libcoreoj/CtsTestPackage.xml
@@ -0,0 +1,450 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestPackage name="CtsLibcoreOj" appPackageName="android.libcore.oj" version="1.0" testType="testNGDeviceTest" jarPath="CtsLibcoreOj.jar">
+  <TestSuite name="org">
+    <TestSuite name="openjdk">
+      <TestSuite name="tests">
+        <TestSuite name="java">
+          <TestSuite name="util">
+            <TestSuite name="stream">
+              <TestCase name="CollectionAndMapModifyStreamTest">
+                <Test name="testCollectionSizeRemove" />
+                <Test name="testMapEntriesSizeRemove" />
+                <Test name="testMapKeysSizeRemove" />
+                <Test name="testMapValuesSizeRemove" />
+              </TestCase>
+              <TestCase name="ConcatOpTest">
+                <Test name="testDoubleSize" />
+                <Test name="testIntSize" />
+                <Test name="testLongSize" />
+                <Test name="testOps" />
+                <Test name="testSize" />
+              </TestCase>
+              <TestCase name="ConcatTest">
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+              </TestCase>
+              <TestCase name="CountLargeTest">
+                <Test name="testDoubleLarge" />
+                <Test name="testIntLarge" />
+                <Test name="testLongLarge" />
+                <Test name="testRefLarge" />
+              </TestCase>
+              <TestCase name="CountTest">
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="DistinctOpTest">
+                <Test name="testDistinctDistinct" />
+                <Test name="testDistinctSorted" />
+                <Test name="testOp" />
+                <Test name="testOpWithNull" />
+                <Test name="testOpWithNullSorted" />
+                <Test name="testSortedDistinct" />
+                <Test name="testStable" />
+                <Test name="testUniqOp" />
+                <Test name="testWithUnorderedInfiniteStream" />
+              </TestCase>
+              <TestCase name="DoublePrimitiveOpsTests">
+                <Test name="testLimit" />
+                <Test name="testSort" />
+                <Test name="testSortSort" />
+                <Test name="testToArray" />
+                <Test name="testUnBox" />
+              </TestCase>
+              <TestCase name="ExplodeOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testFlatMap" />
+                <Test name="testIntOps" />
+                <Test name="testLongOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="FilterOpTest">
+                <Test name="testFilter" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="FindAnyOpTest">
+                <Test name="testDoubleStream" />
+                <Test name="testFindAny" />
+                <Test name="testFindAnyParallel" />
+                <Test name="testIntStream" />
+                <Test name="testLongStream" />
+                <Test name="testStream" />
+              </TestCase>
+              <TestCase name="FindFirstOpTest">
+                <Test name="testDoubleStream" />
+                <Test name="testFindFirst" />
+                <Test name="testIntStream" />
+                <Test name="testLongStream" />
+                <Test name="testStream" />
+              </TestCase>
+              <TestCase name="ForEachOpTest">
+                <Test name="testDoubleForEachOrdered" />
+                <Test name="testDoubleOps" />
+                <Test name="testForEach" />
+                <Test name="testForEach" />
+                <Test name="testForEachOrdered" />
+                <Test name="testIntForEach" />
+                <Test name="testIntForEachOrdered" />
+                <Test name="testLongForEachOrdered" />
+                <Test name="testLongOps" />
+              </TestCase>
+              <TestCase name="GroupByOpTest">
+                <Test name="testBypassCollect" />
+                <Test name="testGroupBy" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="InfiniteStreamWithLimitOpTest">
+                <Test name="testDoubleSubsizedWithRange" />
+                <Test name="testDoubleUnorderedFinite" />
+                <Test name="testDoubleUnorderedGenerator" />
+                <Test name="testDoubleUnorderedIteration" />
+                <Test name="testDoubleUnorderedSizedNotSubsizedFinite" />
+                <Test name="testIntSubsizedWithRange" />
+                <Test name="testIntUnorderedFinite" />
+                <Test name="testIntUnorderedGenerator" />
+                <Test name="testIntUnorderedIteration" />
+                <Test name="testIntUnorderedSizedNotSubsizedFinite" />
+                <Test name="testLongSubsizedWithRange" />
+                <Test name="testLongUnorderedFinite" />
+                <Test name="testLongUnorderedGenerator" />
+                <Test name="testLongUnorderedIteration" />
+                <Test name="testLongUnorderedSizedNotSubsizedFinite" />
+                <Test name="testSubsizedWithRange" />
+                <Test name="testUnorderedFinite" />
+                <Test name="testUnorderedGenerator" />
+                <Test name="testUnorderedIteration" />
+                <Test name="testUnorderedSizedNotSubsizedFinite" />
+              </TestCase>
+              <TestCase name="IntPrimitiveOpsTests">
+                <Test name="testBox" />
+                <Test name="testForEach" />
+                <Test name="testLimit" />
+                <Test name="testMap" />
+                <Test name="testParForEach" />
+                <Test name="testParSum" />
+                <Test name="testSequential" />
+                <Test name="testSort" />
+                <Test name="testSortSort" />
+                <Test name="testSum" />
+                <Test name="testTee" />
+                <Test name="testToArray" />
+                <Test name="testUnBox" />
+              </TestCase>
+              <TestCase name="IntReduceTest">
+                <Test name="testOps" />
+                <Test name="testReduce" />
+              </TestCase>
+              <TestCase name="IntSliceOpTest">
+                <Test name="testLimit" />
+                <Test name="testLimitOps" />
+                <Test name="testLimitParallel" />
+                <Test name="testLimitShortCircuit" />
+                <Test name="testLimitSort" />
+                <Test name="testSkip" />
+                <Test name="testSkipLimit" />
+                <Test name="testSkipLimitOps" />
+                <Test name="testSkipOps" />
+                <Test name="testSkipParallel" />
+              </TestCase>
+              <TestCase name="IntUniqOpTest">
+                <Test name="testOp" />
+                <Test name="testOpSorted" />
+                <Test name="testUniqOp" />
+              </TestCase>
+              <TestCase name="LongPrimitiveOpsTests">
+                <Test name="testBox" />
+                <Test name="testForEach" />
+                <Test name="testLimit" />
+                <Test name="testMap" />
+                <Test name="testParForEach" />
+                <Test name="testParSum" />
+                <Test name="testSequential" />
+                <Test name="testSort" />
+                <Test name="testSortSort" />
+                <Test name="testSum" />
+                <Test name="testTee" />
+                <Test name="testToArray" />
+                <Test name="testUnBox" />
+              </TestCase>
+              <TestCase name="MapOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testEveryMapShape" />
+                <Test name="testIntOps" />
+                <Test name="testLongOps" />
+                <Test name="testMap" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="MatchOpTest">
+                <Test name="testDoubleInfinite" />
+                <Test name="testDoubleStream" />
+                <Test name="testDoubleStreamMatches" />
+                <Test name="testInfinite" />
+                <Test name="testIntInfinite" />
+                <Test name="testIntStream" />
+                <Test name="testIntStreamMatches" />
+                <Test name="testLongInfinite" />
+                <Test name="testLongStream" />
+                <Test name="testLongStreamMatches" />
+                <Test name="testStream" />
+                <Test name="testStreamMatches" />
+              </TestCase>
+              <TestCase name="MinMaxTest">
+                <Test name="testDoubleMinMax" />
+                <Test name="testDoubleOps" />
+                <Test name="testIntMinMax" />
+                <Test name="testIntOps" />
+                <Test name="testLongMinMax" />
+                <Test name="testLongOps" />
+                <Test name="testMinMax" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="PrimitiveAverageOpTest">
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="PrimitiveSumTest">
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="RangeTest">
+                <Test name="tesIntRangeReduce" />
+                <Test name="testInfiniteRangeFindFirst" />
+                <Test name="testIntInfiniteRangeFindFirst" />
+                <Test name="testIntInfiniteRangeLimit" />
+                <Test name="testIntRange" />
+                <Test name="testLongInfiniteRangeFindFirst" />
+                <Test name="testLongInfiniteRangeLimit" />
+                <Test name="testLongLongRange" />
+                <Test name="testLongLongRangeClosed" />
+                <Test name="testLongRange" />
+                <Test name="testLongRangeReduce" />
+              </TestCase>
+              <TestCase name="ReduceByOpTest">
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="ReduceTest">
+                <Test name="testOps" />
+                <Test name="testReduce" />
+              </TestCase>
+              <TestCase name="SequentialOpTest">
+                <Test name="testLazy" />
+                <Test name="testMixedSeqPar" />
+              </TestCase>
+              <TestCase name="SliceOpTest">
+                <Test name="testLimit" />
+                <Test name="testLimitOps" />
+                <Test name="testLimitShortCircuit" />
+                <Test name="testLimitSort" />
+                <Test name="testSkip" />
+                <Test name="testSkipLimit" />
+                <Test name="testSkipLimitOps" />
+                <Test name="testSkipLimitOpsWithNonSplittingSpliterator" />
+                <Test name="testSkipOps" />
+                <Test name="testSlice" />
+              </TestCase>
+              <TestCase name="SortedOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testDoubleSequentialShortCircuitTerminal" />
+                <Test name="testDoubleSortSort" />
+                <Test name="testDoubleStreamTooLarge" />
+                <Test name="testIntOps" />
+                <Test name="testIntSequentialShortCircuitTerminal" />
+                <Test name="testIntSortSort" />
+                <Test name="testIntStreamTooLarge" />
+                <Test name="testLongOps" />
+                <Test name="testLongSequentialShortCircuitTerminal" />
+                <Test name="testLongSortSort" />
+                <Test name="testLongStreamTooLarge" />
+                <Test name="testOps" />
+                <Test name="testRefStreamTooLarge" />
+                <Test name="testSequentialShortCircuitTerminal" />
+                <Test name="testSortSort" />
+                <Test name="testSorted" />
+              </TestCase>
+              <TestCase name="SpliteratorTest">
+                <Test name="testDoubleSpliterator" />
+                <Test name="testIntSpliterator" />
+                <Test name="testLongSpliterator" />
+                <Test name="testSpliterator" />
+              </TestCase>
+              <TestCase name="StreamBuilderTest">
+                <Test name="testAfterBuilding" />
+                <Test name="testDoubleAfterBuilding" />
+                <Test name="testDoubleSingleton" />
+                <Test name="testDoubleStreamBuilder" />
+                <Test name="testIntAfterBuilding" />
+                <Test name="testIntSingleton" />
+                <Test name="testIntStreamBuilder" />
+                <Test name="testLongAfterBuilding" />
+                <Test name="testLongSingleton" />
+                <Test name="testLongStreamBuilder" />
+                <Test name="testSingleton" />
+                <Test name="testStreamBuilder" />
+              </TestCase>
+              <TestCase name="StreamCloseTest">
+                <Test name="testCascadedExceptions" />
+                <Test name="testEmptyCloseHandler" />
+                <Test name="testOneCloseHandler" />
+                <Test name="testTwoCloseHandlers" />
+              </TestCase>
+              <TestCase name="StreamLinkTest">
+                <Test name="testDoubleManyStreams" />
+                <Test name="testIntManyStreams" />
+                <Test name="testLongManyStreams" />
+                <Test name="testManyStreams" />
+              </TestCase>
+              <TestCase name="StreamParSeqTest">
+                <Test name="testParSeq" />
+              </TestCase>
+              <TestCase name="StreamSpliteratorTest">
+                <Test name="testDoubleParSpliterators" />
+                <Test name="testDoubleSpliterators" />
+                <Test name="testDoubleSplitting" />
+                <Test name="testDoubleStreamSpliterators" />
+                <Test name="testIntParSpliterators" />
+                <Test name="testIntSpliterators" />
+                <Test name="testIntSplitting" />
+                <Test name="testIntStreamSpliterators" />
+                <Test name="testLongParSpliterators" />
+                <Test name="testLongSpliterators" />
+                <Test name="testLongSplitting" />
+                <Test name="testLongStreamSpliterators" />
+                <Test name="testParSpliterators" />
+                <Test name="testSpliterators" />
+                <Test name="testSplitting" />
+                <Test name="testStreamSpliterators" />
+              </TestCase>
+              <TestCase name="SummaryStatisticsTest">
+                <Test name="testDoubleStatistics" />
+                <Test name="testIntStatistics" />
+                <Test name="testLongStatistics" />
+              </TestCase>
+              <TestCase name="TabulatorsTest">
+                <Test name="testComposeFinisher" />
+                <Test name="testGroupedReduce" />
+                <Test name="testJoin" />
+                <Test name="testReduce" />
+                <Test name="testSimpleGroupBy" />
+                <Test name="testSimplePartition" />
+                <Test name="testSimpleToMap" />
+                <Test name="testTwoLevelGroupBy" />
+                <Test name="testTwoLevelPartition" />
+              </TestCase>
+              <TestCase name="TeeOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testIntOps" />
+                <Test name="testLongOps" />
+                <Test name="testOps" />
+                <Test name="testTee" />
+              </TestCase>
+              <TestCase name="ToArrayOpTest">
+                <Test name="testAsArrayWithType" />
+                <Test name="testDistinctAndSortedPermutations" />
+                <Test name="testDoubleDistinctAndSortedPermutations" />
+                <Test name="testDoubleOps" />
+                <Test name="testDoubleOpsWithFilter" />
+                <Test name="testDoubleOpsWithFlatMap" />
+                <Test name="testDoubleOpsWithMap" />
+                <Test name="testDoubleOpsWithSorted" />
+                <Test name="testDoubleStatefulOpPermutations" />
+                <Test name="testIntDistinctAndSortedPermutations" />
+                <Test name="testIntOps" />
+                <Test name="testIntOpsWithFilter" />
+                <Test name="testIntOpsWithFlatMap" />
+                <Test name="testIntOpsWithMap" />
+                <Test name="testIntOpsWithSorted" />
+                <Test name="testIntStatefulOpPermutations" />
+                <Test name="testLongDistinctAndSortedPermutations" />
+                <Test name="testLongOps" />
+                <Test name="testLongOpsWithFilter" />
+                <Test name="testLongOpsWithFlatMap" />
+                <Test name="testLongOpsWithMap" />
+                <Test name="testLongOpsWithSorted" />
+                <Test name="testLongStatefulOpPermutations" />
+                <Test name="testOps" />
+                <Test name="testOpsWithFilter" />
+                <Test name="testOpsWithFlatMap" />
+                <Test name="testOpsWithMap" />
+                <Test name="testOpsWithSorted" />
+                <Test name="testStatefulOpPermutations" />
+                <Test name="testToArray" />
+              </TestCase>
+            </TestSuite>
+            <TestCase name="FillableStringTest">
+              <Test name="testStringBuffer" />
+              <Test name="testStringBuilder" />
+              <Test name="testStringJoiner" />
+            </TestCase>
+            <TestCase name="MapTest">
+              <Test name="testForEach" />
+              <Test name="testReplaceAll" />
+            </TestCase>
+          </TestSuite>
+          <TestSuite name="lang">
+            <TestSuite name="invoke">
+              <TestCase name="DeserializeMethodTest">
+                <Test name="testCapturingNonSerLambda" />
+                <Test name="testCapturingNonserIntersectionLambda" />
+                <Test name="testCapturingSerLambda" />
+                <Test name="testEmptyClass" />
+              </TestCase>
+            </TestSuite>
+          </TestSuite>
+        </TestSuite>
+      </TestSuite>
+    </TestSuite>
+  </TestSuite>
+</TestPackage>
diff --git a/tools/testng/Android.mk b/tools/testng/Android.mk
new file mode 100644
index 0000000..2abb7f9
--- /dev/null
+++ b/tools/testng/Android.mk
@@ -0,0 +1,27 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES :=  $(call all-java-files-under, src)
+LOCAL_MODULE := cts-testng
+LOCAL_MODULE_TAGS := optional
+LOCAL_STATIC_JAVA_LIBRARIES := testng
+LOCAL_DEX_PREOPT := false
+include $(BUILD_JAVA_LIBRARY)
+
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
+	$(copy-file-to-target)
diff --git a/tools/testng/OjTests.xml b/tools/testng/OjTests.xml
new file mode 100644
index 0000000..2578fb9
--- /dev/null
+++ b/tools/testng/OjTests.xml
@@ -0,0 +1,450 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestPackage name="CtsLibcoreOj" appPackageName="android.libcore.oj" version="1.0" testType="testNGDeviceTest" jarPath="CtsLibcoreOj.jar">
+  <TestSuite name="org">
+    <TestSuite name="openjdk">
+      <TestSuite name="tests">
+        <TestSuite name="java">
+          <TestSuite name="util">
+            <TestSuite name="stream">
+              <TestCase name="CollectionAndMapModifyStreamTest">
+                <Test name="testCollectionSizeRemove" />
+                <Test name="testMapEntriesSizeRemove" />
+                <Test name="testMapKeysSizeRemove" />
+                <Test name="testMapValuesSizeRemove" />
+              </TestCase>
+              <TestCase name="ConcatOpTest">
+                <Test name="testDoubleSize" />
+                <Test name="testIntSize" />
+                <Test name="testLongSize" />
+                <Test name="testOps" />
+                <Test name="testSize" />
+              </TestCase>
+              <TestCase name="ConcatTest">
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testDoubleConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testIntConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testLongConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+                <Test name="testRefConcat" />
+              </TestCase>
+              <TestCase name="CountLargeTest">
+                <Test name="testDoubleLarge" />
+                <Test name="testIntLarge" />
+                <Test name="testLongLarge" />
+                <Test name="testRefLarge" />
+              </TestCase>
+              <TestCase name="CountTest">
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="DistinctOpTest">
+                <Test name="testDistinctDistinct" />
+                <Test name="testDistinctSorted" />
+                <Test name="testOp" />
+                <Test name="testOpWithNull" />
+                <Test name="testOpWithNullSorted" />
+                <Test name="testSortedDistinct" />
+                <Test name="testStable" />
+                <Test name="testUniqOp" />
+                <Test name="testWithUnorderedInfiniteStream" />
+              </TestCase>
+              <TestCase name="DoublePrimitiveOpsTests">
+                <Test name="testLimit" />
+                <Test name="testSort" />
+                <Test name="testSortSort" />
+                <Test name="testToArray" />
+                <Test name="testUnBox" />
+              </TestCase>
+              <TestCase name="ExplodeOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testFlatMap" />
+                <Test name="testIntOps" />
+                <Test name="testLongOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="FilterOpTest">
+                <Test name="testFilter" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="FindAnyOpTest">
+                <Test name="testDoubleStream" />
+                <Test name="testFindAny" />
+                <Test name="testFindAnyParallel" />
+                <Test name="testIntStream" />
+                <Test name="testLongStream" />
+                <Test name="testStream" />
+              </TestCase>
+              <TestCase name="FindFirstOpTest">
+                <Test name="testDoubleStream" />
+                <Test name="testFindFirst" />
+                <Test name="testIntStream" />
+                <Test name="testLongStream" />
+                <Test name="testStream" />
+              </TestCase>
+              <TestCase name="ForEachOpTest">
+                <Test name="testDoubleForEachOrdered" />
+                <Test name="testDoubleOps" />
+                <Test name="testForEach" />
+                <Test name="testForEach" />
+                <Test name="testForEachOrdered" />
+                <Test name="testIntForEach" />
+                <Test name="testIntForEachOrdered" />
+                <Test name="testLongForEachOrdered" />
+                <Test name="testLongOps" />
+              </TestCase>
+              <TestCase name="GroupByOpTest">
+                <Test name="testBypassCollect" />
+                <Test name="testGroupBy" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="InfiniteStreamWithLimitOpTest">
+                <Test name="testDoubleSubsizedWithRange" />
+                <Test name="testDoubleUnorderedFinite" />
+                <Test name="testDoubleUnorderedGenerator" />
+                <Test name="testDoubleUnorderedIteration" />
+                <Test name="testDoubleUnorderedSizedNotSubsizedFinite" />
+                <Test name="testIntSubsizedWithRange" />
+                <Test name="testIntUnorderedFinite" />
+                <Test name="testIntUnorderedGenerator" />
+                <Test name="testIntUnorderedIteration" />
+                <Test name="testIntUnorderedSizedNotSubsizedFinite" />
+                <Test name="testLongSubsizedWithRange" />
+                <Test name="testLongUnorderedFinite" />
+                <Test name="testLongUnorderedGenerator" />
+                <Test name="testLongUnorderedIteration" />
+                <Test name="testLongUnorderedSizedNotSubsizedFinite" />
+                <Test name="testSubsizedWithRange" />
+                <Test name="testUnorderedFinite" />
+                <Test name="testUnorderedGenerator" />
+                <Test name="testUnorderedIteration" />
+                <Test name="testUnorderedSizedNotSubsizedFinite" />
+              </TestCase>
+              <TestCase name="IntPrimitiveOpsTests">
+                <Test name="testBox" />
+                <Test name="testForEach" />
+                <Test name="testLimit" />
+                <Test name="testMap" />
+                <Test name="testParForEach" />
+                <Test name="testParSum" />
+                <Test name="testSequential" />
+                <Test name="testSort" />
+                <Test name="testSortSort" />
+                <Test name="testSum" />
+                <Test name="testTee" />
+                <Test name="testToArray" />
+                <Test name="testUnBox" />
+              </TestCase>
+              <TestCase name="IntReduceTest">
+                <Test name="testOps" />
+                <Test name="testReduce" />
+              </TestCase>
+              <TestCase name="IntSliceOpTest">
+                <Test name="testLimit" />
+                <Test name="testLimitOps" />
+                <Test name="testLimitParallel" />
+                <Test name="testLimitShortCircuit" />
+                <Test name="testLimitSort" />
+                <Test name="testSkip" />
+                <Test name="testSkipLimit" />
+                <Test name="testSkipLimitOps" />
+                <Test name="testSkipOps" />
+                <Test name="testSkipParallel" />
+              </TestCase>
+              <TestCase name="IntUniqOpTest">
+                <Test name="testOp" />
+                <Test name="testOpSorted" />
+                <Test name="testUniqOp" />
+              </TestCase>
+              <TestCase name="LongPrimitiveOpsTests">
+                <Test name="testBox" />
+                <Test name="testForEach" />
+                <Test name="testLimit" />
+                <Test name="testMap" />
+                <Test name="testParForEach" />
+                <Test name="testParSum" />
+                <Test name="testSequential" />
+                <Test name="testSort" />
+                <Test name="testSortSort" />
+                <Test name="testSum" />
+                <Test name="testTee" />
+                <Test name="testToArray" />
+                <Test name="testUnBox" />
+              </TestCase>
+              <TestCase name="MapOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testEveryMapShape" />
+                <Test name="testIntOps" />
+                <Test name="testLongOps" />
+                <Test name="testMap" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="MatchOpTest">
+                <Test name="testDoubleInfinite" />
+                <Test name="testDoubleStream" />
+                <Test name="testDoubleStreamMatches" />
+                <Test name="testInfinite" />
+                <Test name="testIntInfinite" />
+                <Test name="testIntStream" />
+                <Test name="testIntStreamMatches" />
+                <Test name="testLongInfinite" />
+                <Test name="testLongStream" />
+                <Test name="testLongStreamMatches" />
+                <Test name="testStream" />
+                <Test name="testStreamMatches" />
+              </TestCase>
+              <TestCase name="MinMaxTest">
+                <Test name="testDoubleMinMax" />
+                <Test name="testDoubleOps" />
+                <Test name="testIntMinMax" />
+                <Test name="testIntOps" />
+                <Test name="testLongMinMax" />
+                <Test name="testLongOps" />
+                <Test name="testMinMax" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="PrimitiveAverageOpTest">
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="PrimitiveSumTest">
+                <Test name="testOps" />
+                <Test name="testOps" />
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="RangeTest">
+                <Test name="tesIntRangeReduce" />
+                <Test name="testInfiniteRangeFindFirst" />
+                <Test name="testIntInfiniteRangeFindFirst" />
+                <Test name="testIntInfiniteRangeLimit" />
+                <Test name="testIntRange" />
+                <Test name="testLongInfiniteRangeFindFirst" />
+                <Test name="testLongInfiniteRangeLimit" />
+                <Test name="testLongLongRange" />
+                <Test name="testLongLongRangeClosed" />
+                <Test name="testLongRange" />
+                <Test name="testLongRangeReduce" />
+              </TestCase>
+              <TestCase name="ReduceByOpTest">
+                <Test name="testOps" />
+              </TestCase>
+              <TestCase name="ReduceTest">
+                <Test name="testOps" />
+                <Test name="testReduce" />
+              </TestCase>
+              <TestCase name="SequentialOpTest">
+                <Test name="testLazy" />
+                <Test name="testMixedSeqPar" />
+              </TestCase>
+              <TestCase name="SliceOpTest">
+                <Test name="testLimit" />
+                <Test name="testLimitOps" />
+                <Test name="testLimitShortCircuit" />
+                <Test name="testLimitSort" />
+                <Test name="testSkip" />
+                <Test name="testSkipLimit" />
+                <Test name="testSkipLimitOps" />
+                <Test name="testSkipLimitOpsWithNonSplittingSpliterator" />
+                <Test name="testSkipOps" />
+                <Test name="testSlice" />
+              </TestCase>
+              <TestCase name="SortedOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testDoubleSequentialShortCircuitTerminal" />
+                <Test name="testDoubleSortSort" />
+                <Test name="testDoubleStreamTooLarge" />
+                <Test name="testIntOps" />
+                <Test name="testIntSequentialShortCircuitTerminal" />
+                <Test name="testIntSortSort" />
+                <Test name="testIntStreamTooLarge" />
+                <Test name="testLongOps" />
+                <Test name="testLongSequentialShortCircuitTerminal" />
+                <Test name="testLongSortSort" />
+                <Test name="testLongStreamTooLarge" />
+                <Test name="testOps" />
+                <Test name="testRefStreamTooLarge" />
+                <Test name="testSequentialShortCircuitTerminal" />
+                <Test name="testSortSort" />
+                <Test name="testSorted" />
+              </TestCase>
+              <TestCase name="SpliteratorTest">
+                <Test name="testDoubleSpliterator" />
+                <Test name="testIntSpliterator" />
+                <Test name="testLongSpliterator" />
+                <Test name="testSpliterator" />
+              </TestCase>
+              <TestCase name="StreamBuilderTest">
+                <Test name="testAfterBuilding" />
+                <Test name="testDoubleAfterBuilding" />
+                <Test name="testDoubleSingleton" />
+                <Test name="testDoubleStreamBuilder" />
+                <Test name="testIntAfterBuilding" />
+                <Test name="testIntSingleton" />
+                <Test name="testIntStreamBuilder" />
+                <Test name="testLongAfterBuilding" />
+                <Test name="testLongSingleton" />
+                <Test name="testLongStreamBuilder" />
+                <Test name="testSingleton" />
+                <Test name="testStreamBuilder" />
+              </TestCase>
+              <TestCase name="StreamCloseTest">
+                <Test name="testCascadedExceptions" />
+                <Test name="testEmptyCloseHandler" />
+                <Test name="testOneCloseHandler" />
+                <Test name="testTwoCloseHandlers" />
+              </TestCase>
+              <TestCase name="StreamLinkTest">
+                <Test name="testDoubleManyStreams" />
+                <Test name="testIntManyStreams" />
+                <Test name="testLongManyStreams" />
+                <Test name="testManyStreams" />
+              </TestCase>
+              <TestCase name="StreamParSeqTest">
+                <Test name="testParSeq" />
+              </TestCase>
+              <TestCase name="StreamSpliteratorTest">
+                <Test name="testDoubleParSpliterators" />
+                <Test name="testDoubleSpliterators" />
+                <Test name="testDoubleSplitting" />
+                <Test name="testDoubleStreamSpliterators" />
+                <Test name="testIntParSpliterators" />
+                <Test name="testIntSpliterators" />
+                <Test name="testIntSplitting" />
+                <Test name="testIntStreamSpliterators" />
+                <Test name="testLongParSpliterators" />
+                <Test name="testLongSpliterators" />
+                <Test name="testLongSplitting" />
+                <Test name="testLongStreamSpliterators" />
+                <Test name="testParSpliterators" />
+                <Test name="testSpliterators" />
+                <Test name="testSplitting" />
+                <Test name="testStreamSpliterators" />
+              </TestCase>
+              <TestCase name="SummaryStatisticsTest">
+                <Test name="testDoubleStatistics" />
+                <Test name="testIntStatistics" />
+                <Test name="testLongStatistics" />
+              </TestCase>
+              <TestCase name="TabulatorsTest">
+                <Test name="testComposeFinisher" />
+                <Test name="testGroupedReduce" />
+                <Test name="testJoin" />
+                <Test name="testReduce" />
+                <Test name="testSimpleGroupBy" />
+                <Test name="testSimplePartition" />
+                <Test name="testSimpleToMap" />
+                <Test name="testTwoLevelGroupBy" />
+                <Test name="testTwoLevelPartition" />
+              </TestCase>
+              <TestCase name="TeeOpTest">
+                <Test name="testDoubleOps" />
+                <Test name="testIntOps" />
+                <Test name="testLongOps" />
+                <Test name="testOps" />
+                <Test name="testTee" />
+              </TestCase>
+              <TestCase name="ToArrayOpTest">
+                <Test name="testAsArrayWithType" />
+                <Test name="testDistinctAndSortedPermutations" />
+                <Test name="testDoubleDistinctAndSortedPermutations" />
+                <Test name="testDoubleOps" />
+                <Test name="testDoubleOpsWithFilter" />
+                <Test name="testDoubleOpsWithFlatMap" />
+                <Test name="testDoubleOpsWithMap" />
+                <Test name="testDoubleOpsWithSorted" />
+                <Test name="testDoubleStatefulOpPermutations" />
+                <Test name="testIntDistinctAndSortedPermutations" />
+                <Test name="testIntOps" />
+                <Test name="testIntOpsWithFilter" />
+                <Test name="testIntOpsWithFlatMap" />
+                <Test name="testIntOpsWithMap" />
+                <Test name="testIntOpsWithSorted" />
+                <Test name="testIntStatefulOpPermutations" />
+                <Test name="testLongDistinctAndSortedPermutations" />
+                <Test name="testLongOps" />
+                <Test name="testLongOpsWithFilter" />
+                <Test name="testLongOpsWithFlatMap" />
+                <Test name="testLongOpsWithMap" />
+                <Test name="testLongOpsWithSorted" />
+                <Test name="testLongStatefulOpPermutations" />
+                <Test name="testOps" />
+                <Test name="testOpsWithFilter" />
+                <Test name="testOpsWithFlatMap" />
+                <Test name="testOpsWithMap" />
+                <Test name="testOpsWithSorted" />
+                <Test name="testStatefulOpPermutations" />
+                <Test name="testToArray" />
+              </TestCase>
+            </TestSuite>
+            <TestCase name="FillableStringTest">
+              <Test name="testStringBuffer" />
+              <Test name="testStringBuilder" />
+              <Test name="testStringJoiner" />
+            </TestCase>
+            <TestCase name="MapTest">
+              <Test name="testForEach" />
+              <Test name="testReplaceAll" />
+            </TestCase>
+          </TestSuite>
+          <TestSuite name="lang">
+            <TestSuite name="invoke">
+              <TestCase name="DeserializeMethodTest">
+                <Test name="testCapturingNonSerLambda" />
+                <Test name="testCapturingNonserIntersectionLambda" />
+                <Test name="testCapturingSerLambda" />
+                <Test name="testEmptyClass" />
+              </TestCase>
+            </TestSuite>
+          </TestSuite>
+        </TestSuite>
+      </TestSuite>
+    </TestSuite>
+  </TestSuite>
+</TestPackage>
diff --git a/tools/testng/gen-test-list-xml b/tools/testng/gen-test-list-xml
new file mode 100755
index 0000000..e2a5ef8
--- /dev/null
+++ b/tools/testng/gen-test-list-xml
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+#
+# Usage:
+# -- Update test_list.txt with new tests/methods whenever new code is added.
+# -- Run this script ./gen-test-list-xml
+# -- Save the updated .xml file into the build, so ctsv1 knows how to run our testng tests.
+#
+
+test_list_txt=$DIR/test_list.txt
+[[ -f $test_list_txt ]] || echo "Can't find $test_list_txt" >&2
+
+$DIR/gen-test-list-xml.py --app-package-name android.libcore.oj --cts-name CtsLibcoreOj --jar-path CtsLibcoreOj.jar $DIR/test_list.txt
diff --git a/tools/testng/gen-test-list-xml.py b/tools/testng/gen-test-list-xml.py
new file mode 100755
index 0000000..961410d
--- /dev/null
+++ b/tools/testng/gen-test-list-xml.py
@@ -0,0 +1,248 @@
+#!/usr/bin/python2.7
+
+# 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.
+
+#
+# Generate a CTS test XML file from a text file containing every single class#method per line
+#
+# For example, given an input file:
+#
+#          foo.txt:
+#                com.android.ClassName#methodNameA
+#                com.android.ClassName#methodNameB
+#
+# Will generate the output file:
+#
+#          TestPackage.xml:
+#                <TestPackage>
+#                  <TestSuite name="com">
+#                    <TestSuite name="android">
+#                      <TestCase name="ClassName">
+#                        <Test name="methodNameA" />
+#                        <Test name="methodNameB" />
+#                      </TestCase>
+#                    </TestSuite>
+#                  </TestSuite>
+#                </TestPackage>
+#
+
+import argparse
+import sys
+
+INDENTATION_INCREASE=2
+
+class BaseNode(object):
+    def __init__(self, name=None):
+        self._children = []
+        self._name = name
+        self._properties = []
+
+    def _get_children(self):
+        return self._children
+
+    def _set_children(self, value):
+        self._children = value
+
+    children = property(_get_children, _set_children, doc="Get/set list of children BaseNode")
+
+    def append_child(self, child):
+        self._children.append(child)
+
+    def has_children(self):
+        return not not self._children
+
+    def _get_name(self):
+        return self._name
+
+    def _set_name(self, value):
+        self._name = value
+
+    name = property(_get_name, _set_name, doc="Get/set the name property of the current XML node")
+
+    def _get_type_name(self):
+        return type(self).__name__
+
+    type_name = property(_get_type_name, doc="Get the name of the current XML node")
+
+    def _set_properties(self, value):
+        self._properties = value
+
+    def _get_properties(self):
+        return self._properties
+
+    properties = property(_get_properties, _set_properties, doc="Get/set additional XML properties such as appPackageName (as a dict)")
+
+    def write_xml(self, out, indent=0):
+        out.write(' ' * indent)
+        out.write('<' + self.type_name)
+
+        if self.name is not None:
+            out.write(' name="')
+            out.write(self.name)
+            out.write('"')
+
+        if self.properties:
+            for key, value in self.properties.iteritems():
+                out.write(' ' + key + '="' + value + '"')
+
+        if not self.has_children():
+            out.write(' />')
+            out.write('\n')
+            return
+
+        out.write('>\n')
+
+        #TODO: print all the properties
+
+        for child in self.children:
+            child.write_xml(out, indent + INDENTATION_INCREASE)
+
+        out.write(' ' * indent)
+        out.write('</' + self.type_name + '>')
+        out.write('\n')
+
+class _SuiteContainer(BaseNode):
+    def get_or_create_suite(self, package_list):
+        debug_print("get_or_create_suite, package_list = " + str(package_list))
+        debug_print("name = " + self.name)
+        # If we are empty, then we just reached the TestSuite which we actually wanted. Return.
+        if not package_list:
+            return self
+
+        current_package = package_list[0]
+        rest_of_packages = package_list[1:]
+
+        # If a suite already exists for the requested package, then have it look/create recursively.
+        for child in self.children:
+            if child.name == current_package:
+                return child.get_or_create_suite(rest_of_packages)
+
+        # No suite exists yet, create it recursively
+        new_suite = TestSuite(name=current_package)
+        self.append_child(new_suite)
+        return new_suite.get_or_create_suite(rest_of_packages)
+
+class TestPackage(_SuiteContainer):
+    def add_class_and_method(self, fq_class_name, method):
+        debug_print("add_class_and_method, fq_class_name=" + fq_class_name + ", method=" + method)
+        package_list = fq_class_name.split(".")[:-1] # a.b.c -> ['a', 'b']
+        just_class_name = fq_class_name.split(".")[-1] # a.b.c -> 'c'
+
+        test_suite = self.get_or_create_suite(package_list)
+
+        if test_suite == self:
+            raise Exception("The suite cannot be the package")
+
+        return test_suite.add_class_and_method(just_class_name, method)
+
+class TestSuite(_SuiteContainer):
+    def add_class_and_method(self, just_class_name, method_name):
+        test_case = self.get_or_create_test_case(just_class_name)
+        return test_case.add_method(method_name)
+
+    def get_or_create_test_case(self, just_class_name):
+        for child in self.children:
+            if child.name == just_class_name:
+                return child
+
+        new_test_case = TestCase(name=just_class_name)
+        self.append_child(new_test_case)
+        return new_test_case
+
+class TestCase(BaseNode):
+    def add_method(self, method_name):
+        tst = Test(name=method_name)
+        self.append_child(tst)
+        return tst
+
+class Test(BaseNode):
+    def __init__(self, name):
+        super(Test, self).__init__(name)
+        self._children = None
+
+def debug_print(x):
+    #print x
+    pass
+
+def build_xml_test_package(input, name, xml_properties):
+    root = TestPackage(name=name)
+
+    for line in input:
+        class_and_method_name = line.split('#')
+        fq_class_name = class_and_method_name[0].strip()
+        method_name = class_and_method_name[1].strip()
+
+        root.add_class_and_method(fq_class_name, method_name)
+
+    root.properties = xml_properties
+    return root
+
+def write_xml(out, test_package):
+    out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
+    test_package.write_xml(out)
+
+def main():
+    parser = argparse.ArgumentParser(description='Process a test methods list file to generate CTS test xml.')
+
+    # Named required
+    parser.add_argument('--cts-name', help="name (e.g. CtsJdwp)", required=True)
+    parser.add_argument('--app-package-name', help="appPackageName (e.g. android.jdwp)", required=True)
+    parser.add_argument('--jar-path', help="jarPath (e.g. CtsJdwp.jar)", required=True)
+
+    # Named optionals
+    parser.add_argument('--test-type', help="testType (default testNGDeviceTest)",
+                        default="testNGDeviceTest")
+    parser.add_argument('--runtime-args', help="runtimeArgs (e.g. -XXlib:libart.so)")
+    parser.add_argument('--version', help="version (default 1.0)", default="1.0")
+
+    # Positional optionals
+    parser.add_argument('input-filename', nargs='?',
+                               help='name of the cts test file (stdin by default)')
+    parser.add_argument('output-filename', nargs='?',
+                               help='name of the cts output file (stdout by default)')
+
+    # Map named arguments into the xml <TestPackage> property key name
+    argv_to_xml = {
+            'app_package_name' : 'appPackageName',
+            'jar_path' : 'jarPath',
+            'test_type' : 'testType',
+            'runtime_args' : 'runtimeArgs',
+            'version' : 'version'
+    }
+
+    args = parser.parse_args()
+    argv = vars(args) # convert Namespace to Dict
+
+    xml_properties = {}
+    for key, value in argv_to_xml.iteritems():
+        if argv.get(key):
+            xml_properties[value] = argv[key]
+
+    debug_print(argv['input-filename'])
+    debug_print(argv['output-filename'])
+
+    name_in = argv['input-filename']
+    name_out = argv['output-filename']
+
+    file_in = name_in and open(name_in, "r") or sys.stdin
+    file_out = name_out and open(name_out, "w+") or sys.stdout
+
+    # read all the input
+    test_package = build_xml_test_package(file_in, args.cts_name, xml_properties)
+    # write all the output
+    write_xml(file_out, test_package)
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/testng/src/com/android/cts/testng/SingleTestNGTestRunListener.java b/tools/testng/src/com/android/cts/testng/SingleTestNGTestRunListener.java
new file mode 100644
index 0000000..2509366
--- /dev/null
+++ b/tools/testng/src/com/android/cts/testng/SingleTestNGTestRunListener.java
@@ -0,0 +1,95 @@
+/*
+ * 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 com.android.cts.testng;
+
+import java.util.Arrays;
+
+public class SingleTestNGTestRunListener implements org.testng.ITestListener {
+    private static class Prefixes {
+        @SuppressWarnings("unused")
+        private static final String INFORMATIONAL_MARKER =  "[----------]";
+        private static final String START_TEST_MARKER =     "[ RUN      ]";
+        private static final String OK_TEST_MARKER =        "[       OK ]";
+        private static final String ERROR_TEST_RUN_MARKER = "[    ERROR ]";
+        private static final String SKIPPED_TEST_MARKER =   "[     SKIP ]";
+        private static final String TEST_RUN_MARKER =       "[==========]";
+    }
+
+    @Override
+    public void onFinish(org.testng.ITestContext context) {
+        System.out.println(String.format("%s", Prefixes.TEST_RUN_MARKER));
+    }
+
+    @Override
+    public void onStart(org.testng.ITestContext context) {
+        System.out.println(String.format("%s", Prefixes.INFORMATIONAL_MARKER));
+    }
+
+    @Override
+    public void onTestFailedButWithinSuccessPercentage(org.testng.ITestResult result) {
+        onTestFailure(result);
+    }
+
+    @Override
+    public void onTestFailure(org.testng.ITestResult result) {
+        // All failures are coalesced into one '[ FAILED ]' message at the end
+        // This is because a single test method can run multiple times with different parameters.
+        // Since we only test a single method, it's safe to combine all failures into one
+        // failure at the end.
+        //
+        // The big pass/fail is printed from SingleTestNGTestRunner, not from the listener.
+        System.out.println(String.format("%s %s ::: %s", Prefixes.ERROR_TEST_RUN_MARKER,
+              getId(result), stringify(result.getThrowable())));
+    }
+
+    @Override
+    public void onTestSkipped(org.testng.ITestResult result) {
+        System.out.println(String.format("%s %s", Prefixes.SKIPPED_TEST_MARKER,
+              getId(result)));
+    }
+
+    @Override
+    public void onTestStart(org.testng.ITestResult result) {
+        System.out.println(String.format("%s %s", Prefixes.START_TEST_MARKER,
+              getId(result)));
+    }
+
+    @Override
+    public void onTestSuccess(org.testng.ITestResult result) {
+        System.out.println(String.format("%s", Prefixes.OK_TEST_MARKER));
+    }
+
+    private String getId(org.testng.ITestResult test) {
+        // TestNG is quite complicated since tests can have arbitrary parameters.
+        // Use its code to stringify a result name instead of doing it ourselves.
+
+        org.testng.remote.strprotocol.TestResultMessage msg =
+                new org.testng.remote.strprotocol.TestResultMessage(
+                    null, /*suite name*/
+                    null, /*test name -- display the test method name instead */
+                    test);
+
+        String className = test.getTestClass().getName();
+        //String name = test.getMethod().getMethodName();
+        return String.format("%s#%s", className, msg.toDisplayString());
+
+    }
+
+    private String stringify(Throwable error) {
+        return Arrays.toString(error.getStackTrace()).replaceAll("\n", " ");
+    }
+}
diff --git a/tools/testng/src/com/android/cts/testng/SingleTestNGTestRunner.java b/tools/testng/src/com/android/cts/testng/SingleTestNGTestRunner.java
new file mode 100644
index 0000000..c9f31af
--- /dev/null
+++ b/tools/testng/src/com/android/cts/testng/SingleTestNGTestRunner.java
@@ -0,0 +1,88 @@
+/*
+ * 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 com.android.cts.testng;
+
+import org.testng.TestNG;
+import org.testng.xml.XmlClass;
+import org.testng.xml.XmlInclude;
+import org.testng.xml.XmlSuite;
+import org.testng.xml.XmlTest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test runner to run a single TestNG test. It will output either [PASSED] or [FAILED] at the end.
+ */
+public class SingleTestNGTestRunner {
+    private static String mUsage = "Usage: java -cp <classpath> SingleTestNGTestRunner" +
+            " class#testMethod";
+    private static final String PASSED_TEST_MARKER = "[ PASSED ]";
+    private static final String FAILED_TEST_MARKER = "[ FAILED ]";
+
+    public static void main(String... args) {
+        if (args.length != 1) {
+            throw new IllegalArgumentException(mUsage);
+        }
+        String[] classAndMethod = args[0].split("#");
+        if (classAndMethod.length != 2) {
+            throw new IllegalArgumentException(mUsage);
+        }
+
+        TestNG testng = createTestNG(classAndMethod[0], classAndMethod[1]);
+        testng.run();
+        String status = (!testng.hasFailure()) ? PASSED_TEST_MARKER : FAILED_TEST_MARKER;
+        System.out.println(String.format("%s %s.%s", status,
+                classAndMethod[0], classAndMethod[1]));
+    }
+
+    private static org.testng.TestNG createTestNG(String klass, String method) {
+        org.testng.TestNG testng = new org.testng.TestNG();
+        testng.setUseDefaultListeners(false);  // Don't create the testng-specific HTML/XML reports.
+        testng.addListener(new SingleTestNGTestRunListener());
+
+        /* Construct the following equivalent XML configuration:
+         *
+         * <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+         * <suite>
+         *   <test>
+         *     <classes>
+         *       <class name="$klass">
+         *         <include name="$method" />
+         *       </class>
+         *     </classes>
+         *   </test>
+         * </suite>
+         *
+         * This will ensure that only a single klass/method is being run by testng.
+         * (It can still be run multiple times due to @DataProvider, with different parameters
+         * each time)
+         */
+        List<XmlSuite> suites = new ArrayList<>();
+        XmlSuite the_suite = new XmlSuite();
+        XmlTest the_test = new XmlTest(the_suite);
+        XmlClass the_class = new XmlClass(klass);
+        XmlInclude the_include = new XmlInclude(method);
+
+        the_class.getIncludedMethods().add(the_include);
+        the_test.getXmlClasses().add(the_class);
+        suites.add(the_suite);
+        testng.setXmlSuites(suites);
+
+        return testng;
+    }
+}
diff --git a/tools/testng/test-script b/tools/testng/test-script
new file mode 100755
index 0000000..9bfdf82
--- /dev/null
+++ b/tools/testng/test-script
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+adb push $ANDROID_PRODUCT_OUT/system/framework/cts-testng.jar /data/local/tmp
+adb shell "cd /data/local/tmp && dalvikvm -cp cts-testng.jar:ctslibcore/CtsLibcoreOjTestCases.apk com.android.cts.testng.SingleTestNGTestRunner org.openjdk.tests.java.util.stream.GroupByOpTest#testOps"
diff --git a/tools/testng/test_list.txt b/tools/testng/test_list.txt
new file mode 100644
index 0000000..5516c0d
--- /dev/null
+++ b/tools/testng/test_list.txt
@@ -0,0 +1,345 @@
+org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testCollectionSizeRemove
+org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testMapEntriesSizeRemove
+org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testMapKeysSizeRemove
+org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testMapValuesSizeRemove
+org.openjdk.tests.java.util.stream.ConcatOpTest#testDoubleSize
+org.openjdk.tests.java.util.stream.ConcatOpTest#testIntSize
+org.openjdk.tests.java.util.stream.ConcatOpTest#testLongSize
+org.openjdk.tests.java.util.stream.ConcatOpTest#testOps
+org.openjdk.tests.java.util.stream.ConcatOpTest#testSize
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
+org.openjdk.tests.java.util.stream.CountLargeTest#testDoubleLarge
+org.openjdk.tests.java.util.stream.CountLargeTest#testIntLarge
+org.openjdk.tests.java.util.stream.CountLargeTest#testLongLarge
+org.openjdk.tests.java.util.stream.CountLargeTest#testRefLarge
+org.openjdk.tests.java.util.stream.CountTest#testOps
+org.openjdk.tests.java.util.stream.CountTest#testOps
+org.openjdk.tests.java.util.stream.CountTest#testOps
+org.openjdk.tests.java.util.stream.CountTest#testOps
+org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testCapturingNonSerLambda
+org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testCapturingNonserIntersectionLambda
+org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testCapturingSerLambda
+org.openjdk.tests.java.lang.invoke.DeserializeMethodTest#testEmptyClass
+org.openjdk.tests.java.util.stream.DistinctOpTest#testDistinctDistinct
+org.openjdk.tests.java.util.stream.DistinctOpTest#testDistinctSorted
+org.openjdk.tests.java.util.stream.DistinctOpTest#testOp
+org.openjdk.tests.java.util.stream.DistinctOpTest#testOpWithNull
+org.openjdk.tests.java.util.stream.DistinctOpTest#testOpWithNullSorted
+org.openjdk.tests.java.util.stream.DistinctOpTest#testSortedDistinct
+org.openjdk.tests.java.util.stream.DistinctOpTest#testStable
+org.openjdk.tests.java.util.stream.DistinctOpTest#testUniqOp
+org.openjdk.tests.java.util.stream.DistinctOpTest#testWithUnorderedInfiniteStream
+org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testLimit
+org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testSort
+org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testSortSort
+org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testToArray
+org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testUnBox
+org.openjdk.tests.java.util.stream.ExplodeOpTest#testDoubleOps
+org.openjdk.tests.java.util.stream.ExplodeOpTest#testFlatMap
+org.openjdk.tests.java.util.stream.ExplodeOpTest#testIntOps
+org.openjdk.tests.java.util.stream.ExplodeOpTest#testLongOps
+org.openjdk.tests.java.util.stream.ExplodeOpTest#testOps
+org.openjdk.tests.java.util.FillableStringTest#testStringBuffer
+org.openjdk.tests.java.util.FillableStringTest#testStringBuilder
+org.openjdk.tests.java.util.FillableStringTest#testStringJoiner
+org.openjdk.tests.java.util.stream.FilterOpTest#testFilter
+org.openjdk.tests.java.util.stream.FilterOpTest#testOps
+org.openjdk.tests.java.util.stream.FilterOpTest#testOps
+org.openjdk.tests.java.util.stream.FilterOpTest#testOps
+org.openjdk.tests.java.util.stream.FilterOpTest#testOps
+org.openjdk.tests.java.util.stream.FindAnyOpTest#testDoubleStream
+org.openjdk.tests.java.util.stream.FindAnyOpTest#testFindAny
+org.openjdk.tests.java.util.stream.FindAnyOpTest#testFindAnyParallel
+org.openjdk.tests.java.util.stream.FindAnyOpTest#testIntStream
+org.openjdk.tests.java.util.stream.FindAnyOpTest#testLongStream
+org.openjdk.tests.java.util.stream.FindAnyOpTest#testStream
+org.openjdk.tests.java.util.stream.FindFirstOpTest#testDoubleStream
+org.openjdk.tests.java.util.stream.FindFirstOpTest#testFindFirst
+org.openjdk.tests.java.util.stream.FindFirstOpTest#testIntStream
+org.openjdk.tests.java.util.stream.FindFirstOpTest#testLongStream
+org.openjdk.tests.java.util.stream.FindFirstOpTest#testStream
+org.openjdk.tests.java.util.stream.ForEachOpTest#testDoubleForEachOrdered
+org.openjdk.tests.java.util.stream.ForEachOpTest#testDoubleOps
+org.openjdk.tests.java.util.stream.ForEachOpTest#testForEach
+org.openjdk.tests.java.util.stream.ForEachOpTest#testForEach
+org.openjdk.tests.java.util.stream.ForEachOpTest#testForEachOrdered
+org.openjdk.tests.java.util.stream.ForEachOpTest#testIntForEach
+org.openjdk.tests.java.util.stream.ForEachOpTest#testIntForEachOrdered
+org.openjdk.tests.java.util.stream.ForEachOpTest#testLongForEachOrdered
+org.openjdk.tests.java.util.stream.ForEachOpTest#testLongOps
+org.openjdk.tests.java.util.stream.GroupByOpTest#testBypassCollect
+org.openjdk.tests.java.util.stream.GroupByOpTest#testGroupBy
+org.openjdk.tests.java.util.stream.GroupByOpTest#testOps
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleSubsizedWithRange
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedGenerator
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedIteration
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedSizedNotSubsizedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntSubsizedWithRange
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedGenerator
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedIteration
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedSizedNotSubsizedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongSubsizedWithRange
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedGenerator
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedIteration
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedSizedNotSubsizedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testSubsizedWithRange
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedFinite
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedGenerator
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedIteration
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedSizedNotSubsizedFinite
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testBox
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testForEach
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testLimit
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testMap
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testParForEach
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testParSum
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSequential
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSort
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSortSort
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSum
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testTee
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testToArray
+org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testUnBox
+org.openjdk.tests.java.util.stream.IntReduceTest#testOps
+org.openjdk.tests.java.util.stream.IntReduceTest#testReduce
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimit
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitOps
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitParallel
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitShortCircuit
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitSort
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkip
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipLimit
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipLimitOps
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipOps
+org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipParallel
+org.openjdk.tests.java.util.stream.IntUniqOpTest#testOp
+org.openjdk.tests.java.util.stream.IntUniqOpTest#testOpSorted
+org.openjdk.tests.java.util.stream.IntUniqOpTest#testUniqOp
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testBox
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testForEach
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testLimit
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testMap
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testParForEach
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testParSum
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSequential
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSort
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSortSort
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSum
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testTee
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testToArray
+org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testUnBox
+org.openjdk.tests.java.util.stream.MapOpTest#testDoubleOps
+org.openjdk.tests.java.util.stream.MapOpTest#testEveryMapShape
+org.openjdk.tests.java.util.stream.MapOpTest#testIntOps
+org.openjdk.tests.java.util.stream.MapOpTest#testLongOps
+org.openjdk.tests.java.util.stream.MapOpTest#testMap
+org.openjdk.tests.java.util.stream.MapOpTest#testOps
+org.openjdk.tests.java.util.MapTest#testForEach
+org.openjdk.tests.java.util.MapTest#testReplaceAll
+org.openjdk.tests.java.util.stream.MatchOpTest#testDoubleInfinite
+org.openjdk.tests.java.util.stream.MatchOpTest#testDoubleStream
+org.openjdk.tests.java.util.stream.MatchOpTest#testDoubleStreamMatches
+org.openjdk.tests.java.util.stream.MatchOpTest#testInfinite
+org.openjdk.tests.java.util.stream.MatchOpTest#testIntInfinite
+org.openjdk.tests.java.util.stream.MatchOpTest#testIntStream
+org.openjdk.tests.java.util.stream.MatchOpTest#testIntStreamMatches
+org.openjdk.tests.java.util.stream.MatchOpTest#testLongInfinite
+org.openjdk.tests.java.util.stream.MatchOpTest#testLongStream
+org.openjdk.tests.java.util.stream.MatchOpTest#testLongStreamMatches
+org.openjdk.tests.java.util.stream.MatchOpTest#testStream
+org.openjdk.tests.java.util.stream.MatchOpTest#testStreamMatches
+org.openjdk.tests.java.util.stream.MinMaxTest#testDoubleMinMax
+org.openjdk.tests.java.util.stream.MinMaxTest#testDoubleOps
+org.openjdk.tests.java.util.stream.MinMaxTest#testIntMinMax
+org.openjdk.tests.java.util.stream.MinMaxTest#testIntOps
+org.openjdk.tests.java.util.stream.MinMaxTest#testLongMinMax
+org.openjdk.tests.java.util.stream.MinMaxTest#testLongOps
+org.openjdk.tests.java.util.stream.MinMaxTest#testMinMax
+org.openjdk.tests.java.util.stream.MinMaxTest#testOps
+org.openjdk.tests.java.util.stream.PrimitiveAverageOpTest#testOps
+org.openjdk.tests.java.util.stream.PrimitiveAverageOpTest#testOps
+org.openjdk.tests.java.util.stream.PrimitiveAverageOpTest#testOps
+org.openjdk.tests.java.util.stream.PrimitiveSumTest#testOps
+org.openjdk.tests.java.util.stream.PrimitiveSumTest#testOps
+org.openjdk.tests.java.util.stream.PrimitiveSumTest#testOps
+org.openjdk.tests.java.util.stream.RangeTest#tesIntRangeReduce
+org.openjdk.tests.java.util.stream.RangeTest#testInfiniteRangeFindFirst
+org.openjdk.tests.java.util.stream.RangeTest#testIntInfiniteRangeFindFirst
+org.openjdk.tests.java.util.stream.RangeTest#testIntInfiniteRangeLimit
+org.openjdk.tests.java.util.stream.RangeTest#testIntRange
+org.openjdk.tests.java.util.stream.RangeTest#testLongInfiniteRangeFindFirst
+org.openjdk.tests.java.util.stream.RangeTest#testLongInfiniteRangeLimit
+org.openjdk.tests.java.util.stream.RangeTest#testLongLongRange
+org.openjdk.tests.java.util.stream.RangeTest#testLongLongRangeClosed
+org.openjdk.tests.java.util.stream.RangeTest#testLongRange
+org.openjdk.tests.java.util.stream.RangeTest#testLongRangeReduce
+org.openjdk.tests.java.util.stream.ReduceByOpTest#testOps
+org.openjdk.tests.java.util.stream.ReduceTest#testOps
+org.openjdk.tests.java.util.stream.ReduceTest#testReduce
+org.openjdk.tests.java.util.stream.SequentialOpTest#testLazy
+org.openjdk.tests.java.util.stream.SequentialOpTest#testMixedSeqPar
+org.openjdk.tests.java.util.stream.SliceOpTest#testLimit
+org.openjdk.tests.java.util.stream.SliceOpTest#testLimitOps
+org.openjdk.tests.java.util.stream.SliceOpTest#testLimitShortCircuit
+org.openjdk.tests.java.util.stream.SliceOpTest#testLimitSort
+org.openjdk.tests.java.util.stream.SliceOpTest#testSkip
+org.openjdk.tests.java.util.stream.SliceOpTest#testSkipLimit
+org.openjdk.tests.java.util.stream.SliceOpTest#testSkipLimitOps
+org.openjdk.tests.java.util.stream.SliceOpTest#testSkipLimitOpsWithNonSplittingSpliterator
+org.openjdk.tests.java.util.stream.SliceOpTest#testSkipOps
+org.openjdk.tests.java.util.stream.SliceOpTest#testSlice
+org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleOps
+org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleSequentialShortCircuitTerminal
+org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleSortSort
+org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleStreamTooLarge
+org.openjdk.tests.java.util.stream.SortedOpTest#testIntOps
+org.openjdk.tests.java.util.stream.SortedOpTest#testIntSequentialShortCircuitTerminal
+org.openjdk.tests.java.util.stream.SortedOpTest#testIntSortSort
+org.openjdk.tests.java.util.stream.SortedOpTest#testIntStreamTooLarge
+org.openjdk.tests.java.util.stream.SortedOpTest#testLongOps
+org.openjdk.tests.java.util.stream.SortedOpTest#testLongSequentialShortCircuitTerminal
+org.openjdk.tests.java.util.stream.SortedOpTest#testLongSortSort
+org.openjdk.tests.java.util.stream.SortedOpTest#testLongStreamTooLarge
+org.openjdk.tests.java.util.stream.SortedOpTest#testOps
+org.openjdk.tests.java.util.stream.SortedOpTest#testRefStreamTooLarge
+org.openjdk.tests.java.util.stream.SortedOpTest#testSequentialShortCircuitTerminal
+org.openjdk.tests.java.util.stream.SortedOpTest#testSortSort
+org.openjdk.tests.java.util.stream.SortedOpTest#testSorted
+org.openjdk.tests.java.util.stream.SpliteratorTest#testDoubleSpliterator
+org.openjdk.tests.java.util.stream.SpliteratorTest#testIntSpliterator
+org.openjdk.tests.java.util.stream.SpliteratorTest#testLongSpliterator
+org.openjdk.tests.java.util.stream.SpliteratorTest#testSpliterator
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testAfterBuilding
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testDoubleAfterBuilding
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testDoubleSingleton
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testDoubleStreamBuilder
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testIntAfterBuilding
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testIntSingleton
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testIntStreamBuilder
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testLongAfterBuilding
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testLongSingleton
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testLongStreamBuilder
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testSingleton
+org.openjdk.tests.java.util.stream.StreamBuilderTest#testStreamBuilder
+org.openjdk.tests.java.util.stream.StreamCloseTest#testCascadedExceptions
+org.openjdk.tests.java.util.stream.StreamCloseTest#testEmptyCloseHandler
+org.openjdk.tests.java.util.stream.StreamCloseTest#testOneCloseHandler
+org.openjdk.tests.java.util.stream.StreamCloseTest#testTwoCloseHandlers
+org.openjdk.tests.java.util.stream.StreamLinkTest#testDoubleManyStreams
+org.openjdk.tests.java.util.stream.StreamLinkTest#testIntManyStreams
+org.openjdk.tests.java.util.stream.StreamLinkTest#testLongManyStreams
+org.openjdk.tests.java.util.stream.StreamLinkTest#testManyStreams
+org.openjdk.tests.java.util.stream.StreamParSeqTest#testParSeq
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleParSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleSplitting
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleStreamSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntParSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntSplitting
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntStreamSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongParSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongSplitting
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongStreamSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testParSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testSpliterators
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testSplitting
+org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testStreamSpliterators
+org.openjdk.tests.java.util.stream.SummaryStatisticsTest#testDoubleStatistics
+org.openjdk.tests.java.util.stream.SummaryStatisticsTest#testIntStatistics
+org.openjdk.tests.java.util.stream.SummaryStatisticsTest#testLongStatistics
+org.openjdk.tests.java.util.stream.TabulatorsTest#testComposeFinisher
+org.openjdk.tests.java.util.stream.TabulatorsTest#testGroupedReduce
+org.openjdk.tests.java.util.stream.TabulatorsTest#testJoin
+org.openjdk.tests.java.util.stream.TabulatorsTest#testReduce
+org.openjdk.tests.java.util.stream.TabulatorsTest#testSimpleGroupBy
+org.openjdk.tests.java.util.stream.TabulatorsTest#testSimplePartition
+org.openjdk.tests.java.util.stream.TabulatorsTest#testSimpleToMap
+org.openjdk.tests.java.util.stream.TabulatorsTest#testTwoLevelGroupBy
+org.openjdk.tests.java.util.stream.TabulatorsTest#testTwoLevelPartition
+org.openjdk.tests.java.util.stream.TeeOpTest#testDoubleOps
+org.openjdk.tests.java.util.stream.TeeOpTest#testIntOps
+org.openjdk.tests.java.util.stream.TeeOpTest#testLongOps
+org.openjdk.tests.java.util.stream.TeeOpTest#testOps
+org.openjdk.tests.java.util.stream.TeeOpTest#testTee
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testAsArrayWithType
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDistinctAndSortedPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleDistinctAndSortedPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOps
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithFilter
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithFlatMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithSorted
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleStatefulOpPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntDistinctAndSortedPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOps
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithFilter
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithFlatMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithSorted
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntStatefulOpPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongDistinctAndSortedPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOps
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithFilter
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithFlatMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithSorted
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongStatefulOpPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testOps
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithFilter
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithFlatMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithMap
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithSorted
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testStatefulOpPermutations
+org.openjdk.tests.java.util.stream.ToArrayOpTest#testToArray
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestNGDeviceTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestNGDeviceTest.java
new file mode 100644
index 0000000..377c0c0
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestNGDeviceTest.java
@@ -0,0 +1,231 @@
+/*
+ * 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 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.IAbi;
+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 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;
+
+/**
+ * {@code Test} for running CTS TestNG tests on the device.
+ */
+public class TestNGDeviceTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
+
+    private static final String TMP_DIR = "/data/local/tmp/";
+
+    @Option(name = "testng-device-runtime",
+            description = "The name of the runtime to use on the device",
+            importance = Importance.ALWAYS)
+    private String mRuntimePath = "dalvikvm|#ABI#|";
+
+    @Option(name = "testng-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 IAbi mAbi;
+
+    private static final String TESTNG_JAR = "cts-testng.jar";
+
+    private Set<String> mTestJars = new HashSet<String>(Arrays.asList(TESTNG_JAR));
+
+    /**
+     * @param abi The ABI to run the test on
+     */
+    public void setAbi(IAbi abi) {
+        mAbi = abi;
+    }
+
+    @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(TESTNG_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.testng.SingleTestNGTestRunner %s#%s",
+                        mDeviceTestTmpPath, mRuntimePath, jarPath, getRuntimeArgsNotNull(),
+                        testId.getClassName(), testId.getTestName());
+                String cmd = AbiFormatter.formatCmdForAbi(cmdLine, mAbi.getBitness());
+                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);
+                if (!result) {
+                    throw new AssertionError(String.format("Failed to push file to %s", fullJarPath));
+                }
+                mJarPaths.add(fullJarPath);
+            } catch (FileNotFoundException e) {
+                throw new AssertionError(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;
+    }
+
+    private String getRuntimeArgsNotNull() {
+      if (mRuntimeArgs == null) {
+        return "";
+      }
+      return mRuntimeArgs;
+    }
+}
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 d08c0bc..974033d 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
@@ -56,6 +56,7 @@
     public static final String DEQP_TEST = "deqpTest";
     public static final String UIAUTOMATOR_TEST = "uiAutomator";
     public static final String JUNIT_DEVICE_TEST = "jUnitDeviceTest";
+    public static final String TESTNG_DEVICE_TEST = "testNGDeviceTest";
 
     private String mAppPackageName = null;
     private String mAppNameSpace = null;
@@ -296,7 +297,18 @@
             jUnitDeviceTest.setAbi(mAbi);
             mDigest = generateDigest(testCaseDir, mJarPath);
             return jUnitDeviceTest;
-        } else {
+        } else if (TESTNG_DEVICE_TEST.equals(mTestType)){
+            CLog.d("Creating TestNG device test %s", mName);
+            TestNGDeviceTest testNGDeviceTest = new TestNGDeviceTest();
+            testNGDeviceTest.setRunName(getId());
+            testNGDeviceTest.addTestJarFileName(mJarPath);
+            testNGDeviceTest.addRunTimeArgs(mRunTimeArgs);
+            testNGDeviceTest.setTests(mTests);
+            testNGDeviceTest.setAbi(mAbi);
+            mDigest = generateDigest(testCaseDir, mJarPath);
+            return testNGDeviceTest;
+        }
+        else {
             CLog.d("Creating instrumentation test for %s", mName);
             CtsInstrumentationApkTest instrTest = new CtsInstrumentationApkTest();
             if (mTimeoutInMins >= 0) {