AssertionsConfigurationTest: Split into three test classes

Bug: b/270028969
Change-Id: I39ad0a0a932f464ae464a4b148791ba75d10173f
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java
new file mode 100644
index 0000000..5cbe1b1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinCfTest.java
@@ -0,0 +1,95 @@
+// Copyright (c) 2023, 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.rewrite.assertions;
+
+import com.android.tools.r8.AssertionsConfiguration;
+import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion;
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import java.util.Collection;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class AssertionConfigurationKotlinCfTest extends AssertionConfigurationKotlinTestBase {
+
+  @Parameterized.Parameters(
+      name =
+          "{0}, {1}, kotlin-stdlib as library: {2}, -Xassertions=jvm: {3}, enableJvmAssertions:"
+              + " {4}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withCfRuntimes().build(),
+        getKotlinTestParameters().withAllCompilersAndTargetVersions().build(),
+        BooleanUtils.values(),
+        BooleanUtils.values(),
+        BooleanUtils.values());
+  }
+
+  private final boolean enableJvmAssertions;
+
+  public AssertionConfigurationKotlinCfTest(
+      TestParameters parameters,
+      KotlinTestParameters kotlinParameters,
+      boolean kotlinStdlibAsClasspath,
+      boolean useJvmAssertions,
+      boolean enableJvmAssertions) {
+    super(parameters, kotlinParameters, kotlinStdlibAsClasspath, useJvmAssertions);
+    this.enableJvmAssertions = enableJvmAssertions;
+  }
+
+  @Test
+  public void testAssertionsForCfEnableWithStackMap() throws Exception {
+    Assume.assumeTrue(useJvmAssertions);
+    Assume.assumeTrue(targetVersion == KotlinTargetVersion.JAVA_8);
+    // Compile time enabling or disabling assertions means the -ea flag has no effect.
+    runR8Test(
+        builder -> {
+          builder.addAssertionsConfiguration(
+              AssertionsConfiguration.Builder::compileTimeEnableAllAssertions);
+        },
+        inspector -> checkAssertionCodeEnabled(inspector, true),
+        allAssertionsExpectedLines(),
+        enableJvmAssertions);
+  }
+
+  @Test
+  public void testAssertionsForCfPassThrough() throws Exception {
+    // Leaving assertion code means assertions are controlled by the -ea flag.
+    runR8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::passthroughAllAssertions),
+        inspector -> checkAssertionCodeLeft(inspector, true),
+        enableJvmAssertions ? allAssertionsExpectedLines() : noAllAssertionsExpectedLines(),
+        enableJvmAssertions);
+  }
+
+  @Test
+  public void testAssertionsForCfEnable() throws Exception {
+    // Compile time enabling or disabling assertions means the -ea flag has no effect.
+    runR8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
+        inspector -> checkAssertionCodeEnabled(inspector, true),
+        allAssertionsExpectedLines(),
+        enableJvmAssertions);
+  }
+
+  @Test
+  public void testAssertionsForCfDisable() throws Exception {
+    runR8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
+        inspector -> checkAssertionCodeRemoved(inspector, true),
+        noAllAssertionsExpectedLines(),
+        enableJvmAssertions);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTest.java
new file mode 100644
index 0000000..e5ab25b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinDexTest.java
@@ -0,0 +1,211 @@
+// Copyright (c) 2023, 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.rewrite.assertions;
+
+import com.android.tools.r8.AssertionsConfiguration;
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class AssertionConfigurationKotlinDexTest extends AssertionConfigurationKotlinTestBase {
+
+  @Parameterized.Parameters(name = "{0}, {1}, kotlin-stdlib as library: {2}, -Xassertions=jvm: {3}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimesAndAllApiLevels().build(),
+        getKotlinTestParameters().withAllCompilersAndTargetVersions().build(),
+        BooleanUtils.values(),
+        BooleanUtils.values());
+  }
+
+  public AssertionConfigurationKotlinDexTest(
+      TestParameters parameters,
+      KotlinTestParameters kotlinParameters,
+      boolean kotlinStdlibAsClasspath,
+      boolean useJvmAssertions) {
+    super(parameters, kotlinParameters, kotlinStdlibAsClasspath, useJvmAssertions);
+  }
+
+  @Test
+  public void testD8PassthroughAllAssertions() throws Exception {
+    runD8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::passthroughAllAssertions),
+        inspector -> checkAssertionCodeLeft(inspector, false),
+        // Leaving assertions in on Dalvik/Art means no assertions.
+        noAllAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testR8PassthroughAllAssertions() throws Exception {
+    runR8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::passthroughAllAssertions),
+        inspector -> checkAssertionCodeLeft(inspector, true),
+        // Leaving assertions in on Dalvik/Art means no assertions.
+        noAllAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testD8CompileTimeDisableAllAssertions() throws Exception {
+    runD8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
+        inspector -> checkAssertionCodeRemoved(inspector, false),
+        // Compile time disabling assertions on Dalvik/Art means no assertions.
+        noAllAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testR8CompileTimeDisableAllAssertions() throws Exception {
+    runR8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
+        inspector -> checkAssertionCodeRemoved(inspector, true),
+        // Compile time disabling assertions on Dalvik/Art means no assertions.
+        noAllAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testD8CompileTimeEnableAllAssertions() throws Exception {
+    runD8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
+        inspector -> checkAssertionCodeEnabled(inspector, false),
+        // Compile time enabling assertions gives assertions on Dalvik/Art.
+        allAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testR8CompileTimeEnableAllAssertions() throws Exception {
+    runR8Test(
+        builder ->
+            builder.addAssertionsConfiguration(
+                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
+        inspector -> checkAssertionCodeEnabled(inspector, true),
+        // Compile time enabling assertions gives assertions on Dalvik/Art.
+        allAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testD8CompileTimeEnableForAllClasses() throws Exception {
+    if (useJvmAssertions) {
+      // Enabling for the kotlin generated Java classes should enable all.
+      runD8Test(
+          builder ->
+              builder
+                  .addAssertionsConfiguration(
+                      b -> b.setCompileTimeEnable().setScopeClass(class1).build())
+                  .addAssertionsConfiguration(
+                      b -> b.setCompileTimeEnable().setScopeClass(class2).build()),
+          inspector -> {
+            // The default is applied to kotlin._Assertions (which for DEX is remove).
+            if (!kotlinStdlibAsLibrary) {
+              checkAssertionCodeRemoved(inspector, "kotlin._Assertions", false);
+            }
+            checkAssertionCodeEnabled(inspector, class1, false);
+            checkAssertionCodeEnabled(inspector, class2, false);
+          },
+          allAssertionsExpectedLines());
+    } else {
+      // Enabling for the class kotlin._Assertions should enable all.
+      runD8Test(
+          builder ->
+              builder.addAssertionsConfiguration(
+                  b -> b.setCompileTimeEnable().setScopeClass("kotlin._Assertions").build()),
+          inspector -> checkAssertionCodeEnabled(inspector, false),
+          allAssertionsExpectedLines());
+    }
+  }
+
+  @Test
+  public void testR8CompileTimeEnableForAllClasses() throws Exception {
+    if (useJvmAssertions) {
+      runR8Test(
+          builder ->
+              builder
+                  .addAssertionsConfiguration(
+                      b -> b.setCompileTimeEnable().setScopeClass(class1).build())
+                  .addAssertionsConfiguration(
+                      b -> b.setCompileTimeEnable().setScopeClass(class2).build()),
+          inspector -> checkAssertionCodeEnabled(inspector, true),
+          // When kotlinc generate JVM assertions compile time enabling assertions for the kotlinc
+          // generated Java classes should enable all.
+          allAssertionsExpectedLines());
+    } else {
+      runR8Test(
+          builder ->
+              builder.addAssertionsConfiguration(
+                  b -> b.setCompileTimeEnable().setScopeClass("kotlin._Assertions").build()),
+          inspector -> checkAssertionCodeEnabled(inspector, true),
+          // When kotlinc generate Kotlin assertions compile time enabling assertions the class
+          // kotlin._Assertions should enable all.
+          allAssertionsExpectedLines());
+    }
+  }
+
+  @Test
+  public void testD8CompileTimeEnableForPackage() throws Exception {
+    if (useJvmAssertions) {
+      runD8Test(
+          builder ->
+              builder.addAssertionsConfiguration(
+                  b -> b.setCompileTimeEnable().setScopePackage(kotlintestclasesPackage).build()),
+          inspector -> {
+            // The default is applied to kotlin._Assertions (which for DEX is remove).
+            if (!kotlinStdlibAsLibrary) {
+              checkAssertionCodeRemoved(inspector, "kotlin._Assertions", false);
+            }
+            checkAssertionCodeEnabled(inspector, class1, false);
+            checkAssertionCodeEnabled(inspector, class2, false);
+          },
+          // When kotlinc generate JVM assertions compile time enabling assertions for the kotlinc
+          // generated test classes package should enable all.
+          allAssertionsExpectedLines());
+    } else {
+      runD8Test(
+          builder ->
+              builder.addAssertionsConfiguration(
+                  b -> b.setCompileTimeEnable().setScopePackage("kotlin").build()),
+          inspector -> checkAssertionCodeEnabled(inspector, false),
+          // When kotlinc generate Kotlin assertions compile time enabling assertions the package
+          // kotlin should enable all.
+          allAssertionsExpectedLines());
+    }
+  }
+
+  @Test
+  public void testR8CompileTimeEnableForPackage() throws Exception {
+    if (useJvmAssertions) {
+      runR8Test(
+          builder ->
+              builder.addAssertionsConfiguration(
+                  b -> b.setCompileTimeEnable().setScopePackage(kotlintestclasesPackage).build()),
+          inspector -> checkAssertionCodeEnabled(inspector, true),
+          // When kotlinc generate JVM assertions compile time enabling assertions for the kotlinc
+          // generated test classes package should enable all.
+          allAssertionsExpectedLines());
+    } else {
+      // When kotlinc generate Kotlin assertions compile time enabling assertions the package
+      // kotlin should enable all.
+      runR8Test(
+          builder ->
+              builder.addAssertionsConfiguration(
+                  b -> b.setCompileTimeEnable().setScopePackage("kotlin").build()),
+          inspector -> checkAssertionCodeEnabled(inspector, true),
+          allAssertionsExpectedLines());
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java
deleted file mode 100644
index 99f55e1..0000000
--- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java
+++ /dev/null
@@ -1,704 +0,0 @@
-// Copyright (c) 2020, 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.rewrite.assertions;
-
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.AssertionsConfiguration;
-import com.android.tools.r8.D8TestBuilder;
-import com.android.tools.r8.KotlinCompilerTool.KotlinTargetVersion;
-import com.android.tools.r8.KotlinTestBase;
-import com.android.tools.r8.KotlinTestParameters;
-import com.android.tools.r8.R8FullTestBuilder;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ThrowableConsumer;
-import com.android.tools.r8.utils.BooleanUtils;
-import com.android.tools.r8.utils.ThrowingConsumer;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.InstructionSubject;
-import com.android.tools.r8.utils.codeinspector.MethodSubject;
-import com.google.common.collect.ImmutableList;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-@RunWith(Parameterized.class)
-public class AssertionConfigurationKotlinTest extends KotlinTestBase implements Opcodes {
-
-  private static final Package pkg = AssertionConfigurationKotlinTest.class.getPackage();
-  private static final String kotlintestclasesPackage = pkg.getName() + ".kotlintestclasses";
-  private static final String testClassKt = kotlintestclasesPackage + ".TestClassKt";
-  private static final String class1 = kotlintestclasesPackage + ".Class1";
-  private static final String class2 = kotlintestclasesPackage + ".Class2";
-
-  private static final KotlinCompileMemoizer kotlinWithJvmAssertions =
-      getCompileMemoizer(getKotlinFilesForPackage())
-          .configure(kotlinCompilerTool -> kotlinCompilerTool.setUseJvmAssertions(true));
-  private static final KotlinCompileMemoizer kotlinWithoutJvmAssertions =
-      getCompileMemoizer(getKotlinFilesForPackage())
-          .configure(kotlinCompilerTool -> kotlinCompilerTool.setUseJvmAssertions(false));
-
-  private final TestParameters parameters;
-  private final boolean kotlinStdlibAsLibrary;
-  private final boolean useJvmAssertions;
-  private final KotlinCompileMemoizer compiledForAssertions;
-
-  @Parameterized.Parameters(name = "{0}, {1}, kotlin-stdlib as library: {2}, -Xassertions=jvm: {3}")
-  public static Collection<Object[]> data() {
-    return buildParameters(
-        getTestParameters().withAllRuntimesAndApiLevels().build(),
-        getKotlinTestParameters().withAllCompilersAndTargetVersions().build(),
-        BooleanUtils.values(),
-        BooleanUtils.values());
-  }
-
-  public AssertionConfigurationKotlinTest(
-      TestParameters parameters,
-      KotlinTestParameters kotlinParameters,
-      boolean kotlinStdlibAsClasspath,
-      boolean useJvmAssertions) {
-    super(kotlinParameters);
-    this.parameters = parameters;
-    this.kotlinStdlibAsLibrary = kotlinStdlibAsClasspath;
-    this.useJvmAssertions = useJvmAssertions;
-    this.compiledForAssertions =
-        useJvmAssertions ? kotlinWithJvmAssertions : kotlinWithoutJvmAssertions;
-  }
-
-  private static List<Path> getKotlinFilesForPackage() {
-    try {
-      return getKotlinFilesInTestPackage(pkg);
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  private Path kotlinStdlibLibraryForRuntime() throws Exception {
-    Path kotlinStdlibCf = kotlinc.getKotlinStdlibJar();
-    if (parameters.getRuntime().isCf()) {
-      return kotlinStdlibCf;
-    }
-
-    Path kotlinStdlibDex = temp.newFolder().toPath().resolve("kotlin-stdlib-dex.jar");
-    testForD8()
-        .addProgramFiles(kotlinStdlibCf)
-        .setMinApi(parameters)
-        .compile()
-        .writeToZip(kotlinStdlibDex);
-    return kotlinStdlibDex;
-  }
-
-  private void runD8Test(
-      ThrowableConsumer<D8TestBuilder> builderConsumer,
-      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
-      List<String> outputLines)
-      throws Exception {
-    if (kotlinStdlibAsLibrary) {
-      testForD8()
-          .addClasspathFiles(kotlinc.getKotlinStdlibJar())
-          .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
-          .setMinApi(parameters)
-          .apply(builderConsumer)
-          .addRunClasspathFiles(kotlinStdlibLibraryForRuntime())
-          .run(
-              parameters.getRuntime(),
-              getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
-          .inspect(inspector)
-          .assertSuccessWithOutputLines(outputLines);
-    } else {
-      testForD8()
-          .addProgramFiles(kotlinc.getKotlinStdlibJar())
-          .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
-          .setMinApi(parameters)
-          .apply(builderConsumer)
-          .run(
-              parameters.getRuntime(),
-              getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
-          .inspect(inspector)
-          .assertSuccessWithOutputLines(outputLines);
-    }
-  }
-
-  public void runR8Test(
-      ThrowableConsumer<R8FullTestBuilder> builderConsumer,
-      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
-      List<String> outputLines)
-      throws Exception {
-    runR8Test(builderConsumer, inspector, outputLines, false);
-  }
-
-  public void runR8Test(
-      ThrowableConsumer<R8FullTestBuilder> builderConsumer,
-      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
-      List<String> outputLines,
-      boolean enableJvmAssertions)
-      throws Exception {
-
-    testForR8(parameters.getBackend())
-        .applyIf(
-            kotlinStdlibAsLibrary,
-            b -> {
-              b.addClasspathFiles(kotlinc.getKotlinStdlibJar());
-              b.addRunClasspathFiles(kotlinStdlibLibraryForRuntime());
-            },
-            b -> b.addProgramFiles(kotlinc.getKotlinStdlibJar()))
-        .addClasspathFiles(kotlinc.getKotlinAnnotationJar())
-        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
-        .addKeepMainRule(testClassKt)
-        .addKeepClassAndMembersRules(class1, class2)
-        .setMinApi(parameters)
-        .apply(builderConsumer)
-        .allowDiagnosticWarningMessages(!kotlinStdlibAsLibrary)
-        .addRunClasspathFiles(kotlinStdlibLibraryForRuntime())
-        .compile()
-        .applyIf(
-            !kotlinStdlibAsLibrary,
-            result ->
-                result.assertAllWarningMessagesMatch(
-                    equalTo("Resource 'META-INF/MANIFEST.MF' already exists.")))
-        .enableRuntimeAssertions(enableJvmAssertions)
-        .run(parameters.getRuntime(), testClassKt)
-        .inspect(inspector)
-        .assertSuccessWithOutputLines(outputLines);
-  }
-
-  private List<String> allAssertionsExpectedLines() {
-    return ImmutableList.of("AssertionError in Class1", "AssertionError in Class2", "DONE");
-  }
-
-  private List<String> noAllAssertionsExpectedLines() {
-    return ImmutableList.of("DONE");
-  }
-
-  private void checkAssertionCodeRemoved(ClassSubject subject, boolean isR8) {
-    assertThat(subject, isPresent());
-    if (subject.getOriginalName().equals("kotlin._Assertions")) {
-      assert !kotlinStdlibAsLibrary;
-      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as well,
-      // as is not used.
-      assertEquals(
-          (isR8 ? 0 : 1),
-          subject
-              .uniqueMethodWithOriginalName("<clinit>")
-              .streamInstructions()
-              .filter(InstructionSubject::isStaticPut)
-              .count());
-      assertFalse(
-          subject
-              .uniqueMethodWithOriginalName("<clinit>")
-              .streamInstructions()
-              .anyMatch(InstructionSubject::isConstNumber));
-    } else {
-      // The value of kotlin._Assertions.ENABLED is propagated from the assertions configuration
-      // for the class kotlin._Assertions.
-      assertFalse(
-          subject
-              .uniqueMethodWithOriginalName("m")
-              .streamInstructions()
-              .anyMatch(InstructionSubject::isThrow));
-    }
-  }
-
-  private void checkAssertionCodeRemoved(CodeInspector inspector, String clazz, boolean isR8) {
-    checkAssertionCodeRemoved(inspector.clazz(clazz), isR8);
-  }
-
-  private void checkAssertionCodeEnabled(ClassSubject subject, boolean isR8) {
-    assertThat(subject, isPresent());
-    if (subject.getOriginalName().equals("kotlin._Assertions")) {
-      assert !kotlinStdlibAsLibrary;
-      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as is not used.
-      assertEquals(
-          isR8 ? 1 : 2,
-          subject
-              .uniqueMethodWithOriginalName("<clinit>")
-              .streamInstructions()
-              .filter(InstructionSubject::isStaticPut)
-              .count());
-      assertTrue(
-          subject
-              .uniqueMethodWithOriginalName("<clinit>")
-              .streamInstructions()
-              .anyMatch(instruction -> instruction.isConstNumber(1)));
-    } else {
-      assertTrue(
-          subject
-              .uniqueMethodWithOriginalName("m")
-              .streamInstructions()
-              .anyMatch(InstructionSubject::isThrow));
-    }
-  }
-
-  private void checkAssertionCodeEnabled(CodeInspector inspector, String clazz, boolean isR8) {
-
-    checkAssertionCodeEnabled(inspector.clazz(clazz), isR8);
-  }
-
-  private void checkAssertionCodeLeft(CodeInspector inspector, String clazz, boolean isR8) {
-    ClassSubject subject = inspector.clazz(clazz);
-    if (clazz.equals("kotlin._Assertions")) {
-      assert !kotlinStdlibAsLibrary;
-      if (isR8 && useJvmAssertions) {
-        // When JVM assertions are used the class kotlin._Assertions is unused.
-        assertThat(subject, not(isPresent()));
-        return;
-      }
-      assertThat(subject, isPresent());
-      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as is not used.
-      assertEquals(
-          isR8 ? 1 : 2,
-          subject
-              .uniqueMethodWithOriginalName("<clinit>")
-              .streamInstructions()
-              .filter(InstructionSubject::isStaticPut)
-              .count());
-      assertFalse(
-          subject
-              .uniqueMethodWithOriginalName("<clinit>")
-              .streamInstructions()
-              .anyMatch(InstructionSubject::isConstNumber));
-    } else {
-      assertThat(subject, isPresent());
-      MethodSubject clinit = subject.uniqueMethodWithOriginalName("<clinit>");
-      if (useJvmAssertions) {
-        assertTrue(clinit.streamInstructions().anyMatch(InstructionSubject::isStaticPut));
-      } else {
-        assertThat(clinit, not(isPresent()));
-      }
-      assertTrue(
-          subject
-              .uniqueMethodWithOriginalName("m")
-              .streamInstructions()
-              .anyMatch(InstructionSubject::isThrow));
-    }
-  }
-
-  private void checkAssertionCodeRemoved(CodeInspector inspector, boolean isR8) {
-    if (isR8) {
-      assertThat(inspector.clazz("kotlin._Assertions"), not(isPresent()));
-    } else if (!kotlinStdlibAsLibrary) {
-      checkAssertionCodeRemoved(inspector, "kotlin._Assertions", isR8);
-    }
-    checkAssertionCodeRemoved(inspector, class1, isR8);
-    checkAssertionCodeRemoved(inspector, class2, isR8);
-  }
-
-  private void checkAssertionCodeEnabled(CodeInspector inspector, boolean isR8) {
-    if (isR8) {
-      assertThat(inspector.clazz("kotlin._Assertions"), not(isPresent()));
-    } else if (!kotlinStdlibAsLibrary) {
-      checkAssertionCodeEnabled(inspector, "kotlin._Assertions", isR8);
-    }
-    checkAssertionCodeEnabled(inspector, class1, isR8);
-    checkAssertionCodeEnabled(inspector, class2, isR8);
-  }
-
-  private void checkAssertionCodeLeft(CodeInspector inspector, boolean isR8) {
-    if (!kotlinStdlibAsLibrary) {
-      checkAssertionCodeLeft(inspector, "kotlin._Assertions", isR8);
-    }
-    checkAssertionCodeLeft(inspector, class1, isR8);
-    checkAssertionCodeLeft(inspector, class2, isR8);
-  }
-
-  @Test
-  public void testD8PassthroughAllAssertions() throws Exception {
-    parameters.assumeDexRuntime();
-    runD8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::passthroughAllAssertions),
-        inspector -> checkAssertionCodeLeft(inspector, false),
-        // Leaving assertions in on Dalvik/Art means no assertions.
-        noAllAssertionsExpectedLines());
-  }
-
-  @Test
-  public void testR8PassthroughAllAssertions() throws Exception {
-    parameters.assumeDexRuntime();
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::passthroughAllAssertions),
-        inspector -> checkAssertionCodeLeft(inspector, true),
-        // Leaving assertions in on Dalvik/Art means no assertions.
-        noAllAssertionsExpectedLines());
-  }
-
-  @Test
-  public void testD8CompileTimeDisableAllAssertions() throws Exception {
-    parameters.assumeDexRuntime();
-    runD8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
-        inspector -> checkAssertionCodeRemoved(inspector, false),
-        // Compile time disabling assertions on Dalvik/Art means no assertions.
-        noAllAssertionsExpectedLines());
-  }
-
-  @Test
-  public void testR8CompileTimeDisableAllAssertions() throws Exception {
-    parameters.assumeDexRuntime();
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
-        inspector -> checkAssertionCodeRemoved(inspector, true),
-        // Compile time disabling assertions on Dalvik/Art means no assertions.
-        noAllAssertionsExpectedLines());
-  }
-
-  @Test
-  public void testD8CompileTimeEnableAllAssertions() throws Exception {
-    parameters.assumeDexRuntime();
-    runD8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
-        inspector -> checkAssertionCodeEnabled(inspector, false),
-        // Compile time enabling assertions gives assertions on Dalvik/Art.
-        allAssertionsExpectedLines());
-  }
-
-  @Test
-  public void testR8CompileTimeEnableAllAssertions() throws Exception {
-    parameters.assumeDexRuntime();
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
-        inspector -> checkAssertionCodeEnabled(inspector, true),
-        // Compile time enabling assertions gives assertions on Dalvik/Art.
-        allAssertionsExpectedLines());
-  }
-
-  @Test
-  public void testD8CompileTimeEnableForAllClasses() throws Exception {
-    parameters.assumeDexRuntime();
-    if (useJvmAssertions) {
-      // Enabling for the kotlin generated Java classes should enable all.
-      runD8Test(
-          builder ->
-              builder
-                  .addAssertionsConfiguration(
-                      b -> b.setCompileTimeEnable().setScopeClass(class1).build())
-                  .addAssertionsConfiguration(
-                      b -> b.setCompileTimeEnable().setScopeClass(class2).build()),
-          inspector -> {
-            // The default is applied to kotlin._Assertions (which for DEX is remove).
-            if (!kotlinStdlibAsLibrary) {
-              checkAssertionCodeRemoved(inspector, "kotlin._Assertions", false);
-            }
-            checkAssertionCodeEnabled(inspector, class1, false);
-            checkAssertionCodeEnabled(inspector, class2, false);
-          },
-          allAssertionsExpectedLines());
-    } else {
-      // Enabling for the class kotlin._Assertions should enable all.
-      runD8Test(
-          builder ->
-              builder.addAssertionsConfiguration(
-                  b -> b.setCompileTimeEnable().setScopeClass("kotlin._Assertions").build()),
-          inspector -> checkAssertionCodeEnabled(inspector, false),
-          allAssertionsExpectedLines());
-    }
-  }
-
-  @Test
-  public void testR8CompileTimeEnableForAllClasses() throws Exception {
-    parameters.assumeDexRuntime();
-    if (useJvmAssertions) {
-      runR8Test(
-          builder ->
-              builder
-                  .addAssertionsConfiguration(
-                      b -> b.setCompileTimeEnable().setScopeClass(class1).build())
-                  .addAssertionsConfiguration(
-                      b -> b.setCompileTimeEnable().setScopeClass(class2).build()),
-          inspector -> checkAssertionCodeEnabled(inspector, true),
-          // When kotlinc generate JVM assertions compile time enabling assertions for the kotlinc
-          // generated Java classes should enable all.
-          allAssertionsExpectedLines());
-    } else {
-      runR8Test(
-          builder ->
-              builder.addAssertionsConfiguration(
-                  b -> b.setCompileTimeEnable().setScopeClass("kotlin._Assertions").build()),
-          inspector -> checkAssertionCodeEnabled(inspector, true),
-          // When kotlinc generate Kotlin assertions compile time enabling assertions the class
-          // kotlin._Assertions should enable all.
-          allAssertionsExpectedLines());
-    }
-  }
-
-  @Test
-  public void testD8CompileTimeEnableForPackage() throws Exception {
-    parameters.assumeDexRuntime();
-    if (useJvmAssertions) {
-      runD8Test(
-          builder ->
-              builder.addAssertionsConfiguration(
-                  b -> b.setCompileTimeEnable().setScopePackage(kotlintestclasesPackage).build()),
-          inspector -> {
-            // The default is applied to kotlin._Assertions (which for DEX is remove).
-            if (!kotlinStdlibAsLibrary) {
-              checkAssertionCodeRemoved(inspector, "kotlin._Assertions", false);
-            }
-            checkAssertionCodeEnabled(inspector, class1, false);
-            checkAssertionCodeEnabled(inspector, class2, false);
-          },
-          // When kotlinc generate JVM assertions compile time enabling assertions for the kotlinc
-          // generated test classes package should enable all.
-          allAssertionsExpectedLines());
-    } else {
-      runD8Test(
-          builder ->
-              builder.addAssertionsConfiguration(
-                  b -> b.setCompileTimeEnable().setScopePackage("kotlin").build()),
-          inspector -> checkAssertionCodeEnabled(inspector, false),
-          // When kotlinc generate Kotlin assertions compile time enabling assertions the package
-          // kotlin should enable all.
-          allAssertionsExpectedLines());
-    }
-  }
-
-  @Test
-  public void testR8CompileTimeEnableForPackage() throws Exception {
-    parameters.assumeDexRuntime();
-    if (useJvmAssertions) {
-      runR8Test(
-          builder ->
-              builder.addAssertionsConfiguration(
-                  b -> b.setCompileTimeEnable().setScopePackage(kotlintestclasesPackage).build()),
-          inspector -> checkAssertionCodeEnabled(inspector, true),
-          // When kotlinc generate JVM assertions compile time enabling assertions for the kotlinc
-          // generated test classes package should enable all.
-          allAssertionsExpectedLines());
-    } else {
-      // When kotlinc generate Kotlin assertions compile time enabling assertions the package
-      // kotlin should enable all.
-      runR8Test(
-          builder ->
-              builder.addAssertionsConfiguration(
-                  b -> b.setCompileTimeEnable().setScopePackage("kotlin").build()),
-          inspector -> checkAssertionCodeEnabled(inspector, true),
-          allAssertionsExpectedLines());
-    }
-  }
-
-  @Test
-  public void testAssertionsForCfEnableWithStackMap() throws Exception {
-    parameters.assumeCfRuntime();
-    Assume.assumeTrue(useJvmAssertions);
-    Assume.assumeTrue(targetVersion == KotlinTargetVersion.JAVA_8);
-    // Compile time enabling or disabling assertions means the -ea flag has no effect.
-    runR8Test(
-        builder -> {
-          builder.addAssertionsConfiguration(
-              AssertionsConfiguration.Builder::compileTimeEnableAllAssertions);
-        },
-        inspector -> checkAssertionCodeEnabled(inspector, true),
-        allAssertionsExpectedLines());
-    runR8Test(
-        builder -> {
-          builder.addAssertionsConfiguration(
-              AssertionsConfiguration.Builder::compileTimeEnableAllAssertions);
-        },
-        inspector -> checkAssertionCodeEnabled(inspector, true),
-        allAssertionsExpectedLines(),
-        true);
-  }
-
-  @Test
-  public void testAssertionsForCfPassThrough() throws Exception {
-    parameters.assumeCfRuntime();
-    // Leaving assertion code means assertions are controlled by the -ea flag.
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::passthroughAllAssertions),
-        inspector -> checkAssertionCodeLeft(inspector, true),
-        noAllAssertionsExpectedLines());
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::passthroughAllAssertions),
-        inspector -> checkAssertionCodeLeft(inspector, true),
-        allAssertionsExpectedLines(),
-        true);
-  }
-
-  @Test
-  public void testAssertionsForCfEnable() throws Exception {
-    parameters.assumeCfRuntime();
-    // Compile time enabling or disabling assertions means the -ea flag has no effect.
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
-        inspector -> checkAssertionCodeEnabled(inspector, true),
-        allAssertionsExpectedLines());
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeEnableAllAssertions),
-        inspector -> checkAssertionCodeEnabled(inspector, true),
-        allAssertionsExpectedLines(),
-        true);
-  }
-
-  @Test
-  public void testAssertionsForCfDisable() throws Exception {
-    parameters.assumeCfRuntime();
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
-        inspector -> checkAssertionCodeRemoved(inspector, true),
-        noAllAssertionsExpectedLines());
-    runR8Test(
-        builder ->
-            builder.addAssertionsConfiguration(
-                AssertionsConfiguration.Builder::compileTimeDisableAllAssertions),
-        inspector -> checkAssertionCodeRemoved(inspector, true),
-        noAllAssertionsExpectedLines(),
-        true);
-  }
-
-  @Test
-  public void TestWithModifiedKotlinAssertions() throws Exception {
-    parameters.assumeCfRuntime();
-    testForD8()
-        .addProgramClassFileData(dumpModifiedKotlinAssertions())
-        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
-        .setMinApi(parameters)
-        .addAssertionsConfiguration(AssertionsConfiguration.Builder::passthroughAllAssertions)
-        .run(
-            parameters.getRuntime(),
-            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
-        .assertSuccessWithOutputLines(noAllAssertionsExpectedLines());
-    testForD8()
-        .addProgramClassFileData(dumpModifiedKotlinAssertions())
-        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
-        .setMinApi(parameters)
-        .addAssertionsConfiguration(AssertionsConfiguration.Builder::compileTimeEnableAllAssertions)
-        .run(
-            parameters.getRuntime(),
-            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
-        .assertSuccessWithOutputLines(allAssertionsExpectedLines());
-    testForD8()
-        .addProgramClassFileData(dumpModifiedKotlinAssertions())
-        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
-        .setMinApi(parameters)
-        .addAssertionsConfiguration(
-            AssertionsConfiguration.Builder::compileTimeDisableAllAssertions)
-        .run(
-            parameters.getRuntime(),
-            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
-        .assertSuccessWithOutputLines(noAllAssertionsExpectedLines());
-  }
-
-  // Slightly modified version of kotlin._Assertions to hit all code paths in the assertion
-  // rewriter. See "Code added" below.
-  public static byte[] dumpModifiedKotlinAssertions() {
-
-    ClassWriter classWriter = new ClassWriter(0);
-    FieldVisitor fieldVisitor;
-    MethodVisitor methodVisitor;
-
-    classWriter.visit(
-        V1_6,
-        ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
-        "kotlin/_Assertions",
-        null,
-        "java/lang/Object",
-        null);
-
-    {
-      fieldVisitor =
-          classWriter.visitField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "ENABLED", "Z", null, null);
-      fieldVisitor.visitEnd();
-    }
-    {
-      fieldVisitor =
-          classWriter.visitField(
-              ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "INSTANCE", "Lkotlin/_Assertions;", null, null);
-      fieldVisitor.visitEnd();
-    }
-    {
-      methodVisitor =
-          classWriter.visitMethod(
-              ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC | ACC_DEPRECATED,
-              "ENABLED$annotations",
-              "()V",
-              null,
-              null);
-      methodVisitor.visitCode();
-      methodVisitor.visitInsn(RETURN);
-      methodVisitor.visitMaxs(0, 0);
-      methodVisitor.visitEnd();
-    }
-    {
-      methodVisitor = classWriter.visitMethod(ACC_PRIVATE, "<init>", "()V", null, null);
-      methodVisitor.visitCode();
-      methodVisitor.visitVarInsn(ALOAD, 0);
-      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
-      methodVisitor.visitInsn(RETURN);
-      methodVisitor.visitMaxs(1, 1);
-      methodVisitor.visitEnd();
-    }
-    {
-      methodVisitor = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
-      methodVisitor.visitCode();
-      methodVisitor.visitTypeInsn(NEW, "kotlin/_Assertions");
-      methodVisitor.visitInsn(DUP);
-      methodVisitor.visitMethodInsn(INVOKESPECIAL, "kotlin/_Assertions", "<init>", "()V", false);
-      methodVisitor.visitVarInsn(ASTORE, 0);
-      methodVisitor.visitVarInsn(ALOAD, 0);
-      methodVisitor.visitFieldInsn(
-          PUTSTATIC, "kotlin/_Assertions", "INSTANCE", "Lkotlin/_Assertions;");
-
-      // Code added (added an additional call to getClass().desiredAssertionStatus() which
-      // result is not assigned to ENABLED).
-      methodVisitor.visitVarInsn(ALOAD, 0);
-      methodVisitor.visitMethodInsn(
-          INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
-      methodVisitor.visitMethodInsn(
-          INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
-      methodVisitor.visitInsn(POP);
-      // End code added.
-
-      methodVisitor.visitVarInsn(ALOAD, 0);
-      methodVisitor.visitMethodInsn(
-          INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
-      methodVisitor.visitMethodInsn(
-          INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
-      methodVisitor.visitFieldInsn(PUTSTATIC, "kotlin/_Assertions", "ENABLED", "Z");
-      methodVisitor.visitInsn(RETURN);
-      methodVisitor.visitMaxs(2, 1);
-      methodVisitor.visitEnd();
-    }
-    classWriter.visitEnd();
-
-    return classWriter.toByteArray();
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTestBase.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTestBase.java
new file mode 100644
index 0000000..999ca31
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTestBase.java
@@ -0,0 +1,299 @@
+// Copyright (c) 2023, 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.rewrite.assertions;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.D8TestBuilder;
+import com.android.tools.r8.KotlinTestBase;
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.R8FullTestBuilder;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ThrowableConsumer;
+import com.android.tools.r8.utils.ThrowingConsumer;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+import org.objectweb.asm.Opcodes;
+
+public class AssertionConfigurationKotlinTestBase extends KotlinTestBase implements Opcodes {
+
+  protected static final Package pkg = AssertionConfigurationKotlinTestBase.class.getPackage();
+  protected static final String kotlintestclasesPackage = pkg.getName() + ".kotlintestclasses";
+  protected static final String testClassKt = kotlintestclasesPackage + ".TestClassKt";
+  protected static final String class1 = kotlintestclasesPackage + ".Class1";
+  protected static final String class2 = kotlintestclasesPackage + ".Class2";
+
+  private static final KotlinCompileMemoizer kotlinWithJvmAssertions =
+      getCompileMemoizer(getKotlinFilesForPackage())
+          .configure(kotlinCompilerTool -> kotlinCompilerTool.setUseJvmAssertions(true));
+  private static final KotlinCompileMemoizer kotlinWithoutJvmAssertions =
+      getCompileMemoizer(getKotlinFilesForPackage())
+          .configure(kotlinCompilerTool -> kotlinCompilerTool.setUseJvmAssertions(false));
+
+  protected final TestParameters parameters;
+  protected final boolean kotlinStdlibAsLibrary;
+  protected final boolean useJvmAssertions;
+  protected final KotlinCompileMemoizer compiledForAssertions;
+
+  public AssertionConfigurationKotlinTestBase(
+      TestParameters parameters,
+      KotlinTestParameters kotlinParameters,
+      boolean kotlinStdlibAsClasspath,
+      boolean useJvmAssertions) {
+    super(kotlinParameters);
+    this.parameters = parameters;
+    this.kotlinStdlibAsLibrary = kotlinStdlibAsClasspath;
+    this.useJvmAssertions = useJvmAssertions;
+    this.compiledForAssertions =
+        useJvmAssertions ? kotlinWithJvmAssertions : kotlinWithoutJvmAssertions;
+  }
+
+  private static List<Path> getKotlinFilesForPackage() {
+    try {
+      return getKotlinFilesInTestPackage(pkg);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private Path kotlinStdlibLibraryForRuntime() throws Exception {
+    Path kotlinStdlibCf = kotlinc.getKotlinStdlibJar();
+    if (parameters.getRuntime().isCf()) {
+      return kotlinStdlibCf;
+    }
+
+    Path kotlinStdlibDex = temp.newFolder().toPath().resolve("kotlin-stdlib-dex.jar");
+    testForD8()
+        .addProgramFiles(kotlinStdlibCf)
+        .setMinApi(parameters)
+        .compile()
+        .writeToZip(kotlinStdlibDex);
+    return kotlinStdlibDex;
+  }
+
+  protected void runD8Test(
+      ThrowableConsumer<D8TestBuilder> builderConsumer,
+      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
+      List<String> outputLines)
+      throws Exception {
+    if (kotlinStdlibAsLibrary) {
+      testForD8()
+          .addClasspathFiles(kotlinc.getKotlinStdlibJar())
+          .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
+          .setMinApi(parameters)
+          .apply(builderConsumer)
+          .addRunClasspathFiles(kotlinStdlibLibraryForRuntime())
+          .run(
+              parameters.getRuntime(),
+              getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
+          .inspect(inspector)
+          .assertSuccessWithOutputLines(outputLines);
+    } else {
+      testForD8()
+          .addProgramFiles(kotlinc.getKotlinStdlibJar())
+          .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
+          .setMinApi(parameters)
+          .apply(builderConsumer)
+          .run(
+              parameters.getRuntime(),
+              getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
+          .inspect(inspector)
+          .assertSuccessWithOutputLines(outputLines);
+    }
+  }
+
+  protected void runR8Test(
+      ThrowableConsumer<R8FullTestBuilder> builderConsumer,
+      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
+      List<String> outputLines)
+      throws Exception {
+    runR8Test(builderConsumer, inspector, outputLines, false);
+  }
+
+  protected void runR8Test(
+      ThrowableConsumer<R8FullTestBuilder> builderConsumer,
+      ThrowingConsumer<CodeInspector, RuntimeException> inspector,
+      List<String> outputLines,
+      boolean enableJvmAssertions)
+      throws Exception {
+
+    testForR8(parameters.getBackend())
+        .applyIf(
+            kotlinStdlibAsLibrary,
+            b -> {
+              b.addClasspathFiles(kotlinc.getKotlinStdlibJar());
+              b.addRunClasspathFiles(kotlinStdlibLibraryForRuntime());
+            },
+            b -> b.addProgramFiles(kotlinc.getKotlinStdlibJar()))
+        .addClasspathFiles(kotlinc.getKotlinAnnotationJar())
+        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
+        .addKeepMainRule(testClassKt)
+        .addKeepClassAndMembersRules(class1, class2)
+        .setMinApi(parameters)
+        .apply(builderConsumer)
+        .allowDiagnosticWarningMessages(!kotlinStdlibAsLibrary)
+        .addRunClasspathFiles(kotlinStdlibLibraryForRuntime())
+        .compile()
+        .applyIf(
+            !kotlinStdlibAsLibrary,
+            result ->
+                result.assertAllWarningMessagesMatch(
+                    equalTo("Resource 'META-INF/MANIFEST.MF' already exists.")))
+        .enableRuntimeAssertions(enableJvmAssertions)
+        .run(parameters.getRuntime(), testClassKt)
+        .inspect(inspector)
+        .assertSuccessWithOutputLines(outputLines);
+  }
+
+  protected List<String> allAssertionsExpectedLines() {
+    return ImmutableList.of("AssertionError in Class1", "AssertionError in Class2", "DONE");
+  }
+
+  protected List<String> noAllAssertionsExpectedLines() {
+    return ImmutableList.of("DONE");
+  }
+
+  protected void checkAssertionCodeRemoved(ClassSubject subject, boolean isR8) {
+    assertThat(subject, isPresent());
+    if (subject.getOriginalName().equals("kotlin._Assertions")) {
+      assert !kotlinStdlibAsLibrary;
+      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as well,
+      // as is not used.
+      assertEquals(
+          (isR8 ? 0 : 1),
+          subject
+              .uniqueMethodWithOriginalName("<clinit>")
+              .streamInstructions()
+              .filter(InstructionSubject::isStaticPut)
+              .count());
+      assertFalse(
+          subject
+              .uniqueMethodWithOriginalName("<clinit>")
+              .streamInstructions()
+              .anyMatch(InstructionSubject::isConstNumber));
+    } else {
+      // The value of kotlin._Assertions.ENABLED is propagated from the assertions configuration
+      // for the class kotlin._Assertions.
+      assertFalse(
+          subject
+              .uniqueMethodWithOriginalName("m")
+              .streamInstructions()
+              .anyMatch(InstructionSubject::isThrow));
+    }
+  }
+
+  protected void checkAssertionCodeRemoved(CodeInspector inspector, String clazz, boolean isR8) {
+    checkAssertionCodeRemoved(inspector.clazz(clazz), isR8);
+  }
+
+  protected void checkAssertionCodeEnabled(ClassSubject subject, boolean isR8) {
+    assertThat(subject, isPresent());
+    if (subject.getOriginalName().equals("kotlin._Assertions")) {
+      assert !kotlinStdlibAsLibrary;
+      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as is not used.
+      assertEquals(
+          isR8 ? 1 : 2,
+          subject
+              .uniqueMethodWithOriginalName("<clinit>")
+              .streamInstructions()
+              .filter(InstructionSubject::isStaticPut)
+              .count());
+      assertTrue(
+          subject
+              .uniqueMethodWithOriginalName("<clinit>")
+              .streamInstructions()
+              .anyMatch(instruction -> instruction.isConstNumber(1)));
+    } else {
+      assertTrue(
+          subject
+              .uniqueMethodWithOriginalName("m")
+              .streamInstructions()
+              .anyMatch(InstructionSubject::isThrow));
+    }
+  }
+
+  protected void checkAssertionCodeEnabled(CodeInspector inspector, String clazz, boolean isR8) {
+    checkAssertionCodeEnabled(inspector.clazz(clazz), isR8);
+  }
+
+  protected void checkAssertionCodeLeft(CodeInspector inspector, String clazz, boolean isR8) {
+    ClassSubject subject = inspector.clazz(clazz);
+    if (clazz.equals("kotlin._Assertions")) {
+      assert !kotlinStdlibAsLibrary;
+      if (isR8 && useJvmAssertions) {
+        // When JVM assertions are used the class kotlin._Assertions is unused.
+        assertThat(subject, not(isPresent()));
+        return;
+      }
+      assertThat(subject, isPresent());
+      // With R8 the static-put of the kotlin._Assertions.INSTANCE field is removed as is not used.
+      assertEquals(
+          isR8 ? 1 : 2,
+          subject
+              .uniqueMethodWithOriginalName("<clinit>")
+              .streamInstructions()
+              .filter(InstructionSubject::isStaticPut)
+              .count());
+      assertFalse(
+          subject
+              .uniqueMethodWithOriginalName("<clinit>")
+              .streamInstructions()
+              .anyMatch(InstructionSubject::isConstNumber));
+    } else {
+      assertThat(subject, isPresent());
+      MethodSubject clinit = subject.uniqueMethodWithOriginalName("<clinit>");
+      if (useJvmAssertions) {
+        assertTrue(clinit.streamInstructions().anyMatch(InstructionSubject::isStaticPut));
+      } else {
+        assertThat(clinit, not(isPresent()));
+      }
+      assertTrue(
+          subject
+              .uniqueMethodWithOriginalName("m")
+              .streamInstructions()
+              .anyMatch(InstructionSubject::isThrow));
+    }
+  }
+
+  protected void checkAssertionCodeRemoved(CodeInspector inspector, boolean isR8) {
+    if (isR8) {
+      assertThat(inspector.clazz("kotlin._Assertions"), not(isPresent()));
+    } else if (!kotlinStdlibAsLibrary) {
+      checkAssertionCodeRemoved(inspector, "kotlin._Assertions", isR8);
+    }
+    checkAssertionCodeRemoved(inspector, class1, isR8);
+    checkAssertionCodeRemoved(inspector, class2, isR8);
+  }
+
+  protected void checkAssertionCodeEnabled(CodeInspector inspector, boolean isR8) {
+    if (isR8) {
+      assertThat(inspector.clazz("kotlin._Assertions"), not(isPresent()));
+    } else if (!kotlinStdlibAsLibrary) {
+      checkAssertionCodeEnabled(inspector, "kotlin._Assertions", isR8);
+    }
+    checkAssertionCodeEnabled(inspector, class1, isR8);
+    checkAssertionCodeEnabled(inspector, class2, isR8);
+  }
+
+  protected void checkAssertionCodeLeft(CodeInspector inspector, boolean isR8) {
+    if (!kotlinStdlibAsLibrary) {
+      checkAssertionCodeLeft(inspector, "kotlin._Assertions", isR8);
+    }
+    checkAssertionCodeLeft(inspector, class1, isR8);
+    checkAssertionCodeLeft(inspector, class2, isR8);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java
new file mode 100644
index 0000000..32c29d7
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest.java
@@ -0,0 +1,165 @@
+// Copyright (c) 2023, 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.rewrite.assertions;
+
+import com.android.tools.r8.AssertionsConfiguration;
+import com.android.tools.r8.KotlinTestParameters;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(Parameterized.class)
+public class AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest
+    extends AssertionConfigurationKotlinTestBase implements Opcodes {
+
+  @Parameterized.Parameters(name = "{0}, {1}, kotlin-stdlib as library: {2}, -Xassertions=jvm: {3}")
+  public static Collection<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimesAndAllApiLevels().build(),
+        getKotlinTestParameters().withAllCompilersAndTargetVersions().build(),
+        BooleanUtils.values(),
+        BooleanUtils.values());
+  }
+
+  public AssertionConfigurationKotlinWithModifiedKotlinAssertionsTest(
+      TestParameters parameters,
+      KotlinTestParameters kotlinParameters,
+      boolean kotlinStdlibAsClasspath,
+      boolean useJvmAssertions) {
+    super(parameters, kotlinParameters, kotlinStdlibAsClasspath, useJvmAssertions);
+  }
+
+  @Test
+  public void testPassthroughAllAssertions() throws Exception {
+    testForD8()
+        .addProgramClassFileData(dumpModifiedKotlinAssertions())
+        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
+        .setMinApi(parameters)
+        .addAssertionsConfiguration(AssertionsConfiguration.Builder::passthroughAllAssertions)
+        .run(
+            parameters.getRuntime(),
+            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
+        .assertSuccessWithOutputLines(noAllAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testCompileTimeEnableAllAssertions() throws Exception {
+    testForD8()
+        .addProgramClassFileData(dumpModifiedKotlinAssertions())
+        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
+        .setMinApi(parameters)
+        .addAssertionsConfiguration(AssertionsConfiguration.Builder::compileTimeEnableAllAssertions)
+        .run(
+            parameters.getRuntime(),
+            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
+        .assertSuccessWithOutputLines(allAssertionsExpectedLines());
+  }
+
+  @Test
+  public void testCompileTimeDisableAllAssertions() throws Exception {
+    testForD8()
+        .addProgramClassFileData(dumpModifiedKotlinAssertions())
+        .addProgramFiles(compiledForAssertions.getForConfiguration(kotlinc, targetVersion))
+        .setMinApi(parameters)
+        .addAssertionsConfiguration(
+            AssertionsConfiguration.Builder::compileTimeDisableAllAssertions)
+        .run(
+            parameters.getRuntime(),
+            getClass().getPackage().getName() + ".kotlintestclasses.TestClassKt")
+        .assertSuccessWithOutputLines(noAllAssertionsExpectedLines());
+  }
+
+  // Slightly modified version of kotlin._Assertions to hit all code paths in the assertion
+  // rewriter. See "Code added" below.
+  public static byte[] dumpModifiedKotlinAssertions() {
+
+    ClassWriter classWriter = new ClassWriter(0);
+    FieldVisitor fieldVisitor;
+    MethodVisitor methodVisitor;
+
+    classWriter.visit(
+        V1_6,
+        ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
+        "kotlin/_Assertions",
+        null,
+        "java/lang/Object",
+        null);
+
+    {
+      fieldVisitor =
+          classWriter.visitField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "ENABLED", "Z", null, null);
+      fieldVisitor.visitEnd();
+    }
+    {
+      fieldVisitor =
+          classWriter.visitField(
+              ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "INSTANCE", "Lkotlin/_Assertions;", null, null);
+      fieldVisitor.visitEnd();
+    }
+    {
+      methodVisitor =
+          classWriter.visitMethod(
+              ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC | ACC_DEPRECATED,
+              "ENABLED$annotations",
+              "()V",
+              null,
+              null);
+      methodVisitor.visitCode();
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(0, 0);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PRIVATE, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitTypeInsn(NEW, "kotlin/_Assertions");
+      methodVisitor.visitInsn(DUP);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "kotlin/_Assertions", "<init>", "()V", false);
+      methodVisitor.visitVarInsn(ASTORE, 0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitFieldInsn(
+          PUTSTATIC, "kotlin/_Assertions", "INSTANCE", "Lkotlin/_Assertions;");
+
+      // Code added (added an additional call to getClass().desiredAssertionStatus() which
+      // result is not assigned to ENABLED).
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
+      methodVisitor.visitInsn(POP);
+      // End code added.
+
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z", false);
+      methodVisitor.visitFieldInsn(PUTSTATIC, "kotlin/_Assertions", "ENABLED", "Z");
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 1);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+
+    return classWriter.toByteArray();
+  }
+}