Improve Nest-based control tests

Add more basic tests for nest based access control,
change tests so that as features are implemented
different parts of the tests can be set to successful.

Bug:130529338
Change-Id: I72b11edccb358e62739dfbaf7f86fd4de3cdf86e
diff --git a/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClass.java b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClass.java
deleted file mode 100644
index 06d328d..0000000
--- a/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClass.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// 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 nestHostExample;
-
-public class BasicNestHostWithInnerClass {
-
-  private String method() {
-    return "hostMethod";
-  }
-
-  private static String staticMethod() {
-    return "staticHostMethod";
-  }
-
-  private String field;
-  private static String staticField = "staticField";
-
-  private BasicNestHostWithInnerClass(String field) {
-    this.field = field;
-  }
-
-  public static BasicNestedClass createNestedInstance(String field) {
-    return new BasicNestedClass(field);
-  }
-
-  @SuppressWarnings("static-access") // we want to test that too.
-  public String accessNested(BasicNestedClass o) {
-    return o.field
-        + o.staticField
-        + BasicNestedClass.staticField
-        + o.method()
-        + o.staticMethod()
-        + BasicNestedClass.staticMethod();
-  }
-
-  public static class BasicNestedClass {
-    private String method() {
-      return "nestMethod";
-    }
-
-    private static String staticMethod() {
-      return "staticNestMethod";
-    }
-
-    private String field;
-    private static String staticField = "staticNestField";
-
-    private BasicNestedClass(String field) {
-      this.field = field;
-    }
-
-    public static BasicNestHostWithInnerClass createOuterInstance(String field) {
-      return new BasicNestHostWithInnerClass(field);
-    }
-
-    @SuppressWarnings("static-access") // we want to test that too.
-    public String accessOuter(BasicNestHostWithInnerClass o) {
-      return o.field
-          + o.staticField
-          + BasicNestedClass.staticField
-          + o.method()
-          + o.staticMethod()
-          + BasicNestedClass.staticMethod();
-    }
-
-  }
-  public static void main(String[] args) {
-    BasicNestHostWithInnerClass outer = BasicNestedClass.createOuterInstance("field");
-    BasicNestedClass inner = BasicNestHostWithInnerClass.createNestedInstance("nest1SField");
-
-    System.out.println(outer.accessNested(inner));
-    System.out.println(inner.accessOuter(outer));
-  }
-}
diff --git a/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassConstructors.java b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassConstructors.java
new file mode 100644
index 0000000..8b8f6ce
--- /dev/null
+++ b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassConstructors.java
@@ -0,0 +1,40 @@
+// 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 nestHostExample;
+
+public class BasicNestHostWithInnerClassConstructors {
+
+  public String field;
+
+  private BasicNestHostWithInnerClassConstructors(String field) {
+    this.field = field;
+  }
+
+  public static BasicNestedClass createNestedInstance(String field) {
+    return new BasicNestedClass(field);
+  }
+
+  public static class BasicNestedClass {
+
+    public String field;
+
+    private BasicNestedClass(String field) {
+      this.field = field;
+    }
+
+    public static BasicNestHostWithInnerClassConstructors createOuterInstance(String field) {
+      return new BasicNestHostWithInnerClassConstructors(field);
+    }
+  }
+
+  public static void main(String[] args) {
+    BasicNestHostWithInnerClassConstructors outer = BasicNestedClass.createOuterInstance("field");
+    BasicNestedClass inner =
+        BasicNestHostWithInnerClassConstructors.createNestedInstance("nest1SField");
+
+    System.out.println(outer.field);
+    System.out.println(inner.field);
+  }
+}
diff --git a/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassFields.java b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassFields.java
new file mode 100644
index 0000000..7244a15
--- /dev/null
+++ b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassFields.java
@@ -0,0 +1,35 @@
+// 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 nestHostExample;
+
+public class BasicNestHostWithInnerClassFields {
+
+  private String field = "field";
+  private static String staticField = "staticField";
+
+  @SuppressWarnings("static-access") // we want to test that too.
+  public String accessNested(BasicNestedClass o) {
+    return o.field + o.staticField + BasicNestedClass.staticField;
+  }
+
+  public static class BasicNestedClass {
+
+    private String field = "nestField";
+    private static String staticField = "staticNestField";
+
+    @SuppressWarnings("static-access") // we want to test that too.
+    public String accessOuter(BasicNestHostWithInnerClassFields o) {
+      return o.field + o.staticField + BasicNestedClass.staticField;
+    }
+  }
+
+  public static void main(String[] args) {
+    BasicNestHostWithInnerClassFields outer = new BasicNestHostWithInnerClassFields();
+    BasicNestedClass inner = new BasicNestedClass();
+
+    System.out.println(outer.accessNested(inner));
+    System.out.println(inner.accessOuter(outer));
+  }
+}
diff --git a/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassMethods.java b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassMethods.java
new file mode 100644
index 0000000..1313ef5
--- /dev/null
+++ b/src/test/examplesJava11/nestHostExample/BasicNestHostWithInnerClassMethods.java
@@ -0,0 +1,44 @@
+// 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 nestHostExample;
+
+public class BasicNestHostWithInnerClassMethods {
+
+  private String method() {
+    return "hostMethod";
+  }
+
+  private static String staticMethod() {
+    return "staticHostMethod";
+  }
+
+  @SuppressWarnings("static-access") // we want to test that too.
+  public String accessNested(BasicNestedClass o) {
+    return o.method() + o.staticMethod() + BasicNestedClass.staticMethod();
+  }
+
+  public static class BasicNestedClass {
+    private String method() {
+      return "nestMethod";
+    }
+
+    private static String staticMethod() {
+      return "staticNestMethod";
+    }
+
+    @SuppressWarnings("static-access") // we want to test that too.
+    public String accessOuter(BasicNestHostWithInnerClassMethods o) {
+      return o.method() + o.staticMethod() + BasicNestedClass.staticMethod();
+    }
+  }
+
+  public static void main(String[] args) {
+    BasicNestHostWithInnerClassMethods outer = new BasicNestHostWithInnerClassMethods();
+    BasicNestedClass inner = new BasicNestedClass();
+
+    System.out.println(outer.accessNested(inner));
+    System.out.println(inner.accessOuter(outer));
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java b/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java
index e43594c..004e971 100644
--- a/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/NestAccessControl/NestAccessControlTest.java
@@ -13,6 +13,7 @@
 
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.D8TestCompileResult;
+import com.android.tools.r8.D8TestRunResult;
 import com.android.tools.r8.R8TestCompileResult;
 import com.android.tools.r8.R8TestRunResult;
 import com.android.tools.r8.TestBase;
@@ -20,12 +21,13 @@
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.function.BiFunction;
@@ -38,26 +40,42 @@
 @RunWith(Parameterized.class)
 public class NestAccessControlTest extends TestBase {
 
-  private static final Path EXAMPLE_DIR = Paths.get(ToolHelper.EXAMPLES_JAVA11_BUILD_DIR);
-  private static final Path JAR = EXAMPLE_DIR.resolve("nestHostExample" + JAR_EXTENSION);
+  private static final Path JAR =
+      Paths.get(ToolHelper.EXAMPLES_JAVA11_BUILD_DIR).resolve("nestHostExample" + JAR_EXTENSION);
+  private static final String PACKAGE_NAME = "nestHostExample.";
+  private static final int NUMBER_OF_TEST_CLASSES = 15;
 
-  private static final String EXPECTED = StringUtils.lines(
-      "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
-      "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
-      "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
-      "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
-      "staticInterfaceMethodstaticStaticInterfaceMethod",
-      "staticInterfaceMethodstaticStaticInterfaceMethod",
-      "staticInterfaceMethodstaticStaticInterfaceMethod",
-      "staticInterfaceMethodstaticStaticInterfaceMethod");
-  private static final ImmutableMap<String, String> MAIN_CLASSES_AND_EXPECTED_RESULTS = ImmutableMap
-      .of(
-          "BasicNestHostWithInnerClass", StringUtils.lines(
-              "nest1SFieldstaticNestFieldstaticNestFieldnestMethodstaticNestMethodstaticNestMethod",
-              "fieldstaticFieldstaticNestFieldhostMethodstaticHostMethodstaticNestMethod"),
-          "BasicNestHostWithAnonymousInnerClass", StringUtils
-              .lines("fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethod"),
-          "NestHostExample", EXPECTED);
+  private static final ImmutableMap<String, String> MAIN_CLASSES =
+      ImmutableMap.of(
+          "fields", "BasicNestHostWithInnerClassFields",
+          "methods", "BasicNestHostWithInnerClassMethods",
+          "constructors", "BasicNestHostWithInnerClassConstructors",
+          "anonymous", "BasicNestHostWithAnonymousInnerClass",
+          "all", "NestHostExample");
+  private static final String ALL_EXPECTED_RESULT =
+      StringUtils.lines(
+          "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
+          "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
+          "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
+          "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethodnest1SFieldstaticNest1SFieldstaticNest1SFieldnest1SMethodstaticNest1SMethodstaticNest1SMethodnest2SFieldstaticNest2SFieldstaticNest2SFieldnest2SMethodstaticNest2SMethodstaticNest2SMethodnest1Fieldnest1Methodnest2Fieldnest2Method",
+          "staticInterfaceMethodstaticStaticInterfaceMethod",
+          "staticInterfaceMethodstaticStaticInterfaceMethod",
+          "staticInterfaceMethodstaticStaticInterfaceMethod",
+          "staticInterfaceMethodstaticStaticInterfaceMethod");
+  private static final ImmutableMap<String, String> EXPECTED_RESULTS =
+      ImmutableMap.of(
+          "fields",
+              StringUtils.lines(
+                  "nestFieldstaticNestFieldstaticNestField", "fieldstaticFieldstaticNestField"),
+          "methods",
+              StringUtils.lines(
+                  "nestMethodstaticNestMethodstaticNestMethod",
+                  "hostMethodstaticHostMethodstaticNestMethod"),
+          "constructors", StringUtils.lines("field", "nest1SField"),
+          "anonymous",
+              StringUtils.lines(
+                  "fieldstaticFieldstaticFieldhostMethodstaticHostMethodstaticHostMethod"),
+          "all", ALL_EXPECTED_RESULT);
 
   private static Function<AndroidApiLevel, D8TestCompileResult> d8CompilationResult =
       memoizeFunction(NestAccessControlTest::compileD8);
@@ -92,53 +110,87 @@
         .build();
   }
 
+  private static String getMainClass(String id){
+    return PACKAGE_NAME + MAIN_CLASSES.get(id);
+  }
+
+  private static String getExpectedResult(String id){
+    return EXPECTED_RESULTS.get(id);
+  }
+
+
   public NestAccessControlTest(TestParameters parameters) {
     this.parameters = parameters;
   }
 
-  @Test
-  public void testJavaAndD8() throws Exception {
-    for (ImmutableMap.Entry<String,String> entry : MAIN_CLASSES_AND_EXPECTED_RESULTS.entrySet()) {
-      if (parameters.isCfRuntime()) {
-        testForJvm()
-            .addProgramFiles(JAR)
-            .run(parameters.getRuntime(), "nestHostExample."+ entry.getKey())
-            .assertSuccessWithOutput(entry.getValue());
+  public void testJavaAndD8(String id, boolean d8Success) throws Exception {
+    if (parameters.isCfRuntime()) {
+      testForJvm()
+          .addProgramFiles(JAR)
+          .run(parameters.getRuntime(), getMainClass(id))
+          .assertSuccessWithOutput(getExpectedResult(id));
+    } else {
+      assert parameters.isDexRuntime();
+      D8TestRunResult run =
+          d8CompilationResult
+              .apply(parameters.getApiLevel())
+              .run(parameters.getRuntime(), getMainClass(id));
+      if (d8Success) {
+        run.assertSuccessWithOutput(getExpectedResult(id));
       } else {
-        assert parameters.isDexRuntime();
-        d8CompilationResult
-            .apply(parameters.getApiLevel())
-            .run(parameters.getRuntime(), "nestHostExample."+ entry.getKey())
-            // TODO(b/130529390): Assert expected once fixed.
-            .assertFailureWithErrorThatMatches(containsString("IllegalAccessError"));
+        if (parameters.isDexRuntime() &&
+            (parameters.getRuntime().asDex().getVm().getVersion() == Version.V6_0_1 ||
+                parameters.getRuntime().asDex().getVm().getVersion() == Version.V5_1_1)) {
+          run.assertFailure(); // different message, same error
+        } else {
+          run.assertFailureWithErrorThatMatches(containsString("IllegalAccessError"));
+        }
       }
     }
   }
 
   @Test
-  public void testR8() throws Exception {
-    for (ImmutableMap.Entry<String,String> entry : MAIN_CLASSES_AND_EXPECTED_RESULTS.entrySet()) {
-      R8TestRunResult result =
-          r8CompilationResult
-              .apply(parameters.getBackend(), parameters.getApiLevel())
-              .run(parameters.getRuntime(), "nestHostExample."+ entry.getKey());
-      if (parameters.isCfRuntime()) {
-        result.assertSuccessWithOutput(entry.getValue());
-        result.inspect(NestAccessControlTest::checkNestMateAttributes);
+  public void testJavaAndD8() throws Exception {
+    // TODO(b/130529390): As features are implemented, set success to true in each line.
+    testJavaAndD8("methods", false);
+    testJavaAndD8("fields", false);
+    testJavaAndD8("constructors", false);
+    testJavaAndD8("anonymous", false);
+    testJavaAndD8("all", false);
+  }
+
+  public void testR8(String id, boolean r8Success) throws Exception {
+    R8TestRunResult result =
+        r8CompilationResult
+            .apply(parameters.getBackend(), parameters.getApiLevel())
+            .run(parameters.getRuntime(), getMainClass(id));
+    if (r8Success) {
+      result.assertSuccessWithOutput(getExpectedResult(id));
+      result.inspect(NestAccessControlTest::checkNestMateAttributes);
+    } else {
+      if (parameters.isDexRuntime() &&
+          (parameters.getRuntime().asDex().getVm().getVersion() == Version.V6_0_1 ||
+              parameters.getRuntime().asDex().getVm().getVersion() == Version.V5_1_1)) {
+        result.assertFailure(); // different message, same error
       } else {
-        // TODO(b/130529390): Assert expected once fixed.
         result.assertFailureWithErrorThatMatches(containsString("IllegalAccessError"));
       }
     }
   }
 
+  @Test
+  public void testMethodsAccessR8() throws Exception {
+    // TODO(b/130529390): As features are implemented, set success to true in each line.
+    testR8("methods", parameters.isCfRuntime());
+    testR8("fields", parameters.isCfRuntime());
+    testR8("constructors", parameters.isCfRuntime());
+    testR8("anonymous", parameters.isCfRuntime());
+    testR8("all", parameters.isCfRuntime());
+  }
+
   private static void checkNestMateAttributes(CodeInspector inspector) {
-    assertEquals(11, inspector.allClasses().size());
-    ImmutableSet<String> outerClassNames =
-        ImmutableSet.of(
-            "NestHostExample",
-            "BasicNestHostWithInnerClass",
-            "BasicNestHostWithAnonymousInnerClass");
+    assertEquals(NUMBER_OF_TEST_CLASSES, inspector.allClasses().size());
+    ImmutableList<String> outerClassNames = MAIN_CLASSES.values().asList();
     inspector.forAllClasses(
         classSubject -> {
           DexClass dexClass = classSubject.getDexClass();