Add assertForTesting utility methods for enable assertions in tests

Bug: 187905573
Change-Id: I496c8dbf5565e264489441c8aee2482faa9584b1
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 81a8f82..2fadb7d 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import static com.android.tools.r8.D8Command.USAGE_MESSAGE;
+import static com.android.tools.r8.utils.AssertionUtils.forTesting;
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
 
 import com.android.tools.r8.dex.ApplicationReader;
@@ -186,6 +187,9 @@
       // Disable global optimizations.
       options.disableGlobalOptimizations();
 
+      // Synthetic assertion to check that testing assertions works and can be enabled.
+      assert forTesting(options, () -> !options.testing.testEnableTestAssertions);
+
       AppView<AppInfo> appView = readApp(inputApp, options, executor, timing);
       SyntheticItems.collectSyntheticInputs(appView);
 
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 2404763..b9561b9 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import static com.android.tools.r8.R8Command.USAGE_MESSAGE;
+import static com.android.tools.r8.utils.AssertionUtils.forTesting;
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
 
 import com.android.tools.r8.cf.code.CfInstruction;
@@ -282,6 +283,8 @@
           new StringDiagnostic(
               "Running R8 version " + Version.LABEL + " with assertions enabled."));
     }
+    // Synthetic assertion to check that testing assertions works and can be enabled.
+    assert forTesting(options, () -> !options.testing.testEnableTestAssertions);
     try {
       AppView<AppInfoWithClassHierarchy> appView;
       {
diff --git a/src/main/java/com/android/tools/r8/utils/AssertionUtils.java b/src/main/java/com/android/tools/r8/utils/AssertionUtils.java
index c185096..bb1e59f 100644
--- a/src/main/java/com/android/tools/r8/utils/AssertionUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AssertionUtils.java
@@ -4,10 +4,16 @@
 
 package com.android.tools.r8.utils;
 
+import java.util.function.Supplier;
+
 public class AssertionUtils {
 
   public static boolean assertNotNull(Object o) {
     assert o != null;
     return true;
   }
+
+  public static boolean forTesting(InternalOptions options, Supplier<Boolean> test) {
+    return options.testing.enableTestAssertions ? test.get() : true;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index ff812b6..f2770c0 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1356,6 +1356,9 @@
     public boolean checkForNotExpandingMainDexTracingResult = false;
     public Set<String> allowedUnusedDontWarnPatterns = new HashSet<>();
     public boolean repackageWithNoMinification = false;
+    public boolean enableTestAssertions =
+        System.getProperty("com.android.tools.r8.enableTestAssertions") != null;
+    public boolean testEnableTestAssertions = false;
 
     public boolean allowConflictingSyntheticTypes = false;
 
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index 97a95be8..25d0a69 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -48,6 +48,7 @@
 
   public static final Consumer<InternalOptions> DEFAULT_OPTIONS =
       options -> {
+        options.testing.enableTestAssertions = true;
         options.testing.allowUnusedDontWarnRules = false;
         options.testing.allowUnnecessaryDontWarnWildcards = false;
         options.testing.reportUnusedProguardConfigurationRules = true;
diff --git a/src/test/java/com/android/tools/r8/TestingAssertionsTest.java b/src/test/java/com/android/tools/r8/TestingAssertionsTest.java
new file mode 100644
index 0000000..b2b64ec
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/TestingAssertionsTest.java
@@ -0,0 +1,65 @@
+// Copyright (c) 2021, 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;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticException;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.utils.AndroidApiLevel;
+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 TestingAssertionsTest extends TestBase {
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  public TestingAssertionsTest(TestParameters parameters) {}
+
+  @Test(expected = CompilationFailedException.class)
+  public void testR8() throws Exception {
+    testForR8(Backend.DEX)
+        .addInnerClasses(getClass())
+        .setMinApi(AndroidApiLevel.B)
+        .addKeepMainRule(Main.class)
+        .addOptionsModification(
+            options -> {
+              assertTrue(options.testing.enableTestAssertions);
+              options.testing.testEnableTestAssertions = true;
+            })
+        .compileWithExpectedDiagnostics(
+            diagnostics -> {
+              diagnostics.assertErrorThatMatches(diagnosticException(AssertionError.class));
+            });
+  }
+
+  @Test(expected = CompilationFailedException.class)
+  public void testD8() throws Exception {
+    testForD8(Backend.DEX)
+        .addInnerClasses(getClass())
+        .setMinApi(AndroidApiLevel.B)
+        .addOptionsModification(
+            options -> {
+              assertTrue(options.testing.enableTestAssertions);
+              options.testing.testEnableTestAssertions = true;
+            })
+        .compileWithExpectedDiagnostics(
+            diagnostics -> {
+              diagnostics.assertErrorThatMatches(diagnosticException(AssertionError.class));
+            });
+  }
+
+  public static class Main {
+
+    public static void main(String[] args) {
+      System.out.println("Hello World");
+    }
+  }
+}