Add tests about inconsistent behavior of assume* rule propagation.

Bug: 133208961
Change-Id: I7d438a687f35d9098e88ac3d5aaf100336fa9eaa
diff --git a/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationWithSuperCallTest.java b/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationWithSuperCallTest.java
new file mode 100644
index 0000000..db581be
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/assumenosideeffects/AssumenosideeffectsPropagationWithSuperCallTest.java
@@ -0,0 +1,143 @@
+// Copyright (c) 2019, 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.shaking.assumenosideeffects;
+
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+class BaseClass {
+  void debug(String message) {
+    System.out.println("[Base] " + message);
+  }
+}
+
+class DelegateSub1 extends BaseClass {
+  // TODO(b/133208961): Should behave same with and without the following definition.
+  @Override
+  public void debug(String message) {
+    super.debug(message);
+  }
+}
+
+class DelegateSub2 extends BaseClass {
+  @Override
+  public void debug(String message) {
+    System.out.println("[Sub2] " + message);
+  }
+}
+
+class DelegatesUser {
+  static BaseClass createBase() {
+    return System.currentTimeMillis() > 0 ? new DelegateSub1() : new DelegateSub2();
+  }
+
+  public static void main(String... args) {
+    BaseClass instance = createBase();
+    instance.debug("message1");
+    System.out.println("The end");
+  }
+}
+
+@RunWith(Parameterized.class)
+public class AssumenosideeffectsPropagationWithSuperCallTest extends TestBase {
+  private static final Class<?> MAIN = DelegatesUser.class;
+  private static final List<Class<?>> CLASSES = ImmutableList.of(
+      MAIN, BaseClass.class, DelegateSub1.class, DelegateSub2.class);
+
+  private static final String JVM_OUTPUT = StringUtils.lines(
+      "[Base] message1",
+      "The end"
+  );
+  private static final String OUTPUT_WITHOUT_MESSAGES = StringUtils.lines(
+      "The end"
+  );
+
+  enum TestConfig {
+    SPECIFIC_RULES,
+    NON_SPECIFIC_RULES_WITH_EXTENDS;
+
+    public String getKeepRules() {
+      switch (this) {
+        case SPECIFIC_RULES:
+          return StringUtils.lines(
+              "-assumenosideeffects class **.*Sub* {",
+              "  *** debug(...);",
+              "}"
+          );
+        case NON_SPECIFIC_RULES_WITH_EXTENDS:
+          return StringUtils.lines(
+              "-assumenosideeffects class * extends **.BaseClass {",
+              "  *** debug(...);",
+              "}"
+          );
+        default:
+          throw new Unreachable();
+      }
+    }
+
+    public String expectedOutput(boolean isR8) {
+      if (!isR8) {
+        return OUTPUT_WITHOUT_MESSAGES;
+      }
+      switch (this) {
+        case SPECIFIC_RULES:
+        case NON_SPECIFIC_RULES_WITH_EXTENDS:
+          // TODO(b/133208961): If DelegateSub1#debug is not explicitly defined, we would not
+          //   propagate the rule, and thus the output would
+          // return JVM_OUTPUT;
+          return OUTPUT_WITHOUT_MESSAGES;
+        default:
+          throw new Unreachable();
+      }
+    }
+  }
+
+  private final TestParameters parameters;
+  private final TestConfig config;
+
+  @Parameterized.Parameters(name = "{0} {1}")
+  public static Collection<Object[]> data() {
+    return buildParameters(getTestParameters().withAllRuntimes().build(), TestConfig.values());
+  }
+
+  public AssumenosideeffectsPropagationWithSuperCallTest(
+      TestParameters parameters, TestConfig config) {
+    this.parameters = parameters;
+    this.config = config;
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClasses(CLASSES)
+        .addKeepMainRule(MAIN)
+        .addKeepRules(config.getKeepRules())
+        .noMinification()
+        .setMinApi(parameters.getRuntime())
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutput(config.expectedOutput(true));
+  }
+
+  @Test
+  public void testProguard() throws Exception {
+    assumeTrue(parameters.isCfRuntime());
+    testForProguard()
+        .addProgramClasses(CLASSES)
+        .addKeepMainRule(MAIN)
+        .addKeepRules(config.getKeepRules())
+        .noMinification()
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutput(config.expectedOutput(false));
+  }
+}