summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/129-ThreadGetId/src/Main.java4
-rwxr-xr-xtest/925-threadgroups/build17
-rw-r--r--test/925-threadgroups/expected.txt16
-rw-r--r--test/925-threadgroups/info.txt1
-rwxr-xr-xtest/925-threadgroups/run19
-rw-r--r--test/925-threadgroups/src/Main.java113
-rw-r--r--test/925-threadgroups/threadgroups.cc127
-rwxr-xr-xtest/928-jni-table/build17
-rw-r--r--test/928-jni-table/expected.txt1
-rw-r--r--test/928-jni-table/info.txt1
-rw-r--r--test/928-jni-table/jni_table.cc89
-rwxr-xr-xtest/928-jni-table/run19
-rw-r--r--test/928-jni-table/src/Main.java27
-rwxr-xr-xtest/929-search/build17
-rw-r--r--test/929-search/expected.txt1
-rw-r--r--test/929-search/info.txt1
-rwxr-xr-xtest/929-search/run23
-rw-r--r--test/929-search/search.cc53
-rw-r--r--test/929-search/src-ex/A.java18
-rw-r--r--test/929-search/src/B.java18
-rw-r--r--test/929-search/src/Main.java54
-rw-r--r--test/Android.bp3
-rw-r--r--test/Android.run-test.mk8
23 files changed, 645 insertions, 2 deletions
diff --git a/test/129-ThreadGetId/src/Main.java b/test/129-ThreadGetId/src/Main.java
index 6ba01ff0b5..4e48e0e1a6 100644
--- a/test/129-ThreadGetId/src/Main.java
+++ b/test/129-ThreadGetId/src/Main.java
@@ -23,7 +23,6 @@ public class Main implements Runnable {
public static void main(String[] args) throws Exception {
final Thread[] threads = new Thread[numberOfThreads];
- test_getStackTraces();
for (int t = 0; t < threads.length; t++) {
threads[t] = new Thread(new Main());
threads[t].start();
@@ -31,6 +30,9 @@ public class Main implements Runnable {
for (Thread t : threads) {
t.join();
}
+ // Do this test after the other part to leave some time for the heap task daemon to start
+ // up.
+ test_getStackTraces();
System.out.println("Finishing");
}
diff --git a/test/925-threadgroups/build b/test/925-threadgroups/build
new file mode 100755
index 0000000000..898e2e54a2
--- /dev/null
+++ b/test/925-threadgroups/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+./default-build "$@" --experimental agents
diff --git a/test/925-threadgroups/expected.txt b/test/925-threadgroups/expected.txt
new file mode 100644
index 0000000000..7d1a259c89
--- /dev/null
+++ b/test/925-threadgroups/expected.txt
@@ -0,0 +1,16 @@
+java.lang.ThreadGroup[name=main,maxpri=10]
+ java.lang.ThreadGroup[name=system,maxpri=10]
+ main
+ 10
+ false
+java.lang.ThreadGroup[name=system,maxpri=10]
+ null
+ system
+ 10
+ false
+main:
+ [Thread[main,5,main]]
+ []
+system:
+ [Thread[FinalizerDaemon,5,system], Thread[FinalizerWatchdogDaemon,5,system], Thread[HeapTaskDaemon,5,system], Thread[ReferenceQueueDaemon,5,system], Thread[Signal Catcher,5,system]]
+ [java.lang.ThreadGroup[name=main,maxpri=10]]
diff --git a/test/925-threadgroups/info.txt b/test/925-threadgroups/info.txt
new file mode 100644
index 0000000000..875a5f6ec1
--- /dev/null
+++ b/test/925-threadgroups/info.txt
@@ -0,0 +1 @@
+Tests basic functions in the jvmti plugin.
diff --git a/test/925-threadgroups/run b/test/925-threadgroups/run
new file mode 100755
index 0000000000..4379349cb2
--- /dev/null
+++ b/test/925-threadgroups/run
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+./default-run "$@" --experimental agents \
+ --experimental runtime-plugins \
+ --jvmti
diff --git a/test/925-threadgroups/src/Main.java b/test/925-threadgroups/src/Main.java
new file mode 100644
index 0000000000..c59efe2f7b
--- /dev/null
+++ b/test/925-threadgroups/src/Main.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[1]);
+
+ doTest();
+ }
+
+ private static void doTest() throws Exception {
+ Thread t1 = Thread.currentThread();
+ ThreadGroup curGroup = t1.getThreadGroup();
+
+ ThreadGroup rootGroup = curGroup;
+ while (rootGroup.getParent() != null) {
+ rootGroup = rootGroup.getParent();
+ }
+
+ ThreadGroup topGroups[] = getTopThreadGroups();
+ if (topGroups == null || topGroups.length != 1 || topGroups[0] != rootGroup) {
+ System.out.println(Arrays.toString(topGroups));
+ throw new RuntimeException("Unexpected topGroups");
+ }
+
+ printThreadGroupInfo(curGroup);
+ printThreadGroupInfo(rootGroup);
+
+ waitGroupChildren(rootGroup, 5 /* # daemons */, 30 /* timeout in seconds */);
+
+ checkChildren(curGroup);
+ }
+
+ private static void printThreadGroupInfo(ThreadGroup tg) {
+ Object[] threadGroupInfo = getThreadGroupInfo(tg);
+ if (threadGroupInfo == null || threadGroupInfo.length != 4) {
+ System.out.println(Arrays.toString(threadGroupInfo));
+ throw new RuntimeException("threadGroupInfo length wrong");
+ }
+
+ System.out.println(tg);
+ System.out.println(" " + threadGroupInfo[0]); // Parent
+ System.out.println(" " + threadGroupInfo[1]); // Name
+ System.out.println(" " + threadGroupInfo[2]); // Priority
+ System.out.println(" " + threadGroupInfo[3]); // Daemon
+ }
+
+ private static void checkChildren(ThreadGroup tg) {
+ Object[] data = getThreadGroupChildren(tg);
+ Thread[] threads = (Thread[])data[0];
+ ThreadGroup[] groups = (ThreadGroup[])data[1];
+
+ Arrays.sort(threads, THREAD_COMP);
+ Arrays.sort(groups, THREADGROUP_COMP);
+ System.out.println(tg.getName() + ":");
+ System.out.println(" " + Arrays.toString(threads));
+ System.out.println(" " + Arrays.toString(groups));
+
+ if (tg.getParent() != null) {
+ checkChildren(tg.getParent());
+ }
+ }
+
+ private static void waitGroupChildren(ThreadGroup tg, int expectedChildCount, int timeoutS)
+ throws Exception {
+ for (int i = 0; i < timeoutS; i++) {
+ Object[] data = getThreadGroupChildren(tg);
+ Thread[] threads = (Thread[])data[0];
+ if (threads.length == expectedChildCount) {
+ return;
+ }
+ Thread.sleep(1000);
+ }
+
+ Object[] data = getThreadGroupChildren(tg);
+ Thread[] threads = (Thread[])data[0];
+ System.out.println(Arrays.toString(threads));
+ throw new RuntimeException("Waited unsuccessfully for " + expectedChildCount + " children.");
+ }
+
+ private final static Comparator<Thread> THREAD_COMP = new Comparator<Thread>() {
+ public int compare(Thread o1, Thread o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private final static Comparator<ThreadGroup> THREADGROUP_COMP = new Comparator<ThreadGroup>() {
+ public int compare(ThreadGroup o1, ThreadGroup o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
+
+ private static native ThreadGroup[] getTopThreadGroups();
+ private static native Object[] getThreadGroupInfo(ThreadGroup tg);
+ // Returns an array where element 0 is an array of threads and element 1 is an array of groups.
+ private static native Object[] getThreadGroupChildren(ThreadGroup tg);
+}
diff --git a/test/925-threadgroups/threadgroups.cc b/test/925-threadgroups/threadgroups.cc
new file mode 100644
index 0000000000..6c6e835dd3
--- /dev/null
+++ b/test/925-threadgroups/threadgroups.cc
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include <stdio.h>
+
+#include "android-base/stringprintf.h"
+#include "base/macros.h"
+#include "base/logging.h"
+#include "jni.h"
+#include "openjdkjvmti/jvmti.h"
+#include "ScopedLocalRef.h"
+
+#include "ti-agent/common_helper.h"
+#include "ti-agent/common_load.h"
+
+namespace art {
+namespace Test925ThreadGroups {
+
+// private static native Object[] getThreadGroupInfo();
+// // Returns an array where element 0 is an array of threads and element 1 is an array of groups.
+// private static native Object[] getThreadGroupChildren();
+
+extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getTopThreadGroups(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+ jthreadGroup* groups;
+ jint group_count;
+ jvmtiError result = jvmti_env->GetTopThreadGroups(&group_count, &groups);
+ if (JvmtiErrorToException(env, result)) {
+ return nullptr;
+ }
+
+ auto callback = [&](jint index) -> jobject {
+ return groups[index];
+ };
+ jobjectArray ret = CreateObjectArray(env, group_count, "java/lang/ThreadGroup", callback);
+
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(groups));
+
+ return ret;
+}
+
+extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getThreadGroupInfo(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jthreadGroup group) {
+ jvmtiThreadGroupInfo info;
+ jvmtiError result = jvmti_env->GetThreadGroupInfo(group, &info);
+ if (JvmtiErrorToException(env, result)) {
+ return nullptr;
+ }
+
+ auto callback = [&](jint index) -> jobject {
+ switch (index) {
+ // The parent.
+ case 0:
+ return info.parent;
+
+ // The name.
+ case 1:
+ return (info.name == nullptr) ? nullptr : env->NewStringUTF(info.name);
+
+ // The priority. Use a string for simplicity of construction.
+ case 2:
+ return env->NewStringUTF(android::base::StringPrintf("%d", info.max_priority).c_str());
+
+ // Whether it's a daemon. Use a string for simplicity of construction.
+ case 3:
+ return env->NewStringUTF(info.is_daemon == JNI_TRUE ? "true" : "false");
+ }
+ LOG(FATAL) << "Should not reach here";
+ UNREACHABLE();
+ };
+ return CreateObjectArray(env, 4, "java/lang/Object", callback);
+}
+
+extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getThreadGroupChildren(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jthreadGroup group) {
+ jint thread_count;
+ jthread* threads;
+ jint threadgroup_count;
+ jthreadGroup* groups;
+
+ jvmtiError result = jvmti_env->GetThreadGroupChildren(group,
+ &thread_count,
+ &threads,
+ &threadgroup_count,
+ &groups);
+ if (JvmtiErrorToException(env, result)) {
+ return nullptr;
+ }
+
+ auto callback = [&](jint component_index) -> jobject {
+ if (component_index == 0) {
+ // Threads.
+ auto inner_callback = [&](jint index) {
+ return threads[index];
+ };
+ return CreateObjectArray(env, thread_count, "java/lang/Thread", inner_callback);
+ } else {
+ // Groups.
+ auto inner_callback = [&](jint index) {
+ return groups[index];
+ };
+ return CreateObjectArray(env, threadgroup_count, "java/lang/ThreadGroup", inner_callback);
+ }
+ };
+ jobjectArray ret = CreateObjectArray(env, 2, "java/lang/Object", callback);
+
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(threads));
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(groups));
+
+ return ret;
+}
+
+} // namespace Test925ThreadGroups
+} // namespace art
diff --git a/test/928-jni-table/build b/test/928-jni-table/build
new file mode 100755
index 0000000000..898e2e54a2
--- /dev/null
+++ b/test/928-jni-table/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+./default-build "$@" --experimental agents
diff --git a/test/928-jni-table/expected.txt b/test/928-jni-table/expected.txt
new file mode 100644
index 0000000000..a965a70ed4
--- /dev/null
+++ b/test/928-jni-table/expected.txt
@@ -0,0 +1 @@
+Done
diff --git a/test/928-jni-table/info.txt b/test/928-jni-table/info.txt
new file mode 100644
index 0000000000..875a5f6ec1
--- /dev/null
+++ b/test/928-jni-table/info.txt
@@ -0,0 +1 @@
+Tests basic functions in the jvmti plugin.
diff --git a/test/928-jni-table/jni_table.cc b/test/928-jni-table/jni_table.cc
new file mode 100644
index 0000000000..5123d3a43f
--- /dev/null
+++ b/test/928-jni-table/jni_table.cc
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <stdio.h>
+
+#include "jni.h"
+#include "openjdkjvmti/jvmti.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+
+#include "ti-agent/common_helper.h"
+#include "ti-agent/common_load.h"
+
+namespace art {
+namespace Test927JNITable {
+
+// This test is equivalent to the jni_internal_test JNIEnvExtTableOverride.
+
+static size_t gGlobalRefCount = 0;
+static JNINativeInterface* gOriginalEnv = nullptr;
+
+static jobject CountNewGlobalRef(JNIEnv* env, jobject o) {
+ ++gGlobalRefCount;
+ return gOriginalEnv->NewGlobalRef(env, o);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_doJNITableTest(
+ JNIEnv* env, jclass klass) {
+ // Get the current table, as the delegate.
+ jvmtiError getorig_result = jvmti_env->GetJNIFunctionTable(&gOriginalEnv);
+ if (JvmtiErrorToException(env, getorig_result)) {
+ return;
+ }
+
+ // Get the current table, as the override we'll install.
+ JNINativeInterface* env_override;
+ jvmtiError getoverride_result = jvmti_env->GetJNIFunctionTable(&env_override);
+ if (JvmtiErrorToException(env, getoverride_result)) {
+ return;
+ }
+
+ env_override->NewGlobalRef = CountNewGlobalRef;
+ gGlobalRefCount = 0;
+
+ // Install the override.
+ jvmtiError setoverride_result = jvmti_env->SetJNIFunctionTable(env_override);
+ if (JvmtiErrorToException(env, setoverride_result)) {
+ return;
+ }
+
+ jobject global = env->NewGlobalRef(klass);
+ CHECK_EQ(1u, gGlobalRefCount);
+ env->DeleteGlobalRef(global);
+
+ // Install the "original." There is no real reset.
+ jvmtiError setoverride2_result = jvmti_env->SetJNIFunctionTable(gOriginalEnv);
+ if (JvmtiErrorToException(env, setoverride2_result)) {
+ return;
+ }
+
+ jobject global2 = env->NewGlobalRef(klass);
+ CHECK_EQ(1u, gGlobalRefCount);
+ env->DeleteGlobalRef(global2);
+
+ // Try to install null. Should return NULL_POINTER error.
+ jvmtiError setoverride3_result = jvmti_env->SetJNIFunctionTable(nullptr);
+ if (setoverride3_result != JVMTI_ERROR_NULL_POINTER) {
+ LOG(FATAL) << "Didn't receive NULL_POINTER";
+ }
+
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(env_override));
+}
+
+} // namespace Test927JNITable
+} // namespace art
diff --git a/test/928-jni-table/run b/test/928-jni-table/run
new file mode 100755
index 0000000000..4379349cb2
--- /dev/null
+++ b/test/928-jni-table/run
@@ -0,0 +1,19 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+./default-run "$@" --experimental agents \
+ --experimental runtime-plugins \
+ --jvmti
diff --git a/test/928-jni-table/src/Main.java b/test/928-jni-table/src/Main.java
new file mode 100644
index 0000000000..b0baea1f9d
--- /dev/null
+++ b/test/928-jni-table/src/Main.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[1]);
+
+ doJNITableTest();
+
+ System.out.println("Done");
+ }
+
+ public static native void doJNITableTest();
+}
diff --git a/test/929-search/build b/test/929-search/build
new file mode 100755
index 0000000000..898e2e54a2
--- /dev/null
+++ b/test/929-search/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+./default-build "$@" --experimental agents
diff --git a/test/929-search/expected.txt b/test/929-search/expected.txt
new file mode 100644
index 0000000000..a965a70ed4
--- /dev/null
+++ b/test/929-search/expected.txt
@@ -0,0 +1 @@
+Done
diff --git a/test/929-search/info.txt b/test/929-search/info.txt
new file mode 100644
index 0000000000..875a5f6ec1
--- /dev/null
+++ b/test/929-search/info.txt
@@ -0,0 +1 @@
+Tests basic functions in the jvmti plugin.
diff --git a/test/929-search/run b/test/929-search/run
new file mode 100755
index 0000000000..0a8d0672f6
--- /dev/null
+++ b/test/929-search/run
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Copyright 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.
+
+# This test checks whether dex files can be injected into parent classloaders. App images preload
+# classes, which will make the injection moot. Turn off app images to avoid the issue.
+
+./default-run "$@" --experimental agents \
+ --experimental runtime-plugins \
+ --jvmti \
+ --no-app-image
diff --git a/test/929-search/search.cc b/test/929-search/search.cc
new file mode 100644
index 0000000000..d1c698491e
--- /dev/null
+++ b/test/929-search/search.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include <inttypes.h>
+
+#include "android-base/stringprintf.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "jni.h"
+#include "openjdkjvmti/jvmti.h"
+#include "ScopedUtfChars.h"
+
+#include "ti-agent/common_helper.h"
+#include "ti-agent/common_load.h"
+
+namespace art {
+namespace Test929Search {
+
+extern "C" JNIEXPORT void JNICALL Java_Main_addToBootClassLoader(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jstring segment) {
+ ScopedUtfChars utf(env, segment);
+ if (utf.c_str() == nullptr) {
+ return;
+ }
+ jvmtiError result = jvmti_env->AddToBootstrapClassLoaderSearch(utf.c_str());
+ JvmtiErrorToException(env, result);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_addToSystemClassLoader(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jstring segment) {
+ ScopedUtfChars utf(env, segment);
+ if (utf.c_str() == nullptr) {
+ return;
+ }
+ jvmtiError result = jvmti_env->AddToSystemClassLoaderSearch(utf.c_str());
+ JvmtiErrorToException(env, result);
+}
+
+} // namespace Test929Search
+} // namespace art
diff --git a/test/929-search/src-ex/A.java b/test/929-search/src-ex/A.java
new file mode 100644
index 0000000000..64acb2fcfe
--- /dev/null
+++ b/test/929-search/src-ex/A.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+public class A {
+} \ No newline at end of file
diff --git a/test/929-search/src/B.java b/test/929-search/src/B.java
new file mode 100644
index 0000000000..f1458c3bca
--- /dev/null
+++ b/test/929-search/src/B.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+public class B {
+} \ No newline at end of file
diff --git a/test/929-search/src/Main.java b/test/929-search/src/Main.java
new file mode 100644
index 0000000000..d253e6fdf6
--- /dev/null
+++ b/test/929-search/src/Main.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+import java.util.Arrays;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[1]);
+
+ doTest();
+ }
+
+ private static void doTest() throws Exception {
+ doTest(true, DEX1, "B");
+ doTest(false, DEX2, "A");
+ System.out.println("Done");
+ }
+
+ private static void doTest(boolean boot, String segment, String className) throws Exception {
+ ClassLoader expectedClassLoader;
+ if (boot) {
+ expectedClassLoader = Object.class.getClassLoader();
+ addToBootClassLoader(segment);
+ } else {
+ expectedClassLoader = ClassLoader.getSystemClassLoader();
+ addToSystemClassLoader(segment);
+ }
+
+ Class<?> c = Class.forName(className);
+ if (c.getClassLoader() != expectedClassLoader) {
+ throw new RuntimeException(className + "(" + boot + "/" + segment + "): " +
+ c.getClassLoader() + " vs " + expectedClassLoader);
+ }
+ }
+
+ private static native void addToBootClassLoader(String s);
+ private static native void addToSystemClassLoader(String s);
+
+ private static final String DEX1 = System.getenv("DEX_LOCATION") + "/929-search.jar";
+ private static final String DEX2 = System.getenv("DEX_LOCATION") + "/929-search-ex.jar";
+}
diff --git a/test/Android.bp b/test/Android.bp
index 1ea1252893..965d07aa43 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -265,7 +265,10 @@ art_cc_defaults {
"922-properties/properties.cc",
"923-monitors/monitors.cc",
"924-threads/threads.cc",
+ "925-threadgroups/threadgroups.cc",
"927-timers/timers.cc",
+ "928-jni-table/jni_table.cc",
+ "929-search/search.cc",
],
shared_libs: [
"libbase",
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 55cef974ab..e604c93c72 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -280,6 +280,7 @@ TEST_ART_BROKEN_TARGET_TESTS := \
# These 9** tests are not supported in current form due to linker
# restrictions. See b/31681198
TEST_ART_BROKEN_TARGET_TESTS += \
+ 901-hello-ti-agent \
902-hello-transformation \
903-hello-tagging \
904-object-allocation \
@@ -303,8 +304,11 @@ TEST_ART_BROKEN_TARGET_TESTS += \
922-properties \
923-monitors \
924-threads \
+ 925-threadgroups \
926-multi-obsolescence \
927-timers \
+ 928-jni-table \
+ 929-search \
ifneq (,$(filter target,$(TARGET_TYPES)))
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
@@ -465,10 +469,12 @@ TEST_ART_BROKEN_FALLBACK_RUN_TESTS := \
629-vdex-speed
# This test fails without an image.
-# 964 often times out due to the large number of classes it tries to compile.
+# 018, 961, 964 often time out. b/34369284
TEST_ART_BROKEN_NO_IMAGE_RUN_TESTS := \
137-cfi \
138-duplicate-classes-check \
+ 018-stack-overflow \
+ 961-default-iface-resolution-gen \
964-default-iface-init
ifneq (,$(filter no-dex2oat,$(PREBUILD_TYPES)))