Test determinism of bootstrapping and nowinandroid

Bug: b/338885156
Fixes: b/338927538
Change-Id: If441b767e63036f1d06882dc1f77dc1c68723682
diff --git a/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java b/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java
new file mode 100644
index 0000000..2d68578
--- /dev/null
+++ b/src/test/bootstrap/com/android/tools/r8/bootstrap/BootstrapDeterminismTest.java
@@ -0,0 +1,67 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.bootstrap;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.JdkClassFileProvider;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.utils.DeterminismChecker;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class BootstrapDeterminismTest extends TestBase {
+
+  private static final int ITERATIONS = 2;
+  private static final Path MAIN_KEEP =
+      Paths.get(ToolHelper.getProjectRoot(), "src", "main", "keep.txt");
+
+  @Parameter public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withDefaultCfRuntime().build();
+  }
+
+  @Test
+  public void test() throws Exception {
+    Path logDirectory = temp.newFolder().toPath();
+    Path ref = compile(1, logDirectory);
+    for (int i = 2; i <= ITERATIONS; i++) {
+      Path next = compile(i, logDirectory);
+      assertProgramsEqual(ref, next);
+    }
+    // Check that setting the determinism checker wrote a log file.
+    assertTrue(Files.exists(logDirectory.resolve("0.log")));
+  }
+
+  private Path compile(int iteration, Path logDirectory) throws Exception {
+    System.out.println("= compiling " + iteration + "/" + ITERATIONS + " ======================");
+    return testForR8(parameters.getBackend())
+        .addProgramFiles(ToolHelper.getR8WithRelocatedDeps())
+        .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
+        .addKeepRuleFiles(MAIN_KEEP)
+        .addOptionsModification(
+            options ->
+                options
+                    .getTestingOptions()
+                    .setDeterminismChecker(DeterminismChecker.createWithFileBacking(logDirectory)))
+        .allowDiagnosticMessages()
+        .allowStdoutMessages()
+        .allowStderrMessages()
+        .allowUnusedDontWarnPatterns()
+        .compile()
+        .writeToZip();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/determinism/AppDeterminismTest.java b/src/test/java/com/android/tools/r8/determinism/DumpDeterminismTestBase.java
similarity index 70%
rename from src/test/java/com/android/tools/r8/determinism/AppDeterminismTest.java
rename to src/test/java/com/android/tools/r8/determinism/DumpDeterminismTestBase.java
index bfd26f1..3ddecd4 100644
--- a/src/test/java/com/android/tools/r8/determinism/AppDeterminismTest.java
+++ b/src/test/java/com/android/tools/r8/determinism/DumpDeterminismTestBase.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.determinism;
@@ -7,44 +7,37 @@
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.dump.CompilerDump;
 import com.android.tools.r8.dump.ProguardConfigSanitizer;
 import com.android.tools.r8.utils.DeterminismChecker;
-import com.google.common.collect.ImmutableList;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class AppDeterminismTest extends TestBase {
+public abstract class DumpDeterminismTestBase extends TestBase {
 
-  @Parameterized.Parameters(name = "{1}")
-  public static List<Object[]> data() {
-    return buildParameters(getTestParameters().withNoneRuntime().build(), ImmutableList.of("tivi"));
+  private static final int ITERATIONS = 2;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
   }
 
-  private final String app;
-  private final int iterations = 2;
-
-  public AppDeterminismTest(TestParameters parameters, String app) {
+  public DumpDeterminismTestBase(TestParameters parameters) {
     parameters.assertNoneRuntime();
-    this.app = app;
   }
 
   @Test
   public void test() throws Exception {
-    CompilerDump dump =
-        CompilerDump.fromArchive(
-            Paths.get(ToolHelper.THIRD_PARTY_DIR, "opensource-apps", app, "dump_app.zip"),
-            temp.newFolder().toPath());
+    CompilerDump dump = CompilerDump.fromArchive(getDumpFile(), temp.newFolder().toPath());
     Path logDirectory = temp.newFolder().toPath();
     Path ref = compile(1, dump, logDirectory);
-    for (int i = 2; i <= iterations; i++) {
+    for (int i = 2; i <= ITERATIONS; i++) {
       Path next = compile(i, dump, logDirectory);
       assertProgramsEqual(ref, next);
     }
@@ -53,7 +46,7 @@
   }
 
   private Path compile(int iteration, CompilerDump dump, Path logDirectory) throws Exception {
-    System.out.println("= compiling " + iteration + "/" + iterations + " ======================");
+    System.out.println("= compiling " + iteration + "/" + ITERATIONS + " ======================");
     return testForR8(Backend.DEX)
         .allowStdoutMessages()
         .allowStderrMessages()
@@ -79,4 +72,6 @@
         .compile()
         .writeToZip();
   }
+
+  abstract Path getDumpFile();
 }
diff --git a/src/test/java/com/android/tools/r8/determinism/NowInAndroidDeterminismTest.java b/src/test/java/com/android/tools/r8/determinism/NowInAndroidDeterminismTest.java
new file mode 100644
index 0000000..4956f49
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/determinism/NowInAndroidDeterminismTest.java
@@ -0,0 +1,25 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.determinism;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class NowInAndroidDeterminismTest extends DumpDeterminismTestBase {
+
+  public NowInAndroidDeterminismTest(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  Path getDumpFile() {
+    return Paths.get(
+        ToolHelper.THIRD_PARTY_DIR, "opensource-apps/android/nowinandroid/dump_app.zip");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/determinism/TiviDeterminismTest.java b/src/test/java/com/android/tools/r8/determinism/TiviDeterminismTest.java
new file mode 100644
index 0000000..50b9801
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/determinism/TiviDeterminismTest.java
@@ -0,0 +1,24 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.determinism;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class TiviDeterminismTest extends DumpDeterminismTestBase {
+
+  public TiviDeterminismTest(TestParameters parameters) {
+    super(parameters);
+  }
+
+  @Override
+  Path getDumpFile() {
+    return Paths.get(ToolHelper.THIRD_PARTY_DIR, "opensource-apps/tivi/dump_app.zip");
+  }
+}