diff options
10 files changed, 319 insertions, 0 deletions
diff --git a/config/TEST_MAPPING b/config/TEST_MAPPING new file mode 100644 index 000000000000..d09805ec08b6 --- /dev/null +++ b/config/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "PreloadCheck" + } + ] +} diff --git a/tools/preload-check/Android.bp b/tools/preload-check/Android.bp new file mode 100644 index 000000000000..c84567b704a6 --- /dev/null +++ b/tools/preload-check/Android.bp @@ -0,0 +1,21 @@ +// Copyright (C) 2019 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. + +java_test_host { + name: "PreloadCheck", + srcs: ["src/**/*.java"], + libs: ["tradefed"], + test_suites: ["general-tests"], + required: ["preload-check-device"], +} diff --git a/tools/preload-check/AndroidTest.xml b/tools/preload-check/AndroidTest.xml new file mode 100644 index 000000000000..a0645d5b1051 --- /dev/null +++ b/tools/preload-check/AndroidTest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2019 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="Config for PreloadCheck"> + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="cleanup" value="true" /> + <option name="push" value="preload-check-device.jar->/data/local/tmp/preload-check-device.jar" /> + </target_preparer> + <test class="com.android.tradefed.testtype.HostTest" > + <option name="class" value="com.android.preload.check.PreloadCheck" /> + </test> +</configuration> diff --git a/tools/preload-check/TEST_MAPPING b/tools/preload-check/TEST_MAPPING new file mode 100644 index 000000000000..d09805ec08b6 --- /dev/null +++ b/tools/preload-check/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "PreloadCheck" + } + ] +} diff --git a/tools/preload-check/device/Android.bp b/tools/preload-check/device/Android.bp new file mode 100644 index 000000000000..7782b0d378ae --- /dev/null +++ b/tools/preload-check/device/Android.bp @@ -0,0 +1,27 @@ +// Copyright (C) 2019 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. + +java_test_helper_library { + name: "preload-check-device", + host_supported: false, + device_supported: true, + compile_dex: true, + + sdk_version: "current", + srcs: ["src/**/*.java"], + test_suites: ["general-tests"], + dex_preopt: { + enabled: false, + }, +} diff --git a/tools/preload-check/device/src/com/android/preload/check/Initialized.java b/tools/preload-check/device/src/com/android/preload/check/Initialized.java new file mode 100644 index 000000000000..b21b5f6e024e --- /dev/null +++ b/tools/preload-check/device/src/com/android/preload/check/Initialized.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2019 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.preload.check; + +public class Initialized { + public static void main(String[] args) throws Exception { + Util.assertInitialized(args[0], null); + System.out.println("OK"); + } +} diff --git a/tools/preload-check/device/src/com/android/preload/check/IntegrityCheck.java b/tools/preload-check/device/src/com/android/preload/check/IntegrityCheck.java new file mode 100644 index 000000000000..6cc3946d5be6 --- /dev/null +++ b/tools/preload-check/device/src/com/android/preload/check/IntegrityCheck.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 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.preload.check; + +public class IntegrityCheck { + public static void main(String[] args) throws Exception { + ClassLoader loader = IntegrityCheck.class.getClassLoader(); + + Util.assertNotInitialized("com.android.preload.check.IntegrityCheck$StatusHelper", loader); + + Class<?> klass = Class.forName("com.android.preload.check.IntegrityCheck$StatusHelper", + /* initialize */ true, loader); + + Util.assertInitialized("com.android.preload.check.IntegrityCheck$StatusHelper", loader); + + System.out.println("OK"); + } + + private static class StatusHelper { + private final static Object defer = new Object(); + } +} diff --git a/tools/preload-check/device/src/com/android/preload/check/NotInitialized.java b/tools/preload-check/device/src/com/android/preload/check/NotInitialized.java new file mode 100644 index 000000000000..d2e98fe205a2 --- /dev/null +++ b/tools/preload-check/device/src/com/android/preload/check/NotInitialized.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2019 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.preload.check; + +public class NotInitialized { + public static void main(String[] args) throws Exception { + Util.assertNotInitialized(args[0], null); + System.out.println("OK"); + } +} diff --git a/tools/preload-check/device/src/com/android/preload/check/Util.java b/tools/preload-check/device/src/com/android/preload/check/Util.java new file mode 100644 index 000000000000..662f67ac0bd6 --- /dev/null +++ b/tools/preload-check/device/src/com/android/preload/check/Util.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 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.preload.check; + +import java.lang.reflect.Field; + +public class Util { + private static Field statusField; + + static { + try { + Class<?> klass = Class.class; + statusField = klass.getDeclaredField("status"); + statusField.setAccessible(true); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + public static boolean isInitialized(Class<?> klass) throws Exception { + Object val = statusField.get(klass); + if (val == null || !(val instanceof Integer)) { + throw new IllegalStateException(String.valueOf(val)); + } + int intVal = (int)val; + intVal = (intVal >> (32-4)) & 0xf; + return intVal >= 14; + } + + public static void assertTrue(boolean val, String msg) { + if (!val) { + throw new RuntimeException(msg); + } + } + + public static void assertInitializedState(String className, boolean expected, + ClassLoader loader) { + boolean initialized; + try { + Class<?> klass = Class.forName(className, /* initialize */ false, loader); + initialized = isInitialized(klass); + } catch (Throwable t) { + throw new RuntimeException(t); + } + assertTrue(expected == initialized, className); + } + + public static void assertNotInitialized(String className, ClassLoader loader) { + assertInitializedState(className, false, loader); + } + + public static void assertInitialized(String className, ClassLoader loader) { + assertInitializedState(className, true, loader); + } +} diff --git a/tools/preload-check/src/com/android/preload/check/PreloadCheck.java b/tools/preload-check/src/com/android/preload/check/PreloadCheck.java new file mode 100644 index 000000000000..dbdecdbecd12 --- /dev/null +++ b/tools/preload-check/src/com/android/preload/check/PreloadCheck.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 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.preload.check; + +import static org.junit.Assert.assertEquals; + +import com.android.tradefed.device.ITestDevice; +import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; +import com.android.tradefed.testtype.IDeviceTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(DeviceJUnit4ClassRunner.class) +public class PreloadCheck implements IDeviceTest { + private ITestDevice mTestDevice; + + private static final String TEST_CLASSPATH = "/data/local/tmp/preload-check-device.jar"; + + @Override + public void setDevice(ITestDevice testDevice) { + mTestDevice = testDevice; + } + + @Override + public ITestDevice getDevice() { + return mTestDevice; + } + + /** + * Test that checks work as expected. + */ + @Test + public void testStatus() throws Exception { + run("com.android.preload.check.IntegrityCheck"); + } + + /** + * b/130206915. + */ + @Test + public void testAsyncTask() throws Exception { + run("com.android.preload.check.NotInitialized", "android.os.AsyncTask"); + } + + /** + * Just a check for something we expect to see initialized. + */ + @Test + public void testAnimator() throws Exception { + run("com.android.preload.check.Initialized", "android.animation.Animator"); + } + + private void run(String cmd, String... args) throws Exception { + StringBuilder sb = new StringBuilder(); + sb.append("app_process ") + .append("-cp ").append(TEST_CLASSPATH) + .append(" /system/bin ") + .append(cmd); + for (String arg : args) { + sb.append(' ').append(arg); + } + String res = mTestDevice.executeShellCommand(sb.toString()); + assertEquals(sb.toString(), "OK", res.trim()); + } +} |