Test that dex2oat jars come before any other jars on BCP.

This ensures that non-updatable jars participating in preopt are always
kept before the rest; to avoid unnecessary optimizations on updates to
BCP.

Bug: 180105615
Test: atest
Change-Id: I7c90f087aed375873b5f91dae70fb0fa3e3e1553
diff --git a/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java b/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java
index 6130936..c915bad 100644
--- a/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java
+++ b/tests/cts/Classpaths/src/android/os/ext/classpath/cts/ClasspathsTest.java
@@ -19,12 +19,14 @@
 import static android.compat.testing.Classpaths.ClasspathType.BOOTCLASSPATH;
 import static android.compat.testing.Classpaths.ClasspathType.DEX2OATBOOTCLASSPATH;
 import static android.compat.testing.Classpaths.ClasspathType.SYSTEMSERVERCLASSPATH;
+import static android.compat.testing.Classpaths.getJarsOnClasspath;
 import static android.os.ext.classpath.cts.ClasspathsTest.ClasspathSubject.assertThat;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.truth.Fact.fact;
 import static com.google.common.truth.Fact.simpleFact;
 import static com.google.common.truth.Truth.assertAbout;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assume.assumeTrue;
 
@@ -36,6 +38,7 @@
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.UnmodifiableListIterator;
 import com.google.common.truth.Fact;
 import com.google.common.truth.FailureMetadata;
 import com.google.common.truth.IterableSubject;
@@ -75,7 +78,7 @@
 
     @Test
     public void testBootclasspath() throws Exception {
-        ImmutableList<String> jars = Classpaths.getJarsOnClasspath(getDevice(), BOOTCLASSPATH);
+        ImmutableList<String> jars = getJarsOnClasspath(getDevice(), BOOTCLASSPATH);
 
         assertThat(jars).containsNoDuplicates();
 
@@ -100,8 +103,7 @@
 
     @Test
     public void testDex2oatBootclasspath() throws Exception {
-        ImmutableList<String> jars = Classpaths.getJarsOnClasspath(getDevice(),
-                DEX2OATBOOTCLASSPATH);
+        ImmutableList<String> jars = getJarsOnClasspath(getDevice(), DEX2OATBOOTCLASSPATH);
 
         assertThat(jars).containsNoDuplicates();
 
@@ -124,8 +126,7 @@
 
     @Test
     public void testSystemServerClasspath() throws Exception {
-        ImmutableList<String> jars = Classpaths.getJarsOnClasspath(getDevice(),
-                SYSTEMSERVERCLASSPATH);
+        ImmutableList<String> jars = getJarsOnClasspath(getDevice(), SYSTEMSERVERCLASSPATH);
 
         assertThat(jars).containsNoDuplicates();
 
@@ -141,6 +142,15 @@
         assertThat(getUpdatableApexes(jars)).isInOrder();
     }
 
+    @Test
+    public void testDex2oatJarsAreFirstOnBootclasspath() throws Exception {
+        ImmutableList<String> bootJars = getJarsOnClasspath(getDevice(), BOOTCLASSPATH);
+        ImmutableList<String> dex2oatJars = getJarsOnClasspath(getDevice(), DEX2OATBOOTCLASSPATH);
+
+        // All preopt jars on BOOTCLASSPATH must come before updatable jars.
+        assertThat(bootJars).startsWith(dex2oatJars);
+    }
+
     /**
      * Returns a derived subject with names of the updatable APEXes preserving the original
      * order.
@@ -223,6 +233,18 @@
             );
         }
 
+        /**
+         * Checks that the actual iterable starts with expected elements.
+         */
+        public void startsWith(ImmutableList<String> expected) {
+            if (actual.size() < expected.size()) {
+                failWithActual("expected at least number of elements", expected.size());
+                return;
+            }
+            assertWithMessage("Unexpected initial elements of the list")
+                    .that(actual.subList(0, expected.size())).isEqualTo(expected);
+        }
+
         private static int findFirstMatchingPrefix(String value, ImmutableList<String> prefixes) {
             for (int i = 0; i < prefixes.size(); i++) {
                 if (value.startsWith(prefixes.get(i))) {