Regression test ensuring unresolved classes are not put in dex cache.

Bug: 26792072

(cherry-picked from commit 2bf56594e78ab7b01ee85c1d885c92cb469dfdf2)

Change-Id: I4e9f4ab0b8ff215c39d854ee041c1acfedcf0b6d
diff --git a/test/144-static-field-sigquit/expected.txt b/test/144-static-field-sigquit/expected.txt
new file mode 100644
index 0000000..e0c3e90
--- /dev/null
+++ b/test/144-static-field-sigquit/expected.txt
@@ -0,0 +1,4 @@
+Starting threads...
+Performing sigquits for 5 seconds
+Got date field
+Joined threads
diff --git a/test/144-static-field-sigquit/info.txt b/test/144-static-field-sigquit/info.txt
new file mode 100644
index 0000000..5dcfc76
--- /dev/null
+++ b/test/144-static-field-sigquit/info.txt
@@ -0,0 +1,8 @@
+Regression test for ag/853775
+
+Tests that unresolved classes are not put into the dex cache by the verifier.
+This was potentially happening when receiving a signal while in the static
+initilizer of a class and also within a synchronized block.
+
+This test is flaky and produces the issue rarely, but it should be good enough
+to trigger occasionally with the buildbots.
diff --git a/test/144-static-field-sigquit/src/ClassWithStaticField.java b/test/144-static-field-sigquit/src/ClassWithStaticField.java
new file mode 100644
index 0000000..0b2c855
--- /dev/null
+++ b/test/144-static-field-sigquit/src/ClassWithStaticField.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+import java.util.Date;
+
+public class ClassWithStaticField {
+    public static Date mDate = new Date();
+}
diff --git a/test/144-static-field-sigquit/src/Main.java b/test/144-static-field-sigquit/src/Main.java
new file mode 100644
index 0000000..ab94da3
--- /dev/null
+++ b/test/144-static-field-sigquit/src/Main.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+public class Main {
+
+    public static void main(String[] args) throws Exception {
+        Thread thread1 = new Thread(new SigQuit());
+        Thread thread2 = new Thread(new SynchronizedUse());
+
+        System.out.println("Starting threads...");
+        thread1.start();
+        Thread.sleep(2000);
+        thread2.start();
+
+        thread1.join();
+        thread2.join();
+        System.out.println("Joined threads");
+    }
+}
diff --git a/test/144-static-field-sigquit/src/SigQuit.java b/test/144-static-field-sigquit/src/SigQuit.java
new file mode 100644
index 0000000..bed23e4
--- /dev/null
+++ b/test/144-static-field-sigquit/src/SigQuit.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+import java.lang.reflect.*;
+
+public class SigQuit implements Runnable {
+    private final static int sigquit;
+    private final static Method kill;
+    private final static int pid;
+
+    static {
+        int pidTemp = -1;
+        int sigquitTemp = -1;
+        Method killTemp = null;
+
+        try {
+            Class<?> osClass = Class.forName("android.system.Os");
+            Method getpid = osClass.getDeclaredMethod("getpid");
+            pidTemp = (Integer) getpid.invoke(null);
+
+            Class<?> osConstants = Class.forName("android.system.OsConstants");
+            Field sigquitField = osConstants.getDeclaredField("SIGQUIT");
+            sigquitTemp = (Integer) sigquitField.get(null);
+
+            killTemp = osClass.getDeclaredMethod("kill", int.class, int.class);
+        } catch (Exception e) {
+            if (!e.getClass().getName().equals("ErrnoException")) {
+                e.printStackTrace(System.out);
+            }
+        }
+
+        pid = pidTemp;
+        sigquit = sigquitTemp;
+        kill = killTemp;
+    }
+
+    public boolean perform() {
+        try {
+            kill.invoke(null, pid, sigquit);
+        } catch (Exception e) {
+            if (!e.getClass().getName().equals("ErrnoException")) {
+                e.printStackTrace(System.out);
+            }
+        }
+        return true;
+    }
+
+    public void run() {
+        long endTime = System.currentTimeMillis() + 5000;
+        System.out.println("Performing sigquits for 5 seconds");
+        while (System.currentTimeMillis() < endTime) {
+            perform();
+        }
+    }
+}
diff --git a/test/144-static-field-sigquit/src/SynchronizedUse.java b/test/144-static-field-sigquit/src/SynchronizedUse.java
new file mode 100644
index 0000000..43af1d9
--- /dev/null
+++ b/test/144-static-field-sigquit/src/SynchronizedUse.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+import java.util.Date;
+
+public class SynchronizedUse implements Runnable {
+    public void run() {
+        synchronized (this) {
+            Date dateField = ClassWithStaticField.mDate;
+            System.out.println("Got date field");
+        }
+    }
+}