Move tests to java 17 package

Bug: b/363926134
Change-Id: Icb2a1cb7151c94ff74d5c8b7c7898085620baac0
diff --git a/src/test/examplesJava17/records/RecordShrinkField.java b/src/test/examplesJava17/records/RecordKeepRules.java
similarity index 73%
rename from src/test/examplesJava17/records/RecordShrinkField.java
rename to src/test/examplesJava17/records/RecordKeepRules.java
index 2a21904..a62132f 100644
--- a/src/test/examplesJava17/records/RecordShrinkField.java
+++ b/src/test/examplesJava17/records/RecordKeepRules.java
@@ -4,7 +4,9 @@
 
 package records;
 
-public class RecordShrinkField {
+// The code needs to be completely outside the test for the test to work.
+// If these classes are inner classes, age is not correctly simplified to a 42 constant field.
+public class RecordKeepRules {
 
   record Person(int unused, String name, int age) {
     Person(String name, int age) {
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordKeepRulesTest.java b/src/test/examplesJava17/records/RecordKeepRulesTest.java
similarity index 76%
rename from src/test/java/com/android/tools/r8/desugar/records/RecordKeepRulesTest.java
rename to src/test/examplesJava17/records/RecordKeepRulesTest.java
index 68c85df..cf864fe 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordKeepRulesTest.java
+++ b/src/test/examplesJava17/records/RecordKeepRulesTest.java
@@ -2,8 +2,9 @@
 // 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.desugar.records;
+package records;
 
+import com.android.tools.r8.JdkClassFileProvider;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -17,30 +18,26 @@
 @RunWith(Parameterized.class)
 public class RecordKeepRulesTest extends TestBase {
 
-  private static final String RECORD_NAME = "RecordShrinkField";
-  private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
-  private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
-
   private static final String KEEP_RULE_CLASS_NAME =
-      "-keep,allowshrinking,allowoptimization class records.RecordShrinkField$Person";
+      "-keep,allowshrinking,allowoptimization class records.RecordKeepRules$Person";
   private static final String KEEP_RULE_FIELD_NAMES =
-      "-keepclassmembers,allowshrinking,allowoptimization class records.RecordShrinkField$Person {"
+      "-keepclassmembers,allowshrinking,allowoptimization class records.RecordKeepRules$Person {"
           + " <fields>; }";
   private static final String KEEP_RULE_FIELDS_NO_NAMES =
-      "-keepclassmembers,allowobfuscation class records.RecordShrinkField$Person { <fields>; }";
+      "-keepclassmembers,allowobfuscation class records.RecordKeepRules$Person { <fields>; }";
   private static final String KEEP_RULE_ALL =
-      "-keep class records.RecordShrinkField$Person { <fields>; }";
+      "-keep class records.RecordKeepRules$Person { <fields>; }";
 
   private static final String EXPECTED_RESULT_R8_WITH_CLASS_NAME =
-      StringUtils.lines("RecordShrinkField$Person[a=Jane Doe]", "RecordShrinkField$Person[a=Bob]");
+      StringUtils.lines("RecordKeepRules$Person[a=Jane Doe]", "RecordKeepRules$Person[a=Bob]");
   private static final String EXPECTED_RESULT_R8_WITH_FIELD_NAMES =
       StringUtils.lines("a[name=Jane Doe]", "a[name=Bob]");
   private static final String EXPECTED_RESULT_R8_WITH_FIELD_NO_NAMES =
       StringUtils.lines("a[a=-1, b=Jane Doe, c=42]", "a[a=-1, b=Bob, c=42]");
   private static final String EXPECTED_RESULT_R8_WITH_ALL =
       StringUtils.lines(
-          "RecordShrinkField$Person[unused=-1, name=Jane Doe, age=42]",
-          "RecordShrinkField$Person[unused=-1, name=Bob, age=42]");
+          "RecordKeepRules$Person[unused=-1, name=Jane Doe, age=42]",
+          "RecordKeepRules$Person[unused=-1, name=Bob, age=42]");
 
   private final TestParameters parameters;
   private final boolean proguardCompatibility;
@@ -82,27 +79,27 @@
 
   private void testR8FieldNames(String keepRules, String expectedOutput) throws Exception {
     testForR8Compat(parameters.getBackend(), proguardCompatibility)
-        .addProgramClassFileData(PROGRAM_DATA)
+        .addProgramClassesAndInnerClasses(RecordKeepRules.class)
         .setMinApi(parameters)
-        .addKeepMainRule(MAIN_TYPE)
+        .addKeepMainRule(RecordKeepRules.class)
         .addKeepRules(keepRules)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), RecordKeepRules.class)
         .assertSuccessWithOutput(expectedOutput);
   }
 
   private void testR8CfThenDexFieldNames(String keepRules, String expectedOutput) throws Exception {
     Path desugared =
         testForR8Compat(Backend.CF, proguardCompatibility)
-            .addProgramClassFileData(PROGRAM_DATA)
-            .addKeepMainRule(MAIN_TYPE)
+            .addProgramClassesAndInnerClasses(RecordKeepRules.class)
+            .addKeepMainRule(RecordKeepRules.class)
             .addKeepRules(keepRules)
-            .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+            .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
             .compile()
             .writeToZip();
     testForD8(parameters.getBackend())
         .addProgramFiles(desugared)
         .setMinApi(parameters)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), RecordKeepRules.class)
         .assertSuccessWithOutput(expectedOutput);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java b/src/test/examplesJava17/records/RecordProfileRewritingTest.java
similarity index 86%
rename from src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java
rename to src/test/examplesJava17/records/RecordProfileRewritingTest.java
index 602cdfc..13c5b5a 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/RecordProfileRewritingTest.java
+++ b/src/test/examplesJava17/records/RecordProfileRewritingTest.java
@@ -2,7 +2,7 @@
 // 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.profile.art.completeness;
+package records;
 
 import static com.android.tools.r8.ir.desugar.records.RecordFullInstructionDesugaring.EQUALS_RECORD_METHOD_NAME;
 import static com.android.tools.r8.ir.desugar.records.RecordFullInstructionDesugaring.GET_FIELDS_AS_OBJECTS_METHOD_NAME;
@@ -16,11 +16,11 @@
 import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.D8TestCompileResult;
+import com.android.tools.r8.JdkClassFileProvider;
 import com.android.tools.r8.R8TestCompileResult;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.desugar.records.RecordTestUtils;
 import com.android.tools.r8.profile.art.model.ExternalArtProfile;
 import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
 import com.android.tools.r8.references.ClassReference;
@@ -43,26 +43,12 @@
 @RunWith(Parameterized.class)
 public class RecordProfileRewritingTest extends TestBase {
 
-  private static final String RECORD_NAME = "SimpleRecord";
-  private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
   private static final String EXPECTED_RESULT =
       StringUtils.lines(
-          "Jane Doe",
-          "42",
-          "Jane Doe",
-          "42",
-          "true",
-          "true",
-          "true",
-          "false",
-          "false",
-          "false",
-          "false");
+          "Jane Doe", "42", "true", "true", "true", "false", "false", "false", "false");
 
-  private static final ClassReference MAIN_REFERENCE =
-      Reference.classFromTypeName(RecordTestUtils.getMainType(RECORD_NAME));
-  private static final ClassReference PERSON_REFERENCE =
-      Reference.classFromTypeName(MAIN_REFERENCE.getTypeName() + "$Person");
+  private static final ClassReference MAIN_REFERENCE = Reference.classFromClass(SimpleRecord.class);
+  private static final ClassReference PERSON_REFERENCE = Reference.classFromClass(Person.class);
   private static final ClassReference RECORD_REFERENCE =
       Reference.classFromTypeName("java.lang.Record");
   private static final ClassReference OBJECT_REFERENCE = Reference.classFromClass(Object.class);
@@ -81,7 +67,7 @@
     parameters.assumeJvmTestParameters();
     assumeTrue(runtimeWithRecordsSupport(parameters.getRuntime()));
     testForJvm(parameters)
-        .addProgramClassFileData(PROGRAM_DATA)
+        .addInnerClassesAndStrippedOuter(getClass())
         .run(parameters.getRuntime(), MAIN_REFERENCE.getTypeName())
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
@@ -90,7 +76,7 @@
   public void testD8() throws Exception {
     D8TestCompileResult compileResult =
         testForD8(parameters.getBackend())
-            .addProgramClassFileData(PROGRAM_DATA)
+            .addInnerClassesAndStrippedOuter(getClass())
             .addArtProfileForRewriting(getArtProfile())
             .setMinApi(parameters)
             .compile();
@@ -114,7 +100,7 @@
     assumeTrue(runtimeWithRecordsSupport(parameters.getRuntime()) || parameters.isDexRuntime());
     R8TestCompileResult compileResult =
         testForR8(parameters.getBackend())
-            .addProgramClassFileData(PROGRAM_DATA)
+            .addInnerClassesAndStrippedOuter(getClass())
             .addKeepMainRule(MAIN_REFERENCE.getTypeName())
             .addKeepRules(
                 "-neverpropagatevalue class " + PERSON_REFERENCE.getTypeName() + " { <fields>; }")
@@ -122,8 +108,7 @@
             .addOptionsModification(InlinerOptions::disableInlining)
             .applyIf(
                 parameters.isCfRuntime(),
-                testBuilder ->
-                    testBuilder.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)))
+                testBuilder -> testBuilder.addLibraryProvider(JdkClassFileProvider.fromSystemJdk()))
             .enableProguardTestOptions()
             .noHorizontalClassMergingOfSynthetics()
             .setMinApi(parameters)
@@ -218,7 +203,7 @@
                 : recordTagClassSubject.asTypeSubject(),
         personRecordClassSubject.getSuperType());
     assertEquals(
-        recordDesugaringIsOff ? 6 : (canMergeRecordTag && !partialDesugaring) ? 11 : 10,
+        recordDesugaringIsOff ? 6 : (canMergeRecordTag && !partialDesugaring) ? 9 : 8,
         personRecordClassSubject.allMethods().size());
 
     MethodSubject personDefaultInstanceInitializerSubject = personRecordClassSubject.init();
@@ -236,24 +221,10 @@
     MethodSubject nameMethodSubject = personRecordClassSubject.uniqueMethodWithOriginalName("name");
     assertThat(nameMethodSubject, isPresent());
 
-    MethodSubject nameNestAccessorMethodSubject =
-        personRecordClassSubject.uniqueMethodWithOriginalName(
-            SyntheticItemsTestUtils.syntheticNestInstanceFieldGetter(
-                    Reference.field(PERSON_REFERENCE, "name", STRING_REFERENCE))
-                .getMethodName());
-    assertThat(nameNestAccessorMethodSubject, isAbsentIf(canUseNestBasedAccesses));
-
     // Age getters.
     MethodSubject ageMethodSubject = personRecordClassSubject.uniqueMethodWithOriginalName("age");
     assertThat(ageMethodSubject, isPresent());
 
-    MethodSubject ageNestAccessorMethodSubject =
-        personRecordClassSubject.uniqueMethodWithOriginalName(
-            SyntheticItemsTestUtils.syntheticNestInstanceFieldGetter(
-                    Reference.field(PERSON_REFERENCE, "age", Reference.INT))
-                .getMethodName());
-    assertThat(ageNestAccessorMethodSubject, isAbsentIf(canUseNestBasedAccesses));
-
     // boolean equals(Object)
     MethodSubject getFieldsAsObjectsMethodSubject =
         personRecordClassSubject.uniqueMethodWithOriginalName(GET_FIELDS_AS_OBJECTS_METHOD_NAME);
@@ -272,7 +243,7 @@
 
     // int hashCode()
     ClassSubject hashCodeHelperClassSubject =
-        inspector.clazz(SyntheticItemsTestUtils.syntheticRecordHelperClass(PERSON_REFERENCE, 1));
+        inspector.clazz(SyntheticItemsTestUtils.syntheticRecordHelperClass(PERSON_REFERENCE, 0));
     assertThat(hashCodeHelperClassSubject, isAbsentIf(recordDesugaringIsOff));
 
     MethodSubject hashCodeHelperMethodSubject = hashCodeHelperClassSubject.uniqueMethod();
@@ -290,7 +261,7 @@
 
     // String toString()
     ClassSubject toStringHelperClassSubject =
-        inspector.clazz(SyntheticItemsTestUtils.syntheticRecordHelperClass(PERSON_REFERENCE, 0));
+        inspector.clazz(SyntheticItemsTestUtils.syntheticRecordHelperClass(PERSON_REFERENCE, 1));
     assertThat(toStringHelperClassSubject, isAbsentIf(recordDesugaringIsOff));
 
     MethodSubject toStringHelperMethodSubject = toStringHelperClassSubject.uniqueMethod();
@@ -317,11 +288,6 @@
             hashCodeMethodSubject,
             toStringMethodSubject)
         .applyIf(
-            !canUseNestBasedAccesses,
-            i ->
-                i.assertContainsMethodRules(
-                    nameNestAccessorMethodSubject, ageNestAccessorMethodSubject))
-        .applyIf(
             canMergeRecordTag && !partialDesugaring,
             i -> i.assertContainsMethodRule(personDefaultInstanceInitializerSubject))
         .applyIf(
@@ -340,4 +306,32 @@
                         toStringHelperMethodSubject))
         .assertContainsNoOtherRules();
   }
+
+  record Person(String name, int age) {}
+
+  public class SimpleRecord {
+
+    public static void main(String[] args) {
+      Person janeDoe = new Person("Jane Doe", 42);
+      System.out.println(janeDoe.name());
+      System.out.println(janeDoe.age());
+
+      // Test equals with self.
+      System.out.println(janeDoe.equals(janeDoe));
+
+      // Test equals with structurally equals Person.
+      Person otherJaneDoe = new Person("Jane Doe", 42);
+      System.out.println(janeDoe.equals(otherJaneDoe));
+      System.out.println(otherJaneDoe.equals(janeDoe));
+
+      // Test equals with not-structually equals Person.
+      Person johnDoe = new Person("John Doe", 42);
+      System.out.println(janeDoe.equals(johnDoe));
+      System.out.println(johnDoe.equals(janeDoe));
+
+      // Test equals with Object and null.
+      System.out.println(janeDoe.equals(new Object()));
+      System.out.println(janeDoe.equals(null));
+    }
+  }
 }
diff --git a/src/test/examplesJava17/records/RecordReflection.java b/src/test/examplesJava17/records/RecordReflection.java
deleted file mode 100644
index 1b94a12..0000000
--- a/src/test/examplesJava17/records/RecordReflection.java
+++ /dev/null
@@ -1,29 +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 records;
-
-import java.util.Arrays;
-
-public class RecordReflection {
-
-  record Empty(){}
-
-  record Person(String name, int age) {}
-
-  record PersonGeneric <S extends CharSequence>(S name, int age) {}
-
-  public static void main(String[] args) {
-    System.out.println(Empty.class.isRecord());
-    System.out.println(Arrays.toString(Empty.class.getRecordComponents()));
-    System.out.println(Person.class.isRecord());
-    System.out.println(Arrays.toString(Person.class.getRecordComponents()));
-    System.out.println(PersonGeneric.class.isRecord());
-    System.out.println(Arrays.toString(PersonGeneric.class.getRecordComponents()));
-    System.out.println(Arrays.toString(PersonGeneric.class.getTypeParameters()));
-    System.out.println(Object.class.isRecord());
-    System.out.println(Arrays.toString(Object.class.getRecordComponents()));
-  }
-
-}
diff --git a/src/test/examplesJava17/records/RecordReflectionTest.java b/src/test/examplesJava17/records/RecordReflectionTest.java
new file mode 100644
index 0000000..bab9fb7
--- /dev/null
+++ b/src/test/examplesJava17/records/RecordReflectionTest.java
@@ -0,0 +1,89 @@
+// 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 records;
+
+import com.android.tools.r8.JdkClassFileProvider;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.utils.StringUtils;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class RecordReflectionTest extends TestBase {
+
+  private static final String EXPECTED_RESULT =
+      StringUtils.lines(
+          "true",
+          "[]",
+          "true",
+          "[java.lang.String name, int age]",
+          "true",
+          "[java.lang.CharSequence name, int age]",
+          "[S]",
+          "false",
+          "null");
+
+  private final TestParameters parameters;
+
+  public RecordReflectionTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withCfRuntimesStartingFromIncluding(CfVm.JDK17).build();
+  }
+
+  @Test
+  public void testJvm() throws Exception {
+    parameters.assumeJvmTestParameters();
+    testForJvm(parameters)
+        .addInnerClassesAndStrippedOuter(getClass())
+        .run(parameters.getRuntime(), RecordReflection.class)
+        .assertSuccessWithOutput(EXPECTED_RESULT);
+  }
+
+  @Test
+  public void testR8Cf() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClassesAndStrippedOuter(getClass())
+        .setMinApi(parameters)
+        .addKeepMainRule(RecordReflection.class)
+        .addKeepAllAttributes()
+        .addKeepRules("-keep class * extends java.lang.Record { private final <fields>; }")
+        .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
+        .compile()
+        .inspect(RecordTestUtils::assertRecordsAreRecords)
+        .enableJVMPreview()
+        .run(parameters.getRuntime(), RecordReflection.class)
+        .assertSuccessWithOutput(EXPECTED_RESULT);
+  }
+
+  record Empty() {}
+
+  record Person(String name, int age) {}
+
+  record PersonGeneric<S extends CharSequence>(S name, int age) {}
+
+  public class RecordReflection {
+
+    public static void main(String[] args) {
+      System.out.println(Empty.class.isRecord());
+      System.out.println(Arrays.toString(Empty.class.getRecordComponents()));
+      System.out.println(Person.class.isRecord());
+      System.out.println(Arrays.toString(Person.class.getRecordComponents()));
+      System.out.println(PersonGeneric.class.isRecord());
+      System.out.println(Arrays.toString(PersonGeneric.class.getRecordComponents()));
+      System.out.println(Arrays.toString(PersonGeneric.class.getTypeParameters()));
+      System.out.println(Object.class.isRecord());
+      System.out.println(Arrays.toString(Object.class.getRecordComponents()));
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java b/src/test/examplesJava17/records/RecordShrinkFieldTest.java
similarity index 72%
rename from src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
rename to src/test/examplesJava17/records/RecordShrinkFieldTest.java
index e8587ca..232f02f 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
+++ b/src/test/examplesJava17/records/RecordShrinkFieldTest.java
@@ -2,10 +2,11 @@
 // 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.desugar.records;
+package records;
 
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.JdkClassFileProvider;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.BooleanUtils;
@@ -22,17 +23,13 @@
 @RunWith(Parameterized.class)
 public class RecordShrinkFieldTest extends TestBase {
 
-  private static final String RECORD_NAME = "RecordShrinkField";
-  private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
-  private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
-
   private static final String EXPECTED_RESULT_D8 =
       StringUtils.lines(
           "Person[unused=-1, name=Jane Doe, age=42]", "Person[unused=-1, name=Bob, age=42]");
   private static final String EXPECTED_RESULT_R8 = StringUtils.lines("a[a=Jane Doe]", "a[a=Bob]");
   private static final String EXPECTED_RESULT_R8_NO_MINIFICATION =
       StringUtils.lines(
-          "RecordShrinkField$Person[name=Jane Doe]", "RecordShrinkField$Person[name=Bob]");
+          "RecordShrinkFieldTest$Person[name=Jane Doe]", "RecordShrinkFieldTest$Person[name=Bob]");
 
   private final TestParameters parameters;
   private final boolean minifying;
@@ -53,10 +50,10 @@
   public void testD8() throws Exception {
     Assume.assumeTrue("Only valid in R8", minifying);
     testForD8(parameters.getBackend())
-        .addProgramClassFileData(PROGRAM_DATA)
+        .addInnerClassesAndStrippedOuter(getClass())
         .setMinApi(parameters)
         .compile()
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), RecordShrinkField.class)
         .assertSuccessWithOutput(EXPECTED_RESULT_D8);
   }
 
@@ -64,13 +61,13 @@
   public void testR8() throws Exception {
     parameters.assumeR8TestParameters();
     testForR8(parameters.getBackend())
-        .addProgramClassFileData(PROGRAM_DATA)
+        .addInnerClassesAndStrippedOuter(getClass())
         .setMinApi(parameters)
-        .addKeepMainRule(MAIN_TYPE)
+        .addKeepMainRule(RecordShrinkField.class)
         .addDontObfuscateUnless(minifying)
         .compile()
         .inspect(inspector -> inspect(inspector, false))
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), RecordShrinkField.class)
         .assertSuccessWithOutput(
             minifying ? EXPECTED_RESULT_R8 : EXPECTED_RESULT_R8_NO_MINIFICATION);
   }
@@ -80,28 +77,27 @@
     parameters.assumeR8TestParameters();
     Path desugared =
         testForR8(Backend.CF)
-            .addProgramClassFileData(PROGRAM_DATA)
-            .addKeepMainRule(MAIN_TYPE)
+            .addInnerClassesAndStrippedOuter(getClass())
+            .addKeepMainRule(RecordShrinkField.class)
             .addDontObfuscateUnless(minifying)
-            .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+            .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
             .compile()
             .writeToZip();
     testForR8(parameters.getBackend())
         .addProgramFiles(desugared)
         .setMinApi(parameters)
-        .addKeepMainRule(MAIN_TYPE)
+        .addKeepMainRule(RecordShrinkField.class)
         .addDontObfuscateUnless(minifying)
         .compile()
         .inspect(inspector -> inspect(inspector, true))
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), RecordShrinkField.class)
         .assertSuccessWithOutput(
             minifying ? EXPECTED_RESULT_R8 : EXPECTED_RESULT_R8_NO_MINIFICATION);
   }
 
   private void inspect(CodeInspector inspector, boolean isCfThenDex) {
-    ClassSubject recordClass =
-        inspector.clazz(minifying ? "records.a" : "records.RecordShrinkField$Person");
-    if (isCfThenDex || !minifying) {
+    ClassSubject recordClass = inspector.clazz(Person.class);
+    if (!isCfThenDex || !minifying) {
       assertEquals(1, recordClass.allInstanceFields().size());
       assertEquals(
           "java.lang.String", recordClass.allInstanceFields().get(0).getField().type().toString());
@@ -109,4 +105,20 @@
       assertEquals(0, recordClass.allInstanceFields().size());
     }
   }
+
+  record Person(int unused, String name, int age) {
+    Person(String name, int age) {
+      this(-1, name, age);
+    }
+  }
+
+  public class RecordShrinkField {
+
+    public static void main(String[] args) {
+      Person jane = new Person("Jane Doe", 42);
+      Person bob = new Person("Bob", 42);
+      System.out.println(jane);
+      System.out.println(bob);
+    }
+  }
 }
diff --git a/src/test/examplesJava17/records/SimpleRecord.java b/src/test/examplesJava17/records/SimpleRecord.java
deleted file mode 100644
index 3f908dc..0000000
--- a/src/test/examplesJava17/records/SimpleRecord.java
+++ /dev/null
@@ -1,35 +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 records;
-
-public class SimpleRecord {
-
-  record Person(String name, int age) {}
-
-  public static void main(String[] args) {
-    Person janeDoe = new Person("Jane Doe", 42);
-    System.out.println(janeDoe.name);
-    System.out.println(janeDoe.age);
-    System.out.println(janeDoe.name());
-    System.out.println(janeDoe.age());
-
-    // Test equals with self.
-    System.out.println(janeDoe.equals(janeDoe));
-
-    // Test equals with structurally equals Person.
-    Person otherJaneDoe = new Person("Jane Doe", 42);
-    System.out.println(janeDoe.equals(otherJaneDoe));
-    System.out.println(otherJaneDoe.equals(janeDoe));
-
-    // Test equals with not-structually equals Person.
-    Person johnDoe = new Person("John Doe", 42);
-    System.out.println(janeDoe.equals(johnDoe));
-    System.out.println(johnDoe.equals(janeDoe));
-
-    // Test equals with Object and null.
-    System.out.println(janeDoe.equals(new Object()));
-    System.out.println(janeDoe.equals(null));
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java b/src/test/examplesJava17/records/SimpleRecordTest.java
similarity index 72%
rename from src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
rename to src/test/examplesJava17/records/SimpleRecordTest.java
index 088beb3..d7c8131 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/SimpleRecordTest.java
+++ b/src/test/examplesJava17/records/SimpleRecordTest.java
@@ -2,14 +2,14 @@
 // 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.desugar.records;
+package records;
 
-import static com.android.tools.r8.desugar.records.RecordTestUtils.assertNoJavaLangRecord;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.GlobalSyntheticsConsumer;
 import com.android.tools.r8.GlobalSyntheticsTestingConsumer;
+import com.android.tools.r8.JdkClassFileProvider;
 import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
@@ -28,22 +28,9 @@
 @RunWith(Parameterized.class)
 public class SimpleRecordTest extends TestBase {
 
-  private static final String RECORD_NAME = "SimpleRecord";
-  private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
-  private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
   private static final String EXPECTED_RESULT =
       StringUtils.lines(
-          "Jane Doe",
-          "42",
-          "Jane Doe",
-          "42",
-          "true",
-          "true",
-          "true",
-          "false",
-          "false",
-          "false",
-          "false");
+          "Jane Doe", "42", "true", "true", "true", "false", "false", "false", "false");
 
   @Parameter(0)
   public TestParameters parameters;
@@ -69,8 +56,8 @@
     assumeTrue(isCfRuntimeWithNativeRecordSupport());
     assumeFalse(forceInvokeRangeForInvokeCustom);
     testForJvm(parameters)
-        .addProgramClassFileData(PROGRAM_DATA)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .addInnerClassesAndStrippedOuter(getClass())
+        .run(parameters.getRuntime(), SimpleRecord.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
@@ -78,13 +65,13 @@
   public void testD8() throws Exception {
     assumeFalse(forceInvokeRangeForInvokeCustom);
     testForD8(parameters.getBackend())
-        .addProgramClassFileData(PROGRAM_DATA)
+        .addInnerClassesAndStrippedOuter(getClass())
         .setMinApi(parameters)
         .compile()
         .inspectWithOptions(
-            i -> assertNoJavaLangRecord(i, parameters),
+            i -> RecordTestUtils.assertNoJavaLangRecord(i, parameters),
             options -> options.testing.disableRecordApplicationReaderMap = true)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), SimpleRecord.class)
         .applyIf(
             isRecordsFullyDesugaredForD8(parameters)
                 || runtimeWithRecordsSupport(parameters.getRuntime()),
@@ -108,7 +95,7 @@
                     .addGlobalSyntheticsResourceProviders(globals.getIndexedModeProvider()))
         .setMinApi(parameters)
         .setIncludeClassesChecksum(true)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), SimpleRecord.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
@@ -129,14 +116,14 @@
         .setMinApi(parameters)
         .setIncludeClassesChecksum(true)
         .disableDesugaring()
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), SimpleRecord.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
   private Path compileIntermediate(GlobalSyntheticsConsumer globalSyntheticsConsumer)
       throws Exception {
     return testForD8(Backend.DEX)
-        .addProgramClassFileData(PROGRAM_DATA)
+        .addInnerClassesAndStrippedOuter(getClass())
         .setMinApi(parameters)
         .setIntermediate(true)
         .setIncludeClassesChecksum(true)
@@ -156,25 +143,25 @@
                 opptions ->
                     opptions.testing.forceInvokeRangeForInvokeCustom =
                         forceInvokeRangeForInvokeCustom)
-            .addProgramClassFileData(PROGRAM_DATA)
+            .addInnerClassesAndStrippedOuter(getClass())
             .setMinApi(parameters)
-            .addKeepMainRule(MAIN_TYPE);
+            .addKeepMainRule(SimpleRecord.class);
     if (parameters.isCfRuntime()) {
       builder
-          .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+          .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
           .compile()
           .inspect(RecordTestUtils::assertRecordsAreRecords)
-          .inspect(inspector -> inspector.clazz("records.SimpleRecord$Person").isRenamed())
-          .run(parameters.getRuntime(), MAIN_TYPE)
+          .inspect(inspector -> inspector.clazz(Person.class).isRenamed())
+          .run(parameters.getRuntime(), SimpleRecord.class)
           .assertSuccessWithOutput(EXPECTED_RESULT);
       return;
     }
     builder
         .compile()
         .inspectWithOptions(
-            i -> assertNoJavaLangRecord(i, parameters),
+            i -> RecordTestUtils.assertNoJavaLangRecord(i, parameters),
             options -> options.testing.disableRecordApplicationReaderMap = true)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), SimpleRecord.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
@@ -185,25 +172,53 @@
     assumeTrue(forceInvokeRangeForInvokeCustom || !parameters.isDexRuntime());
     R8FullTestBuilder builder =
         testForR8(parameters.getBackend())
-            .addProgramClassFileData(PROGRAM_DATA)
+            .addInnerClassesAndStrippedOuter(getClass())
             .addDontObfuscate()
             .setMinApi(parameters)
-            .addKeepMainRule(MAIN_TYPE);
+            .addKeepMainRule(SimpleRecord.class);
     if (parameters.isCfRuntime()) {
       builder
-          .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
+          .addLibraryProvider(JdkClassFileProvider.fromSystemJdk())
           .compile()
           .inspect(RecordTestUtils::assertRecordsAreRecords)
-          .run(parameters.getRuntime(), MAIN_TYPE)
+          .run(parameters.getRuntime(), SimpleRecord.class)
           .assertSuccessWithOutput(EXPECTED_RESULT);
       return;
     }
     builder
         .compile()
         .inspectWithOptions(
-            i -> assertNoJavaLangRecord(i, parameters),
+            i -> RecordTestUtils.assertNoJavaLangRecord(i, parameters),
             options -> options.testing.disableRecordApplicationReaderMap = true)
-        .run(parameters.getRuntime(), MAIN_TYPE)
+        .run(parameters.getRuntime(), SimpleRecord.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
+
+  record Person(String name, int age) {}
+
+  public class SimpleRecord {
+
+    public static void main(String[] args) {
+      Person janeDoe = new Person("Jane Doe", 42);
+      System.out.println(janeDoe.name());
+      System.out.println(janeDoe.age());
+
+      // Test equals with self.
+      System.out.println(janeDoe.equals(janeDoe));
+
+      // Test equals with structurally equals Person.
+      Person otherJaneDoe = new Person("Jane Doe", 42);
+      System.out.println(janeDoe.equals(otherJaneDoe));
+      System.out.println(otherJaneDoe.equals(janeDoe));
+
+      // Test equals with not-structually equals Person.
+      Person johnDoe = new Person("John Doe", 42);
+      System.out.println(janeDoe.equals(johnDoe));
+      System.out.println(johnDoe.equals(janeDoe));
+
+      // Test equals with Object and null.
+      System.out.println(janeDoe.equals(new Object()));
+      System.out.println(janeDoe.equals(null));
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
deleted file mode 100644
index 6a63449..0000000
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordReflectionTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.desugar.records;
-
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.desugar.LibraryFilesHelper;
-import com.android.tools.r8.utils.StringUtils;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class RecordReflectionTest extends TestBase {
-
-  private static final String RECORD_NAME = "RecordReflection";
-  private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
-  private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
-  private static final String EXPECTED_RESULT =
-      StringUtils.lines(
-          "true",
-          "[]",
-          "true",
-          "[java.lang.String name, int age]",
-          "true",
-          "[java.lang.CharSequence name, int age]",
-          "[S]",
-          "false",
-          "null");
-
-  private final TestParameters parameters;
-
-  public RecordReflectionTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withCfRuntimesStartingFromIncluding(CfVm.JDK17).build();
-  }
-
-  @Test
-  public void testJvm() throws Exception {
-    parameters.assumeJvmTestParameters();
-    testForJvm(parameters)
-        .addProgramClassFileData(PROGRAM_DATA)
-        .run(parameters.getRuntime(), MAIN_TYPE)
-        .assertSuccessWithOutput(EXPECTED_RESULT);
-  }
-
-  @Test
-  public void testR8Cf() throws Exception {
-    testForR8(parameters.getBackend())
-        .addProgramClassFileData(PROGRAM_DATA)
-        .setMinApi(parameters)
-        .addKeepMainRule(MAIN_TYPE)
-        .addKeepAllAttributes()
-        .addKeepRules("-keep class * extends java.lang.Record { private final <fields>; }")
-        .addLibraryFiles(LibraryFilesHelper.getJdk15LibraryFiles(temp))
-        .compile()
-        .inspect(RecordTestUtils::assertRecordsAreRecords)
-        .enableJVMPreview()
-        .run(parameters.getRuntime(), MAIN_TYPE)
-        .assertSuccessWithOutput(EXPECTED_RESULT);
-  }
-}