Disallow diagnostic messages, stdout and stderr by default in tests
Bug: 122819270
Change-Id: I34dc74b33ed8e306dcfa51c0ee7c2bfa680e2442
diff --git a/src/test/java/com/android/tools/r8/D8TestCompileResult.java b/src/test/java/com/android/tools/r8/D8TestCompileResult.java
index 117ca7b..80b23ac 100644
--- a/src/test/java/com/android/tools/r8/D8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/D8TestCompileResult.java
@@ -24,6 +24,16 @@
}
@Override
+ public String getStdout() {
+ return state.getStdout();
+ }
+
+ @Override
+ public String getStderr() {
+ return state.getStderr();
+ }
+
+ @Override
public D8TestRunResult createRunResult(TestRuntime runtime, ProcessResult result) {
return new D8TestRunResult(app, runtime, result);
}
diff --git a/src/test/java/com/android/tools/r8/DXTestCompileResult.java b/src/test/java/com/android/tools/r8/DXTestCompileResult.java
index 3cf9b73..e362f78 100644
--- a/src/test/java/com/android/tools/r8/DXTestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/DXTestCompileResult.java
@@ -4,6 +4,7 @@
package com.android.tools.r8;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApp;
public class DXTestCompileResult extends TestCompileResult<DXTestCompileResult, DXTestRunResult> {
@@ -23,6 +24,16 @@
}
@Override
+ public String getStdout() {
+ throw new Unimplemented("Unexpected attempt to access stdout from dx");
+ }
+
+ @Override
+ public String getStderr() {
+ throw new Unimplemented("Unexpected attempt to access stderr from dx");
+ }
+
+ @Override
public DXTestRunResult createRunResult(TestRuntime runtime, ProcessResult result) {
return new DXTestRunResult(app, runtime, result);
}
diff --git a/src/test/java/com/android/tools/r8/DumpInputsTest.java b/src/test/java/com/android/tools/r8/DumpInputsTest.java
index e7f2ef8..84febed 100644
--- a/src/test/java/com/android/tools/r8/DumpInputsTest.java
+++ b/src/test/java/com/android/tools/r8/DumpInputsTest.java
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.utils.DescriptorUtils;
-import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.ZipUtils;
import java.io.IOException;
import java.nio.file.Files;
@@ -24,8 +24,6 @@
@RunWith(Parameterized.class)
public class DumpInputsTest extends TestBase {
- static final String EXPECTED = StringUtils.lines("Hello, world");
-
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
@@ -62,6 +60,9 @@
.addLibraryFiles(ToolHelper.getJava8RuntimeJar())
.addKeepMainRule(TestClass.class)
.addOptionsModification(options -> options.dumpInputToDirectory = dumpDir.toString())
+ .allowDiagnosticInfoMessages()
+ .compile()
+ .assertAllInfoMessagesMatch(containsString("Dumped compilation inputs to:"))
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutputLines("Hello, world");
assertTrue(Files.isDirectory(dumpDir));
diff --git a/src/test/java/com/android/tools/r8/ExternalR8TestCompileResult.java b/src/test/java/com/android/tools/r8/ExternalR8TestCompileResult.java
index 04a37fa..75cd5526 100644
--- a/src/test/java/com/android/tools/r8/ExternalR8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/ExternalR8TestCompileResult.java
@@ -5,6 +5,7 @@
package com.android.tools.r8;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.io.IOException;
@@ -58,6 +59,16 @@
}
@Override
+ public String getStdout() {
+ throw new Unimplemented("Unexpected attempt to access stdout from external R8");
+ }
+
+ @Override
+ public String getStderr() {
+ throw new Unimplemented("Unexpected attempt to access stderr from external R8");
+ }
+
+ @Override
public CodeInspector inspector() throws IOException, ExecutionException {
return new CodeInspector(app, proguardMap);
}
diff --git a/src/test/java/com/android/tools/r8/ProguardTestCompileResult.java b/src/test/java/com/android/tools/r8/ProguardTestCompileResult.java
index fbb8282..dbb3c6e 100644
--- a/src/test/java/com/android/tools/r8/ProguardTestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/ProguardTestCompileResult.java
@@ -4,6 +4,7 @@
package com.android.tools.r8;
import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.io.IOException;
@@ -37,6 +38,16 @@
}
@Override
+ public String getStdout() {
+ throw new Unimplemented("Unexpected attempt to access stdout from Proguard");
+ }
+
+ @Override
+ public String getStderr() {
+ throw new Unimplemented("Unexpected attempt to access stderr from Proguard");
+ }
+
+ @Override
public CodeInspector inspector() throws IOException, ExecutionException {
return new CodeInspector(app, proguardMap);
}
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 1dca05c..bd27965 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.R8Command.Builder;
import com.android.tools.r8.TestBase.Backend;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase.KeepRuleConsumer;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.CollectingGraphConsumer;
@@ -26,14 +27,23 @@
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
+import org.hamcrest.core.IsAnything;
public abstract class R8TestBuilder<T extends R8TestBuilder<T>>
extends TestShrinkerBuilder<R8Command, Builder, R8TestCompileResult, R8TestRunResult, T> {
+ enum AllowedDiagnosticMessages {
+ ALL,
+ INFO,
+ NONE,
+ WARNING
+ }
+
R8TestBuilder(TestState state, Builder builder, Backend backend) {
super(state, builder, backend);
}
+ private AllowedDiagnosticMessages allowedDiagnosticMessages = AllowedDiagnosticMessages.NONE;
private boolean enableInliningAnnotations = false;
private boolean enableNeverClassInliningAnnotations = false;
private boolean enableMergeAnnotations = false;
@@ -105,14 +115,32 @@
builder.build(),
optionsConsumer.andThen(
options -> box.proguardConfiguration = options.getProguardConfiguration()));
- return new R8TestCompileResult(
- getState(),
- getOutputMode(),
- app.get(),
- box.proguardConfiguration,
- box.syntheticProguardRules,
- proguardMapBuilder.toString(),
- graphConsumer);
+ R8TestCompileResult compileResult =
+ new R8TestCompileResult(
+ getState(),
+ getOutputMode(),
+ app.get(),
+ box.proguardConfiguration,
+ box.syntheticProguardRules,
+ proguardMapBuilder.toString(),
+ graphConsumer);
+ switch (allowedDiagnosticMessages) {
+ case ALL:
+ compileResult.assertDiagnosticMessageThatMatches(new IsAnything<>());
+ break;
+ case INFO:
+ compileResult.assertOnlyInfos();
+ break;
+ case NONE:
+ compileResult.assertNoMessages();
+ break;
+ case WARNING:
+ compileResult.assertOnlyWarnings();
+ break;
+ default:
+ throw new Unreachable();
+ }
+ return compileResult;
}
public Builder getBuilder() {
@@ -201,6 +229,36 @@
return addOptionsModification(options -> options.testing.allowClassInlinerGracefulExit = true);
}
+ public T allowDiagnosticMessages() {
+ assert allowedDiagnosticMessages == AllowedDiagnosticMessages.NONE;
+ allowedDiagnosticMessages = AllowedDiagnosticMessages.ALL;
+ return self();
+ }
+
+ public T allowDiagnosticInfoMessages() {
+ return allowDiagnosticInfoMessages(true);
+ }
+
+ public T allowDiagnosticInfoMessages(boolean condition) {
+ if (condition) {
+ assert allowedDiagnosticMessages == AllowedDiagnosticMessages.NONE;
+ allowedDiagnosticMessages = AllowedDiagnosticMessages.INFO;
+ }
+ return self();
+ }
+
+ public T allowDiagnosticWarningMessages() {
+ return allowDiagnosticWarningMessages(true);
+ }
+
+ public T allowDiagnosticWarningMessages(boolean condition) {
+ if (condition) {
+ assert allowedDiagnosticMessages == AllowedDiagnosticMessages.NONE;
+ allowedDiagnosticMessages = AllowedDiagnosticMessages.WARNING;
+ }
+ return self();
+ }
+
public T allowUnusedProguardConfigurationRules() {
return addOptionsModification(
options -> options.testing.allowUnusedProguardConfigurationRules = true);
diff --git a/src/test/java/com/android/tools/r8/R8TestCompileResult.java b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
index c4ec2aa..ae6fc69 100644
--- a/src/test/java/com/android/tools/r8/R8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
@@ -53,6 +53,16 @@
}
@Override
+ public String getStdout() {
+ return state.getStdout();
+ }
+
+ @Override
+ public String getStderr() {
+ return state.getStderr();
+ }
+
+ @Override
public CodeInspector inspector() throws IOException, ExecutionException {
return new CodeInspector(app, proguardMap);
}
diff --git a/src/test/java/com/android/tools/r8/TestBuilderMinAndroidJarTest.java b/src/test/java/com/android/tools/r8/TestBuilderMinAndroidJarTest.java
index 8d6b8d2..06cba56 100644
--- a/src/test/java/com/android/tools/r8/TestBuilderMinAndroidJarTest.java
+++ b/src/test/java/com/android/tools/r8/TestBuilderMinAndroidJarTest.java
@@ -4,7 +4,9 @@
package com.android.tools.r8;
+import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
@@ -57,8 +59,16 @@
: containsString("AbstractMethodError");
testForR8(parameters.getBackend())
.addProgramClasses(Main.class)
+ .allowDiagnosticWarningMessages(
+ parameters.isDexRuntime() && parameters.getApiLevel().isLessThan(AndroidApiLevel.O))
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
+ .compile()
+ .assertAllWarningMessagesMatch(
+ anyOf(
+ equalTo(
+ "Lambda expression implements missing interface `java.util.function.Supplier`"),
+ containsString("required for default or static interface methods desugaring")))
.run(parameters.getRuntime(), Main.class)
.assertFailureWithErrorThatMatches(expectedError);
}
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index e04a2c1..9e54272 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -5,7 +5,9 @@
import static com.android.tools.r8.TestBase.Backend.DEX;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
import com.android.tools.r8.TestBase.Backend;
@@ -78,6 +80,10 @@
public abstract TestDiagnosticMessages getDiagnosticMessages();
+ public abstract String getStdout();
+
+ public abstract String getStderr();
+
public OutputMode getOutputMode() {
return outputMode;
}
@@ -268,11 +274,20 @@
return self();
}
+ public CR assertDiagnosticMessageThatMatches(Matcher<String> matcher) {
+ getDiagnosticMessages().assertDiagnosticMessageThatMatches(matcher);
+ return self();
+ }
+
public CR assertInfoMessageThatMatches(Matcher<String> matcher) {
getDiagnosticMessages().assertInfoMessageThatMatches(matcher);
return self();
}
+ public CR assertAllInfoMessagesMatch(Matcher<String> matcher) {
+ return assertNoInfoMessageThatMatches(not(matcher));
+ }
+
public CR assertNoInfoMessageThatMatches(Matcher<String> matcher) {
getDiagnosticMessages().assertNoInfoMessageThatMatches(matcher);
return self();
@@ -283,6 +298,11 @@
return self();
}
+ public CR assertAllWarningMessagesMatch(Matcher<String> matcher) {
+ getDiagnosticMessages().assertNoWarningMessageThatMatches(not(matcher));
+ return self();
+ }
+
public CR assertNoWarningMessageThatMatches(Matcher<String> matcher) {
getDiagnosticMessages().assertNoWarningMessageThatMatches(matcher);
return self();
@@ -298,6 +318,26 @@
return self();
}
+ public CR assertNoStdout() {
+ assertEquals("", getStdout());
+ return self();
+ }
+
+ public CR assertStdoutThatMatches(Matcher<String> matcher) {
+ assertThat(getStdout(), matcher);
+ return self();
+ }
+
+ public CR assertNoStderr() {
+ assertEquals("", getStderr());
+ return self();
+ }
+
+ public CR assertStderrThatMatches(Matcher<String> matcher) {
+ assertThat(getStderr(), matcher);
+ return self();
+ }
+
public CR disassemble(PrintStream ps) throws IOException, ExecutionException {
ToolHelper.disassemble(app, ps);
return self();
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index 8c6e7c2..c216670 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -10,8 +10,10 @@
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
+import com.android.tools.r8.utils.ForwardingOutputStream;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.base.Suppliers;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Path;
@@ -42,13 +44,16 @@
final Backend backend;
// Default initialized setup. Can be overwritten if needed.
+ private boolean allowStdoutMessages = false;
+ private boolean allowStderrMessages = false;
private boolean useDefaultRuntimeLibrary = true;
private final List<Path> additionalRunClassPath = new ArrayList<>();
private ProgramConsumer programConsumer;
private StringConsumer mainDexListConsumer;
private AndroidApiLevel defaultMinApiLevel = ToolHelper.getMinApiLevelForDexVm();
private Consumer<InternalOptions> optionsConsumer = DEFAULT_OPTIONS;
- private PrintStream stdout = null;
+ private ByteArrayOutputStream stdout = null;
+ private ByteArrayOutputStream stderr = null;
protected OutputMode outputMode = OutputMode.DexIndexed;
TestCompilerBuilder(TestState state, B builder, Backend backend) {
@@ -92,16 +97,32 @@
}
}
PrintStream oldOut = System.out;
+ PrintStream oldErr = System.err;
+ CR cr = null;
try {
if (stdout != null) {
- System.setOut(stdout);
+ System.setOut(new PrintStream(new ForwardingOutputStream(stdout, System.out)));
}
- CR cr = internalCompile(builder, optionsConsumer, Suppliers.memoize(sink::build));
+ if (stderr != null) {
+ System.setErr(new PrintStream(new ForwardingOutputStream(stderr, System.err)));
+ }
+ cr = internalCompile(builder, optionsConsumer, Suppliers.memoize(sink::build));
cr.addRunClasspathFiles(additionalRunClassPath);
return cr;
} finally {
if (stdout != null) {
+ getState().setStdout(stdout.toString());
System.setOut(oldOut);
+ if (cr != null && !allowStdoutMessages) {
+ cr.assertNoStdout();
+ }
+ }
+ if (stderr != null) {
+ getState().setStderr(stderr.toString());
+ System.setErr(oldErr);
+ if (cr != null && !allowStderrMessages) {
+ cr.assertNoStderr();
+ }
}
}
}
@@ -288,12 +309,28 @@
return self();
}
- public T redirectStdOut(PrintStream printStream) {
- assert stdout == null;
- stdout = printStream;
+ public T allowStdoutMessages() {
+ allowStdoutMessages = true;
return self();
}
+ public T collectStdout() {
+ assert stdout == null;
+ stdout = new ByteArrayOutputStream();
+ return allowStdoutMessages();
+ }
+
+ public T allowStderrMessages() {
+ allowStdoutMessages = true;
+ return self();
+ }
+
+ public T collectStderr() {
+ assert stderr == null;
+ stderr = new ByteArrayOutputStream();
+ return allowStderrMessages();
+ }
+
public T enableCoreLibraryDesugaring(AndroidApiLevel minAPILevel) {
return enableCoreLibraryDesugaring(minAPILevel, null);
}
diff --git a/src/test/java/com/android/tools/r8/TestDiagnosticMessages.java b/src/test/java/com/android/tools/r8/TestDiagnosticMessages.java
index 702815a..0dd7e67 100644
--- a/src/test/java/com/android/tools/r8/TestDiagnosticMessages.java
+++ b/src/test/java/com/android/tools/r8/TestDiagnosticMessages.java
@@ -9,35 +9,41 @@
public interface TestDiagnosticMessages {
- public List<Diagnostic> getInfos();
+ List<Diagnostic> getInfos();
- public List<Diagnostic> getWarnings();
+ List<Diagnostic> getWarnings();
- public List<Diagnostic> getErrors();
+ List<Diagnostic> getErrors();
- public TestDiagnosticMessages assertNoMessages();
+ TestDiagnosticMessages assertNoMessages();
- public TestDiagnosticMessages assertOnlyInfos();
+ TestDiagnosticMessages assertOnlyInfos();
- public TestDiagnosticMessages assertOnlyWarnings();
+ TestDiagnosticMessages assertOnlyWarnings();
- public TestDiagnosticMessages assertOnlyErrors();
+ TestDiagnosticMessages assertOnlyErrors();
- public TestDiagnosticMessages assertInfosCount(int count);
+ TestDiagnosticMessages assertInfosCount(int count);
- public TestDiagnosticMessages assertWarningsCount(int count);
+ TestDiagnosticMessages assertWarningsCount(int count);
- public TestDiagnosticMessages assertErrorsCount(int count);
+ TestDiagnosticMessages assertErrorsCount(int count);
- public TestDiagnosticMessages assertInfoMessageThatMatches(Matcher<String> matcher);
+ TestDiagnosticMessages assertDiagnosticMessageThatMatches(Matcher<String> matcher);
- public TestDiagnosticMessages assertNoInfoMessageThatMatches(Matcher<String> matcher);
+ TestDiagnosticMessages assertInfoMessageThatMatches(Matcher<String> matcher);
- public TestDiagnosticMessages assertWarningMessageThatMatches(Matcher<String> matcher);
+ TestDiagnosticMessages assertAllInfoMessagesMatch(Matcher<String> matcher);
- public TestDiagnosticMessages assertNoWarningMessageThatMatches(Matcher<String> matcher);
+ TestDiagnosticMessages assertNoInfoMessageThatMatches(Matcher<String> matcher);
- public TestDiagnosticMessages assertErrorMessageThatMatches(Matcher<String> matcher);
+ TestDiagnosticMessages assertWarningMessageThatMatches(Matcher<String> matcher);
- public TestDiagnosticMessages assertNoErrorMessageThatMatches(Matcher<String> matcher);
+ TestDiagnosticMessages assertAllWarningMessagesMatch(Matcher<String> matcher);
+
+ TestDiagnosticMessages assertNoWarningMessageThatMatches(Matcher<String> matcher);
+
+ TestDiagnosticMessages assertErrorMessageThatMatches(Matcher<String> matcher);
+
+ TestDiagnosticMessages assertNoErrorMessageThatMatches(Matcher<String> matcher);
}
diff --git a/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java b/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java
index 478a60d..44f046b 100644
--- a/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java
+++ b/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java
@@ -4,11 +4,13 @@
package com.android.tools.r8;
+import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
import com.android.tools.r8.utils.ListUtils;
+import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.List;
import org.hamcrest.Matcher;
@@ -122,22 +124,24 @@
}
private TestDiagnosticMessages assertMessageThatMatches(
- List<Diagnostic> diagnostics, String tag, Matcher<String> matcher) {
- assertNotEquals(0, diagnostics.size());
- for (int i = 0; i < diagnostics.size(); i++) {
- if (matcher.matches(diagnostics.get(i).getDiagnosticMessage())) {
+ Iterable<Diagnostic> diagnostics, String tag, Matcher<String> matcher) {
+ int numberOfDiagnostics = 0;
+ for (Diagnostic diagnostic : diagnostics) {
+ if (matcher.matches(diagnostic.getDiagnosticMessage())) {
return this;
}
+ numberOfDiagnostics++;
}
+ assertNotEquals(0, numberOfDiagnostics);
StringBuilder builder = new StringBuilder("No " + tag + " matches " + matcher.toString());
builder.append(System.lineSeparator());
if (getWarnings().size() == 0) {
builder.append("There were no " + tag + "s.");
} else {
- builder.append("There were " + diagnostics.size() + " "+ tag + "s:");
+ builder.append("There were " + numberOfDiagnostics + " " + tag + "s:");
builder.append(System.lineSeparator());
- for (int i = 0; i < diagnostics.size(); i++) {
- builder.append(diagnostics.get(i).getDiagnosticMessage());
+ for (Diagnostic diagnostic : diagnostics) {
+ builder.append(diagnostic.getDiagnosticMessage());
builder.append(System.lineSeparator());
}
}
@@ -156,18 +160,38 @@
return this;
}
+ @Override
+ public TestDiagnosticMessages assertDiagnosticMessageThatMatches(Matcher<String> matcher) {
+ return assertMessageThatMatches(
+ Iterables.concat(getInfos(), getWarnings(), getErrors()), "diagnostic message", matcher);
+ }
+
+ @Override
public TestDiagnosticMessages assertInfoMessageThatMatches(Matcher<String> matcher) {
return assertMessageThatMatches(getInfos(), "info", matcher);
}
+ @Override
+ public TestDiagnosticMessages assertAllInfoMessagesMatch(Matcher<String> matcher) {
+ return assertNoInfoMessageThatMatches(not(matcher));
+ }
+
+ @Override
public TestDiagnosticMessages assertNoInfoMessageThatMatches(Matcher<String> matcher) {
return assertNoMessageThatMatches(getInfos(), "info", matcher);
}
+ @Override
public TestDiagnosticMessages assertWarningMessageThatMatches(Matcher<String> matcher) {
return assertMessageThatMatches(getWarnings(), "warning", matcher);
}
+ @Override
+ public TestDiagnosticMessages assertAllWarningMessagesMatch(Matcher<String> matcher) {
+ return assertNoWarningMessageThatMatches(not(matcher));
+ }
+
+ @Override
public TestDiagnosticMessages assertNoWarningMessageThatMatches(Matcher<String> matcher) {
return assertNoMessageThatMatches(getWarnings(), "warning", matcher);
}
diff --git a/src/test/java/com/android/tools/r8/TestParametersBuilder.java b/src/test/java/com/android/tools/r8/TestParametersBuilder.java
index 35d37cc..b29d851 100644
--- a/src/test/java/com/android/tools/r8/TestParametersBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestParametersBuilder.java
@@ -160,6 +160,10 @@
return withApiFilter(api -> true);
}
+ public TestParametersBuilder withApiLevel(AndroidApiLevel api) {
+ return withApiFilter(api::equals);
+ }
+
public TestParametersBuilder withApiLevelsStartingAtIncluding(AndroidApiLevel startInclusive) {
return withApiFilter(api -> startInclusive.getLevel() <= api.getLevel());
}
diff --git a/src/test/java/com/android/tools/r8/TestState.java b/src/test/java/com/android/tools/r8/TestState.java
index bdb4e2f..78388bc 100644
--- a/src/test/java/com/android/tools/r8/TestState.java
+++ b/src/test/java/com/android/tools/r8/TestState.java
@@ -12,6 +12,9 @@
private final TemporaryFolder temp;
private final TestDiagnosticMessagesImpl messages = new TestDiagnosticMessagesImpl();
+ private String stdout;
+ private String stderr;
+
public TestState(TemporaryFolder temp) {
this.temp = temp;
}
@@ -27,4 +30,20 @@
public TestDiagnosticMessages getDiagnosticsMessages() {
return messages;
}
+
+ public String getStdout() {
+ return stdout;
+ }
+
+ void setStdout(String stdout) {
+ this.stdout = stdout;
+ }
+
+ public String getStderr() {
+ return stderr;
+ }
+
+ void setStderr(String stderr) {
+ this.stderr = stderr;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java b/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java
index ddb0608..1bde24a 100644
--- a/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java
+++ b/src/test/java/com/android/tools/r8/cf/bootstrap/BootstrapCurrentEqualityTest.java
@@ -5,6 +5,7 @@
import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
import static com.google.common.io.ByteStreams.toByteArray;
+import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -103,7 +104,14 @@
.setMode(mode)
.addProgramFiles(ToolHelper.R8_WITH_RELOCATED_DEPS_JAR)
.addKeepRuleFiles(MAIN_KEEP)
+ .allowDiagnosticInfoMessages(mode == CompilationMode.DEBUG)
.compile()
+ .assertAllInfoMessagesMatch(
+ anyOf(
+ containsString("Stripped invalid locals information from 1 method."),
+ containsString("Methods with invalid locals information:"),
+ containsString(
+ "Some warnings are typically a sign of using an outdated Java toolchain.")))
.apply(c -> FileUtils.writeTextFile(map, c.getProguardMap()))
.writeToZip(jar);
}
diff --git a/src/test/java/com/android/tools/r8/classlookup/LibraryClassExtendsProgramClassTest.java b/src/test/java/com/android/tools/r8/classlookup/LibraryClassExtendsProgramClassTest.java
index 5cbb40d..363008d 100644
--- a/src/test/java/com/android/tools/r8/classlookup/LibraryClassExtendsProgramClassTest.java
+++ b/src/test/java/com/android/tools/r8/classlookup/LibraryClassExtendsProgramClassTest.java
@@ -180,13 +180,12 @@
.addProgramClassFileData(junitClasses)
.addKeepAllClassesRule()
.addOptionsModification(options -> options.lookupLibraryBeforeProgram = false)
- .compileWithExpectedDiagnostics(
+ .allowDiagnosticWarningMessages(libraryContainsJUnit())
+ .compile()
+ .inspectDiagnosticMessages(
diagnostics -> {
if (libraryContainsJUnit()) {
- diagnostics.assertOnlyWarnings();
checkDiagnostics(diagnostics.getWarnings());
- } else {
- diagnostics.assertNoMessages();
}
})
.inspect(this::testCaseClassInResult);
diff --git a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
index 09489c9..e0ea969 100644
--- a/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/VerticalClassMergerTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.OutputMode;
import com.android.tools.r8.ProgramResourceProvider;
+import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.StringConsumer.FileConsumer;
import com.android.tools.r8.TestBase;
@@ -140,14 +141,17 @@
"classmerging.ArrayTypeCollisionTest$A",
"classmerging.ArrayTypeCollisionTest$B");
runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(
+ getProguardConfig(
+ EXAMPLE_KEEP,
+ "-neverinline public class classmerging.ArrayTypeCollisionTest {",
+ " static void method(...);",
+ "}"))
+ .allowDiagnosticInfoMessages(),
main,
programFiles,
- preservedClassNames::contains,
- getProguardConfig(
- EXAMPLE_KEEP,
- "-neverinline public class classmerging.ArrayTypeCollisionTest {",
- " static void method(...);",
- "}"));
+ preservedClassNames::contains);
}
/**
@@ -199,17 +203,18 @@
// Run test.
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(
+ "-keep class " + main + " {",
+ " public static void main(...);",
+ "}",
+ "-neverinline class " + main + " {",
+ " static classmerging.A[] method(...);",
+ " static classmerging.B[] method(...);",
+ "}"),
main,
jasminBuilder.build(),
- preservedClassNames::contains,
- StringUtils.joinLines(
- "-keep class " + main + " {",
- " public static void main(...);",
- "}",
- "-neverinline class " + main + " {",
- " static classmerging.A[] method(...);",
- " static classmerging.B[] method(...);",
- "}"));
+ preservedClassNames::contains);
}
// This test has a cycle in the call graph consisting of the methods A.<init> and B.<init>.
@@ -231,7 +236,13 @@
Set<String> preservedClassNames =
ImmutableSet.of("classmerging.CallGraphCycleTest", "classmerging.CallGraphCycleTest$B");
for (int i = 0; i < 5; i++) {
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
}
@@ -250,10 +261,12 @@
"classmerging.ConflictInGeneratedNameTest$B");
CodeInspector inspector =
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
// Avoid that direct methods in B get inlined.
@@ -321,7 +334,13 @@
ImmutableSet.of(
"classmerging.FieldCollisionTest",
"classmerging.FieldCollisionTest$B");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
@Test
@@ -342,10 +361,12 @@
"classmerging.LambdaRewritingTest$FunctionImpl",
"classmerging.LambdaRewritingTest$InterfaceImpl");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(JAVA8_EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
name -> preservedClassNames.contains(name) || name.contains("$Lambda$"),
- getProguardConfig(JAVA8_EXAMPLE_KEEP),
options -> {
this.configure(options);
options.enableClassInlining = false;
@@ -367,10 +388,12 @@
"classmerging.ConflictingInterfaceSignaturesTest",
"classmerging.ConflictingInterfaceSignaturesTest$InterfaceImpl");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP),
options -> {
this.configure(options);
options.enableInlining = false;
@@ -399,7 +422,13 @@
"classmerging.MethodCollisionTest$B",
"classmerging.MethodCollisionTest$C",
"classmerging.MethodCollisionTest$D");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
@Test
@@ -418,7 +447,12 @@
"classmerging.NestedDefaultInterfaceMethodsTest$B",
"classmerging.NestedDefaultInterfaceMethodsTest$C");
runTest(
- main, programFiles, preservedClassNames::contains, getProguardConfig(JAVA8_EXAMPLE_KEEP));
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(JAVA8_EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
@Test
@@ -436,14 +470,16 @@
"classmerging.NestedDefaultInterfaceMethodsTest$B",
"classmerging.NestedDefaultInterfaceMethodsTest$C");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(JAVA8_EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
AndroidApp.builder()
.addProgramFiles(programFiles)
.addClassProgramData(
NestedDefaultInterfaceMethodsTestDump.CDump.dump(), Origin.unknown())
.build(),
- preservedClassNames::contains,
- getProguardConfig(JAVA8_EXAMPLE_KEEP));
+ preservedClassNames::contains);
}
@Test
@@ -463,10 +499,12 @@
"classmerging.PinnedParameterTypesTest$InterfaceImpl",
"classmerging.PinnedParameterTypesTest$TestClass");
runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP, "-keepparameternames"))
+ .allowDiagnosticInfoMessages(),
main,
programFiles,
- preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP, "-keepparameternames"));
+ preservedClassNames::contains);
}
@Test
@@ -486,10 +524,12 @@
"classmerging.PinnedArrayParameterTypesTest$InterfaceImpl",
"classmerging.PinnedArrayParameterTypesTest$TestClass");
runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP, "-keepparameternames"))
+ .allowDiagnosticInfoMessages(),
main,
programFiles,
- preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP, "-keepparameternames"));
+ preservedClassNames::contains);
}
@Test
@@ -515,10 +555,12 @@
" 1:1:void <init>():20:20 -> <init>",
" 1:1:void test():23:23 -> test");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
Predicates.alwaysTrue(),
- getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
options.enableVerticalClassMerging = false;
@@ -546,10 +588,12 @@
Set<String> preservedClassNames =
ImmutableSet.of("classmerging.ProguardFieldMapTest", "classmerging.ProguardFieldMapTest$B");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
@@ -583,10 +627,12 @@
" 1:1:void <init>():22:22 -> <init>",
" 1:2:void method():26:27 -> method");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
Predicates.alwaysTrue(),
- getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
options.enableVerticalClassMerging = false;
@@ -617,10 +663,12 @@
ImmutableSet.of(
"classmerging.ProguardMethodMapTest", "classmerging.ProguardMethodMapTest$B");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP),
options -> {
configure(options);
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
@@ -655,12 +703,16 @@
" 2:2:void classmerging.ProguardMethodMapTest$A.method():17:17 -> method",
" 2:2:void method():27 -> method");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(
+ getProguardConfig(
+ EXAMPLE_KEEP,
+ "-forceinline class classmerging.ProguardMethodMapTest$A { public void"
+ + " method(); }"))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
Predicates.alwaysTrue(),
- getProguardConfig(
- EXAMPLE_KEEP,
- "-forceinline class classmerging.ProguardMethodMapTest$A { public void method(); }"),
options -> {
configure(options);
options.enableVerticalClassMerging = false;
@@ -688,12 +740,16 @@
ImmutableSet.of(
"classmerging.ProguardMethodMapTest", "classmerging.ProguardMethodMapTest$B");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(
+ getProguardConfig(
+ EXAMPLE_KEEP,
+ "-forceinline class classmerging.ProguardMethodMapTest$A { public void"
+ + " method(); }"))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
preservedClassNames::contains,
- getProguardConfig(
- EXAMPLE_KEEP,
- "-forceinline class classmerging.ProguardMethodMapTest$A { public void method(); }"),
options -> {
configure(options);
options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
@@ -717,7 +773,13 @@
ImmutableSet.of(
"classmerging.SubClassThatReferencesSuperMethod",
"classmerging.SuperCallRewritingTest");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
// When a subclass A has been merged into its subclass B, we rewrite invoke-super calls that hit
@@ -924,10 +986,11 @@
// Run test.
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(String.format("-keep class %s { public static void main(...); }", main)),
main,
appBuilder.build(),
- preservedClassNames::contains,
- String.format("-keep class %s { public static void main(...); }", main));
+ preservedClassNames::contains);
}
@Test
@@ -953,10 +1016,12 @@
"classmerging.SyntheticBridgeSignaturesTest$ASub",
"classmerging.SyntheticBridgeSignaturesTest$BSub");
runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
main,
readProgramFiles(programFiles),
preservedClassNames::contains,
- getProguardConfig(EXAMPLE_KEEP),
options -> {
this.configure(options);
if (!allowInlining) {
@@ -989,7 +1054,13 @@
ImmutableSet.of(
"classmerging.ConflictingInterfaceSignaturesTest",
"classmerging.ConflictingInterfaceSignaturesTest$InterfaceImpl");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
// If an exception class A is merged into another exception class B, then all exception tables
@@ -1010,7 +1081,14 @@
"classmerging.ExceptionTest",
"classmerging.ExceptionTest$ExceptionB",
"classmerging.ExceptionTest$Exception2");
- CodeInspector inspector = runTest(main, programFiles, preservedClassNames::contains);
+ CodeInspector inspector =
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
ClassSubject mainClass = inspector.clazz(main);
assertThat(mainClass, isPresent());
@@ -1061,7 +1139,13 @@
method.getMethod().getCode().asCfCode().toString(),
containsString("invokeinterface classmerging.MergeDefaultMethodIntoClassTest$A.f()V"));
- runTestOnInput(main, app, preservedClassNames::contains, getProguardConfig(JAVA8_EXAMPLE_KEEP));
+ runTestOnInput(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(JAVA8_EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ app,
+ preservedClassNames::contains);
}
@Test
@@ -1079,7 +1163,13 @@
"classmerging.ClassWithNativeMethodTest",
"classmerging.ClassWithNativeMethodTest$A",
"classmerging.ClassWithNativeMethodTest$B");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
@Test
@@ -1104,7 +1194,13 @@
"classmerging.SimpleInterfaceAccessTest$OtherSimpleInterfaceImpl",
"classmerging.pkg.SimpleInterfaceImplRetriever",
"classmerging.pkg.SimpleInterfaceImplRetriever$SimpleInterfaceImpl");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
@Test
@@ -1130,13 +1226,16 @@
// Allow access modifications (and prevent SimpleInterfaceImplRetriever from being removed as
// a result of inlining).
runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(
+ getProguardConfig(
+ EXAMPLE_KEEP,
+ "-allowaccessmodification",
+ "-keep public class classmerging.pkg.SimpleInterfaceImplRetriever"))
+ .allowDiagnosticInfoMessages(),
main,
programFiles,
- preservedClassNames::contains,
- getProguardConfig(
- EXAMPLE_KEEP,
- "-allowaccessmodification",
- "-keep public class classmerging.pkg.SimpleInterfaceImplRetriever"));
+ preservedClassNames::contains);
}
// TODO(christofferqa): This test checks that the invoke-super instruction in B is not rewritten
@@ -1158,11 +1257,14 @@
"classmerging.RewritePinnedMethodTest$A",
"classmerging.RewritePinnedMethodTest$C");
runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(
+ getProguardConfig(
+ EXAMPLE_KEEP, "-keep class classmerging.RewritePinnedMethodTest$A { *; }"))
+ .allowDiagnosticInfoMessages(),
main,
programFiles,
- preservedClassNames::contains,
- getProguardConfig(
- EXAMPLE_KEEP, "-keep class classmerging.RewritePinnedMethodTest$A { *; }"));
+ preservedClassNames::contains);
}
@Test
@@ -1177,57 +1279,60 @@
Set<String> preservedClassNames =
ImmutableSet.of(
"classmerging.TemplateMethodTest", "classmerging.TemplateMethodTest$AbstractClassImpl");
- runTest(main, programFiles, preservedClassNames::contains);
+ runTest(
+ testForR8(Backend.DEX)
+ .addKeepRules(getProguardConfig(EXAMPLE_KEEP))
+ .allowDiagnosticInfoMessages(),
+ main,
+ programFiles,
+ preservedClassNames::contains);
}
private CodeInspector runTest(
- String main, Path[] programFiles, Predicate<String> preservedClassNames) throws Throwable {
- return runTest(main, programFiles, preservedClassNames, getProguardConfig(EXAMPLE_KEEP));
- }
-
- private CodeInspector runTest(
+ R8FullTestBuilder builder,
String main,
Path[] programFiles,
- Predicate<String> preservedClassNames,
- String proguardConfig)
+ Predicate<String> preservedClassNames)
throws Throwable {
- return runTestOnInput(
- main, readProgramFiles(programFiles), preservedClassNames, proguardConfig);
+ return runTestOnInput(builder, main, readProgramFiles(programFiles), preservedClassNames);
}
private CodeInspector runTestOnInput(
- String main, AndroidApp input, Predicate<String> preservedClassNames, String proguardConfig)
+ R8FullTestBuilder builder,
+ String main,
+ AndroidApp input,
+ Predicate<String> preservedClassNames)
throws Throwable {
- return runTestOnInput(main, input, preservedClassNames, proguardConfig, this::configure);
+ return runTestOnInput(builder, main, input, preservedClassNames, this::configure);
}
private CodeInspector runTestOnInput(
+ R8FullTestBuilder builder,
String main,
AndroidApp input,
Predicate<String> preservedClassNames,
- String proguardConfig,
Consumer<InternalOptions> optionsConsumer)
throws Throwable {
return runTestOnInput(
+ builder,
main,
input,
preservedClassNames,
- proguardConfig,
optionsConsumer,
new VerticalClassMergerDebugTest(main));
}
private CodeInspector runTestOnInput(
+ R8FullTestBuilder builder,
String main,
AndroidApp input,
Predicate<String> preservedClassNames,
- String proguardConfig,
Consumer<InternalOptions> optionsConsumer,
VerticalClassMergerDebugTest debugTestRunner)
throws Throwable {
Path proguardMapPath = File.createTempFile("mapping", ".txt", temp.getRoot()).toPath();
R8TestCompileResult compileResult =
- testForR8(Backend.DEX)
+ builder
.apply(
b -> {
// Some tests add DEX inputs, so circumvent the check by adding directly to the
@@ -1238,7 +1343,6 @@
}
})
.noMinification()
- .addKeepRules(proguardConfig)
.enableProguardTestOptions()
.addOptionsModification(
o -> {
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11R8CompilationTest.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11R8CompilationTest.java
index dbdc654..a79ccf7 100644
--- a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11R8CompilationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/Java11R8CompilationTest.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.desugar.nestaccesscontrol;
import static junit.framework.TestCase.assertTrue;
+import static org.hamcrest.CoreMatchers.containsString;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -50,7 +51,9 @@
.addProgramFiles(ToolHelper.R8_WITH_RELOCATED_DEPS_JAR_11)
.addKeepRuleFiles(MAIN_KEEP)
.addOptionsModification(opt -> opt.ignoreMissingClasses = true)
+ .allowDiagnosticWarningMessages()
.compile()
+ .assertAllWarningMessagesMatch(containsString("Missing class:"))
.inspect(this::assertNotEmpty)
.inspect(Java11R8CompilationTest::assertNoNests);
}
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/NestCompilationExceptionTest.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/NestCompilationExceptionTest.java
index 48fe91b..75982e9 100644
--- a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/NestCompilationExceptionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/NestCompilationExceptionTest.java
@@ -69,7 +69,11 @@
}
private TestCompileResult compileOnlyClassesMatching(
- Matcher<String> matcher, boolean d8, boolean ignoreMissingClasses) throws Exception {
+ Matcher<String> matcher,
+ boolean d8,
+ boolean allowDiagnosticWarningMessages,
+ boolean ignoreMissingClasses)
+ throws Exception {
List<Path> matchingClasses =
CLASS_NAMES.stream()
.filter(matcher::matches)
@@ -93,6 +97,7 @@
options.enableNestBasedAccessDesugaring = true;
options.ignoreMissingClasses = ignoreMissingClasses;
})
+ .allowDiagnosticWarningMessages(allowDiagnosticWarningMessages)
.compile();
}
}
@@ -101,7 +106,7 @@
try {
Matcher<String> innerClassMatcher =
containsString("BasicNestHostWithInnerClassMethods$BasicNestedClass");
- compileOnlyClassesMatching(innerClassMatcher, false, false);
+ compileOnlyClassesMatching(innerClassMatcher, false, false, false);
fail("Should have raised an exception for missing nest host");
} catch (Exception e) {
assertTrue(e.getCause().getCause().getMessage().contains("requires its nest host"));
@@ -111,7 +116,7 @@
private void testIncompleteNestError() {
try {
Matcher<String> innerClassMatcher = endsWith("BasicNestHostWithInnerClassMethods");
- compileOnlyClassesMatching(innerClassMatcher, false, false);
+ compileOnlyClassesMatching(innerClassMatcher, false, false, false);
fail("Should have raised an exception for incomplete nest");
} catch (Exception e) {
assertTrue(e.getCause().getCause().getMessage().contains("requires its nest mates"));
@@ -121,7 +126,7 @@
private void testMissingNestHostWarning(boolean d8, boolean desugarWarning) throws Exception {
Matcher<String> innerClassMatcher =
containsString("BasicNestHostWithInnerClassMethods$BasicNestedClass");
- TestCompileResult compileResult = compileOnlyClassesMatching(innerClassMatcher, d8, true);
+ TestCompileResult compileResult = compileOnlyClassesMatching(innerClassMatcher, d8, !d8, true);
assertTrue(compileResult.getDiagnosticMessages().getWarnings().size() >= 1);
if (desugarWarning) {
assertTrue(
@@ -137,7 +142,7 @@
private void testIncompleteNestWarning(boolean d8, boolean desugarWarning) throws Exception {
Matcher<String> innerClassMatcher = endsWith("BasicNestHostWithInnerClassMethods");
- TestCompileResult compileResult = compileOnlyClassesMatching(innerClassMatcher, d8, true);
+ TestCompileResult compileResult = compileOnlyClassesMatching(innerClassMatcher, d8, !d8, true);
assertTrue(compileResult.getDiagnosticMessages().getWarnings().size() >= 1);
if (desugarWarning) {
assertTrue(
@@ -145,9 +150,7 @@
.anyMatch(warn -> warn instanceof IncompleteNestNestDesugarDiagnosic));
} else if (!d8) {
// R8 should raise extra warning when cleaning the nest.
- assertTrue(
- compileResult.getDiagnosticMessages().getWarnings().stream()
- .anyMatch(warn -> warn.getDiagnosticMessage().contains("requires its nest mates")));
+ compileResult.assertWarningMessageThatMatches(containsString("requires its nest mates"));
}
}
}
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/FailingEnumUnboxingAnalysisTest.java b/src/test/java/com/android/tools/r8/enumunboxing/FailingEnumUnboxingAnalysisTest.java
index 247e8a1..9c4872f 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/FailingEnumUnboxingAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/FailingEnumUnboxingAnalysisTest.java
@@ -59,6 +59,7 @@
.enableInliningAnnotations()
.addKeepRules(KEEP_ENUM)
.addOptionsModification(this::enableEnumOptions)
+ .allowDiagnosticInfoMessages()
.setMinApi(parameters.getApiLevel())
.compile()
.inspect(this::assertEnumsAsExpected);
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/FailingMethodEnumUnboxingAnalysisTest.java b/src/test/java/com/android/tools/r8/enumunboxing/FailingMethodEnumUnboxingAnalysisTest.java
index 762380a..e4f7bd1 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/FailingMethodEnumUnboxingAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/FailingMethodEnumUnboxingAnalysisTest.java
@@ -8,7 +8,6 @@
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestParameters;
@@ -46,16 +45,13 @@
@Test
public void testEnumUnboxingFailure() throws Exception {
- R8FullTestBuilder r8FullTestBuilder =
- testForR8(parameters.getBackend())
- .addInnerClasses(FailingMethodEnumUnboxingAnalysisTest.class);
- for (Class<?> failure : FAILURES) {
- r8FullTestBuilder.addKeepMainRule(failure);
- }
R8TestCompileResult compile =
- r8FullTestBuilder
+ testForR8(parameters.getBackend())
+ .addInnerClasses(FailingMethodEnumUnboxingAnalysisTest.class)
+ .addKeepMainRules(FAILURES)
.addKeepRules(KEEP_ENUM)
.addOptionsModification(this::enableEnumOptions)
+ .allowDiagnosticInfoMessages()
.enableInliningAnnotations()
.addOptionsModification(
// Disabled to avoid toString() being removed.
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/FieldPutEnumUnboxingAnalysisTest.java b/src/test/java/com/android/tools/r8/enumunboxing/FieldPutEnumUnboxingAnalysisTest.java
index 2841689..8811ee5 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/FieldPutEnumUnboxingAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/FieldPutEnumUnboxingAnalysisTest.java
@@ -40,6 +40,7 @@
.addKeepMainRules(INPUTS)
.addKeepRules(KEEP_ENUM)
.addOptionsModification(this::enableEnumOptions)
+ .allowDiagnosticInfoMessages()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.noMinification()
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/OrdinalEnumUnboxingAnalysisTest.java b/src/test/java/com/android/tools/r8/enumunboxing/OrdinalEnumUnboxingAnalysisTest.java
index 079c9f7..2570a12 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/OrdinalEnumUnboxingAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/OrdinalEnumUnboxingAnalysisTest.java
@@ -37,6 +37,7 @@
.addKeepMainRule(classToTest)
.addKeepRules(KEEP_ENUM)
.addOptionsModification(this::enableEnumOptions)
+ .allowDiagnosticInfoMessages()
.setMinApi(parameters.getApiLevel())
.compile()
.inspectDiagnosticMessages(
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/PhiEnumUnboxingAnalysisTest.java b/src/test/java/com/android/tools/r8/enumunboxing/PhiEnumUnboxingAnalysisTest.java
index 87cacd5..2abd358 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/PhiEnumUnboxingAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/PhiEnumUnboxingAnalysisTest.java
@@ -39,6 +39,7 @@
.addKeepRules(KEEP_ENUM)
.enableInliningAnnotations()
.addOptionsModification(this::enableEnumOptions)
+ .allowDiagnosticInfoMessages()
.setMinApi(parameters.getApiLevel())
.compile()
.inspectDiagnosticMessages(
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingAnalysisTest.java b/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingAnalysisTest.java
index 699c72d..53cddc6 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/SwitchEnumUnboxingAnalysisTest.java
@@ -39,6 +39,7 @@
.addKeepRules(KEEP_ENUM)
.enableInliningAnnotations()
.addOptionsModification(this::enableEnumOptions)
+ .allowDiagnosticInfoMessages()
.setMinApi(parameters.getApiLevel())
.compile()
.inspectDiagnosticMessages(
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java
index 6bf5d8f..0788985 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2BuilderShrinkingTest.java
@@ -5,6 +5,8 @@
package com.android.tools.r8.internal.proto;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
@@ -91,10 +93,15 @@
options.enableStringSwitchConversion = true;
})
.allowAccessModification()
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.inspect(this::inspect);
for (String main : mains) {
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
index 558664f..1473e03 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
@@ -5,6 +5,9 @@
package com.android.tools.r8.internal.proto;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -88,10 +91,15 @@
options.enableStringSwitchConversion = true;
})
.allowAccessModification(allowAccessModification)
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.minification(enableMinification)
.setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.inspect(
outputInspector -> {
verifyMapAndRequiredFieldsAreKept(inputInspector, outputInspector);
@@ -356,10 +364,17 @@
options.protoShrinking().enableGeneratedMessageLiteShrinking = true;
})
.allowAccessModification(allowAccessModification)
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.minification(enableMinification)
.setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(
+ anyOf(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."),
+ containsString("required for default or static interface methods desugaring")))
.inspect(
inspector ->
assertRewrittenProtoSchemasMatch(new CodeInspector(PROGRAM_FILES), inspector));
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
index faa91e5..7a261ff 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
@@ -5,6 +5,9 @@
package com.android.tools.r8.internal.proto;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -64,10 +67,14 @@
options.enableStringSwitchConversion = true;
})
.allowAccessModification(allowAccessModification)
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.minification(enableMinification)
.setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.inspect(
outputInspector -> {
verifyUnusedFieldsAreRemoved(inputInspector, outputInspector);
@@ -113,10 +120,17 @@
options.protoShrinking().enableGeneratedMessageLiteShrinking = true;
})
.allowAccessModification(allowAccessModification)
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.minification(enableMinification)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .assertAllWarningMessagesMatch(
+ anyOf(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."),
+ containsString("required for default or static interface methods desugaring")))
.inspect(
inspector ->
assertRewrittenProtoSchemasMatch(new CodeInspector(PROGRAM_FILES), inspector));
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java
index 901a577..41ce8a8 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java
@@ -5,19 +5,20 @@
package com.android.tools.r8.ir.analysis.type;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.NeverMerge;
-import com.android.tools.r8.R8TestRunResult;
+import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.base.Throwables;
-import java.nio.file.Path;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +36,8 @@
@Parameters(name = "{1}, allow type errors: {0}")
public static List<Object[]> data() {
- return buildParameters(BooleanUtils.values(), getTestParameters().withAllRuntimes().build());
+ return buildParameters(
+ BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build());
}
public MissingClassesJoinTest(boolean allowTypeErrors, TestParameters parameters) {
@@ -45,57 +47,63 @@
@Test
public void test() throws Exception {
- Path classpathFile =
- testForD8()
- .addProgramClasses(ASub2.class)
- .setMinApi(parameters.getRuntime())
- .compile()
- .writeToZip();
-
if (parameters.isDexRuntime() && !allowTypeErrors) {
- testForD8()
- // Intentionally not adding ASub2 as a program class.
- .addProgramClasses(A.class, ASub1.class, Box.class, TestClass.class)
- .setMinApi(parameters.getRuntime())
- .compile()
- .addRunClasspathFiles(classpathFile)
+ D8TestCompileResult compileResult =
+ testForD8()
+ // Intentionally not adding ASub2 as a program class.
+ .addProgramClasses(A.class, ASub1.class, Box.class, TestClass.class)
+ .setMinApi(parameters.getApiLevel())
+ .compile();
+
+ testForRuntime(parameters)
+ .addProgramFiles(compileResult.writeToZip())
+ .addProgramClasses(ASub2.class)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(expectedOutput);
}
try {
- R8TestRunResult result =
+ R8TestCompileResult compileResult =
testForR8(parameters.getBackend())
// Intentionally not adding ASub2 as a program class.
.addProgramClasses(A.class, ASub1.class, Box.class, TestClass.class)
.addKeepAllClassesRule()
.addOptionsModification(options -> options.testing.allowTypeErrors = allowTypeErrors)
+ .allowDiagnosticWarningMessages()
.enableMergeAnnotations()
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.compile()
- .addRunClasspathFiles(classpathFile)
- .run(parameters.getRuntime(), TestClass.class);
+ .assertAllWarningMessagesMatch(
+ equalTo(
+ "The method `void "
+ + TestClass.class.getTypeName()
+ + ".main(java.lang.String[])` does not type check and will be assumed to"
+ + " be unreachable."));
// Compilation fails unless type errors are allowed.
assertTrue(allowTypeErrors);
- // TestClass.main() does not type check, so it should have been replaced by `throw null`.
- // Note that, even if we do not replace the body of main() with `throw null`, the code would
- // still not work for the CF backend:
- //
- // java.lang.VerifyError: Bad type on operand stack
- // Exception Details:
- // Location:
- // MissingClassesJoinTest$TestClass.main([Ljava/lang/String;)V @28: putstatic
- // Reason:
- // Type 'java/lang/Object' (current frame, stack[0]) is not assignable to
- // 'com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest$A'
- // Current Frame:
- // bci: @28
- // flags: { }
- // locals: { 'java/lang/Object' }
- // stack: { 'java/lang/Object' }
- result.assertFailureWithErrorThatMatches(containsString("NullPointerException"));
+ testForRuntime(parameters)
+ .addProgramFiles(compileResult.writeToZip())
+ .addProgramClasses(ASub2.class)
+ .run(parameters.getRuntime(), TestClass.class)
+ // TestClass.main() does not type check, so it should have been replaced by `throw null`.
+ // Note that, even if we do not replace the body of main() with `throw null`, the code
+ // would still not work for the CF backend:
+ //
+ // java.lang.VerifyError: Bad type on operand stack
+ // Exception Details:
+ // Location:
+ // MissingClassesJoinTest$TestClass.main([Ljava/lang/String;)V @28: putstatic
+ // Reason:
+ // Type 'java/lang/Object' (current frame, stack[0]) is not assignable to
+ // 'com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest$A'
+ // Current Frame:
+ // bci: @28
+ // flags: { }
+ // locals: { 'java/lang/Object' }
+ // stack: { 'java/lang/Object' }
+ .assertFailureWithErrorThatMatches(containsString("NullPointerException"));
} catch (CompilationFailedException e) {
// Compilation should only fail when type errors are not allowed.
assertFalse(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress131349148.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress131349148.java
index 08d4f85..98a6e9e 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress131349148.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress131349148.java
@@ -4,25 +4,21 @@
package com.android.tools.r8.ir.optimize.inliner;
-import static junit.framework.TestCase.assertTrue;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.google.common.collect.Streams;
-import java.util.List;
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 Regress131349148 extends TestBase {
@@ -60,12 +56,18 @@
public void testNoInlineNonExistingCatchPreL() throws Exception {
R8TestRunResult result =
testForR8(parameters.getBackend())
- .addProgramClasses(TestClassCallingMethodWithNonExisting.class,
- ClassWithCatchNonExisting.class, ExistingException.class)
+ .addProgramClasses(
+ TestClassCallingMethodWithNonExisting.class,
+ ClassWithCatchNonExisting.class,
+ ExistingException.class)
.addKeepMainRule(TestClassCallingMethodWithNonExisting.class)
.addKeepRules("-dontwarn " + NonExistingException.class.getTypeName())
+ .allowDiagnosticWarningMessages(
+ parameters.isCfRuntime() || parameters.getApiLevel().isLessThan(AndroidApiLevel.N))
.setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllWarningMessagesMatch(
+ containsString("required for default or static interface methods desugaring"))
.run(parameters.getRuntime(), TestClassCallingMethodWithNonExisting.class)
.assertSuccess();
ClassSubject classSubject =
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/redundantfieldloadelimination/InstanceFieldLoadsSeparatedByInvokeCustomTest.java b/src/test/java/com/android/tools/r8/ir/optimize/redundantfieldloadelimination/InstanceFieldLoadsSeparatedByInvokeCustomTest.java
index 4e4624a..86745e5 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/redundantfieldloadelimination/InstanceFieldLoadsSeparatedByInvokeCustomTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/redundantfieldloadelimination/InstanceFieldLoadsSeparatedByInvokeCustomTest.java
@@ -4,10 +4,13 @@
package com.android.tools.r8.ir.optimize.redundantfieldloadelimination;
+import static org.hamcrest.CoreMatchers.containsString;
+
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.utils.AndroidApiLevel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -28,6 +31,7 @@
return getTestParameters()
.withCfRuntimes()
.withDexRuntimesStartingFromIncluding(Version.V8_1_0)
+ .withApiLevelsStartingAtIncluding(AndroidApiLevel.O)
.build();
}
@@ -40,8 +44,10 @@
testForR8(parameters.getBackend())
.addProgramClassFileData(InstanceFieldLoadsSeparatedByInvokeCustomTestClassGenerator.dump())
.addKeepAllClassesRule()
- .setMinApi(parameters.getRuntime())
+ .allowDiagnosticWarningMessages()
+ .setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllWarningMessagesMatch(containsString("Unknown bootstrap method"))
.run(parameters.getRuntime(), "InstanceFieldLoadsSeparatedByInvokeCustomTestClass")
.assertSuccess();
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/reflection/InnerClassNameTestRunner.java b/src/test/java/com/android/tools/r8/ir/optimize/reflection/InnerClassNameTestRunner.java
index 8896197..8b33acb 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/reflection/InnerClassNameTestRunner.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/reflection/InnerClassNameTestRunner.java
@@ -143,7 +143,7 @@
@Parameters(name = "{0} minify:{1} {2}")
public static Collection<Object[]> parameters() {
return buildParameters(
- getTestParameters().withAllRuntimes().build(),
+ getTestParameters().withAllRuntimesAndApiLevels().build(),
BooleanUtils.values(),
TestNamingConfig.values());
}
@@ -159,6 +159,23 @@
this.config = config;
}
+ public boolean hasMalformedInnerClassAttribute() {
+ switch (config) {
+ case DEFAULT:
+ case OUTER_ENDS_WITH_DOLLAR:
+ case $_$_$:
+ case DOLLAR2_SEPARATOR:
+ return false;
+ case EMTPY_SEPARATOR:
+ case UNDERBAR_SEPARATOR:
+ case NON_NESTED_INNER:
+ case WRONG_REPACKAGE:
+ return true;
+ default:
+ throw new Unreachable("Unexpected test configuration: " + config);
+ }
+ }
+
private void checkWarningsAboutMalformedAttribute(TestCompileResult<?, ?> result) {
switch (config) {
case DEFAULT:
@@ -188,7 +205,7 @@
testForD8()
.addProgramClassFileData(InnerClassNameTestDump.dump(config, parameters))
.addOptionsModification(InternalOptions::disableNameReflectionOptimization)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.compile();
checkWarningsAboutMalformedAttribute(d8CompileResult);
D8TestRunResult d8RunResult = d8CompileResult.run(parameters.getRuntime(), MAIN_CLASS);
@@ -211,11 +228,13 @@
.addKeepRules("-keep,allowobfuscation class * { *; }")
.addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
.addProgramClassFileData(InnerClassNameTestDump.dump(config, parameters))
+ .allowDiagnosticInfoMessages(hasMalformedInnerClassAttribute())
.minification(minify)
.addOptionsModification(InternalOptions::disableNameReflectionOptimization)
- .setMinApi(parameters.getRuntime())
- .compile();
- checkWarningsAboutMalformedAttribute(r8CompileResult);
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .apply(this::checkWarningsAboutMalformedAttribute);
+
CodeInspector inspector = r8CompileResult.inspector();
R8TestRunResult r8RunResult = r8CompileResult.run(parameters.getRuntime(), MAIN_CLASS);
switch (config) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java
index 1c46c19..4062cb0 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergerValidationTest.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.kotlin.lambda;
import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
+import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.TestParameters;
@@ -54,11 +56,14 @@
.addLibraryFiles(ToolHelper.getKotlinStdlibJar())
.addProgramFiles(ktClasses)
.addKeepMainRule("**.B143165163Kt")
+ .allowDiagnosticInfoMessages()
.setMinApi(parameters.getApiLevel())
.compile()
// TODO(b/143165163): better not output info like this.
- .assertInfoMessageThatMatches(containsString("Unrecognized Kotlin lambda"))
- .assertInfoMessageThatMatches(containsString("unexpected static method"))
+ .assertAllInfoMessagesMatch(
+ allOf(
+ containsString("Unrecognized Kotlin lambda"),
+ containsString("unexpected static method")))
.addRunClasspathFiles(ToolHelper.getKotlinStdlibJar())
.run(parameters.getRuntime(), pkg + ".B143165163Kt")
.assertSuccessWithOutputLines("outer foo bar", "outer foo default");
@@ -80,11 +85,15 @@
.addProgramFiles(ToolHelper.getKotlinStdlibJar())
.addProgramFiles(ktClasses)
.addKeepMainRule("**.B143165163Kt")
+ .allowDiagnosticMessages()
.setMinApi(parameters.getApiLevel())
.compile()
// TODO(b/143165163): better not output info like this.
- .assertInfoMessageThatMatches(containsString("Unrecognized Kotlin lambda"))
- .assertInfoMessageThatMatches(containsString("does not implement any interfaces"))
+ .assertAllInfoMessagesMatch(
+ allOf(
+ containsString("Unrecognized Kotlin lambda"),
+ containsString("does not implement any interfaces")))
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), pkg + ".B143165163Kt")
.assertSuccessWithOutputLines("outer foo bar", "outer foo default");
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
index c2f9bd9..2c42f2a 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataRewriteInLibraryTypeTest.java
@@ -6,6 +6,8 @@
import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
@@ -88,9 +90,14 @@
// Keep the main entry.
.addKeepMainRule(main)
.addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
+ .allowDiagnosticWarningMessages()
// -dontoptimize so that basic code structure is kept.
.noOptimization()
- .compile();
+ .compile()
+ .assertAllWarningMessagesMatch(
+ anyOf(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."),
+ equalTo("Resource 'META-INF/main.kotlin_module' already exists.")));
final String extClassName = pkg + ".libtype_lib_ext.ExtKt";
compileResult.inspect(inspector -> {
ClassSubject ext = inspector.clazz(extClassName);
diff --git a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
index 6c745bf..f93179f 100644
--- a/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/metadata/MetadataStripTest.java
@@ -5,6 +5,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -51,7 +52,11 @@
.addKeepMainRule(mainClassName)
.addKeepAttributes(ProguardKeepAttributes.RUNTIME_VISIBLE_ANNOTATIONS)
.addKeepRules("-keep class kotlin.Metadata")
+ .allowDiagnosticWarningMessages()
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), mainClassName);
CodeInspector inspector = result.inspector();
ClassSubject clazz = inspector.clazz(mainClassName);
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index 3806c05..8bc0e79 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -8,6 +8,7 @@
import static com.android.tools.r8.utils.FileUtils.ZIP_EXTENSION;
import static com.android.tools.r8.utils.FileUtils.withNativeFileSeparators;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import com.android.tools.r8.GenerateMainDexList;
import com.android.tools.r8.GenerateMainDexListCommand;
@@ -328,12 +329,14 @@
.addKeepRules("-keepattributes *Annotation*")
.addMainDexRuleFiles(mainDexRules)
.addOptionsModification(optionsConsumer)
+ .allowDiagnosticWarningMessages()
.assumeAllMethodsMayHaveSideEffects()
.setMinApi(minSdk)
.noMinification()
.noTreeShaking()
.setMainDexListConsumer(ToolHelper.consumeString(r8MainDexListOutput::set))
.compile()
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.writeToZip(out);
List<String> r8MainDexList =
diff --git a/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java b/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
index 3778392..bf33b1c 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
@@ -48,6 +48,7 @@
.addKeepMainRule(mainClass)
// Include explicit main dex entry for class Static.
.addMainDexListClasses(Static.class)
+ .allowDiagnosticWarningMessages()
.compile()
.inspect(this::classStaticGone)
.assertOnlyWarnings()
@@ -66,6 +67,7 @@
.addMainDexListClasses(Main.class, Static.class)
// Include main dex rule for class Static2.
.addMainDexClassRules(Static2.class)
+ .allowDiagnosticWarningMessages()
.compile()
.inspect(this::classStaticGone)
.assertOnlyWarnings()
diff --git a/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java b/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
index d56ae8e..7e15524 100644
--- a/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/naming/EnumMinificationKotlinTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -33,7 +34,7 @@
@Parameterized.Parameters(name = "{0} target: {1} minify: {2}")
public static Collection<Object[]> data() {
return buildParameters(
- getTestParameters().withAllRuntimes().build(),
+ getTestParameters().withAllRuntimesAndApiLevels().build(),
KotlinTargetVersion.values(),
BooleanUtils.values());
}
@@ -52,8 +53,12 @@
.addProgramFiles(getKotlinJarFile(FOLDER))
.addProgramFiles(getJavaJarFile(FOLDER))
.addKeepMainRule(MAIN_CLASS_NAME)
+ .allowDiagnosticWarningMessages()
.minification(minify)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), MAIN_CLASS_NAME)
.inspector();
ClassSubject enumClass = inspector.clazz(ENUM_CLASS_NAME);
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java
index e9383ef..e5a152e 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierMinifierTest.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.utils.DescriptorUtils.descriptorToJavaType;
import static com.android.tools.r8.utils.DescriptorUtils.isValidJavaType;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -46,6 +47,7 @@
private final String appFileName;
private final List<String> keepRulesFiles;
private final BiConsumer<TestParameters, CodeInspector> inspection;
+ private final String test;
public IdentifierMinifierTest(
TestParameters parameters,
@@ -56,18 +58,34 @@
this.appFileName = ToolHelper.EXAMPLES_BUILD_DIR + test + FileUtils.JAR_EXTENSION;
this.keepRulesFiles = keepRulesFiles;
this.inspection = inspection;
+ this.test = test;
}
@Test
public void identiferMinifierTest() throws Exception {
+ boolean hasWarning =
+ test.equals("identifiernamestring") && keepRulesFiles.get(0).endsWith("keep-rules-2.txt");
CodeInspector codeInspector =
testForR8(parameters.getBackend())
.addProgramFiles(Paths.get(appFileName))
.addKeepRuleFiles(ListUtils.map(keepRulesFiles, Paths::get))
.allowUnusedProguardConfigurationRules()
+ .apply(
+ builder -> {
+ if (hasWarning) {
+ builder.allowDiagnosticWarningMessages();
+ }
+ })
.enableProguardTestOptions()
.setMinApi(parameters.getRuntime())
.compile()
+ .inspectDiagnosticMessages(
+ diagnostics -> {
+ if (hasWarning) {
+ diagnostics.assertAllWarningMessagesMatch(
+ containsString("Cannot determine what identifier string flows to"));
+ }
+ })
.inspector();
inspection.accept(parameters, codeInspector);
}
diff --git a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
index 2b06482..e9ce1d8 100644
--- a/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/naming/IdentifierNameStringMarkerTest.java
@@ -3,11 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.R8FullTestBuilder;
+import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.ThrowableConsumer;
import com.android.tools.r8.code.AputObject;
import com.android.tools.r8.code.Const4;
import com.android.tools.r8.code.ConstClass;
@@ -53,7 +57,7 @@
"-keep class " + CLASS_NAME,
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { !static <fields>; }",
"-dontoptimize");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -86,7 +90,7 @@
"-keep class " + CLASS_NAME,
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { !static <fields>; }",
"-dontoptimize");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -129,7 +133,7 @@
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { !static <fields>; }",
"-keep,allowobfuscation class " + BOO,
"-dontoptimize");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -167,7 +171,7 @@
"-keep class " + CLASS_NAME,
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { static <fields>; }",
"-dontoptimize");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -199,7 +203,7 @@
"-keep class " + CLASS_NAME,
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { static <fields>; }",
"-dontoptimize");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -238,7 +242,7 @@
"-keepclassmembers,allowobfuscation class " + CLASS_NAME + " { static <fields>; }",
"-keep,allowobfuscation class " + BOO,
"-dontoptimize");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -268,7 +272,7 @@
"-identifiernamestring class " + CLASS_NAME + " { static java.lang.String sClassName; }",
"-keep class " + CLASS_NAME + " { static java.lang.String sClassName; }",
"-dontshrink");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -290,7 +294,7 @@
"-keep class " + CLASS_NAME + " { static java.lang.String sClassName; }",
"-keep,allowobfuscation class " + BOO,
"-dontshrink");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -314,7 +318,7 @@
"-keep class " + CLASS_NAME + " { static java.lang.String sFieldName; }",
"-keep,allowobfuscation class " + BOO + " { <fields>; }",
"-dontshrink");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -338,7 +342,7 @@
"-keep class " + CLASS_NAME + " { static java.lang.String sMethodName; }",
"-keep,allowobfuscation class " + BOO + " { <methods>; }",
"-dontshrink");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -365,10 +369,20 @@
"invoke-static {v0, v1}, LExample;->foo(Ljava/lang/String;Ljava/lang/String;)V",
"return-void");
- List<String> pgConfigs = ImmutableList.of(
- "-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
- "-keep class " + CLASS_NAME);
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector =
+ compileWithR8(
+ builder,
+ testBuilder ->
+ testBuilder
+ .addKeepRules(
+ "-identifiernamestring class "
+ + CLASS_NAME
+ + " { static void foo(...); }",
+ "-keep class " + CLASS_NAME)
+ .allowDiagnosticWarningMessages())
+ .assertAllWarningMessagesMatch(
+ containsString("Cannot determine what 'Mixed/form.Boo' refers to"))
+ .inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -410,7 +424,7 @@
List<String> pgConfigs = ImmutableList.of(
"-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
"-keep class " + CLASS_NAME);
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -456,7 +470,7 @@
"-identifiernamestring class " + CLASS_NAME + " { static void foo(...); }",
"-keep class " + CLASS_NAME,
"-keep,allowobfuscation class " + BOO);
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -510,7 +524,7 @@
+ "}",
"-keep class " + CLASS_NAME,
"-keep class R { *; }");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -560,7 +574,7 @@
+ "}",
"-keep class " + CLASS_NAME,
"-keep,allowobfuscation class R { *; }");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -617,7 +631,7 @@
+ "}",
"-keep class " + CLASS_NAME,
"-keep class R { *; }");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -678,7 +692,7 @@
+ "}",
"-keep class " + CLASS_NAME,
"-keep,allowobfuscation class R { *; }");
- CodeInspector inspector = getInspectorAfterRunR8(builder, pgConfigs);
+ CodeInspector inspector = compileWithR8(builder, pgConfigs).inspector();
ClassSubject clazz = inspector.clazz(CLASS_NAME);
assertTrue(clazz.isPresent());
@@ -702,13 +716,17 @@
assertNotEquals("foo", constString.getString().toString());
}
- private CodeInspector getInspectorAfterRunR8(
+ private R8TestCompileResult compileWithR8(
SmaliBuilder builder, List<String> proguardConfigurations) throws Exception {
+ return compileWithR8(builder, testBuilder -> testBuilder.addKeepRules(proguardConfigurations));
+ }
+
+ private R8TestCompileResult compileWithR8(
+ SmaliBuilder builder, ThrowableConsumer<R8FullTestBuilder> configuration) throws Exception {
return testForR8(Backend.DEX)
.addProgramDexFileData(builder.compile())
- .addKeepRules(proguardConfigurations)
+ .apply(configuration)
.debug()
- .compile()
- .inspector();
+ .compile();
}
}
diff --git a/src/test/java/com/android/tools/r8/naming/InvalidObfuscationEntryTest.java b/src/test/java/com/android/tools/r8/naming/InvalidObfuscationEntryTest.java
index 982267f..57bd145 100644
--- a/src/test/java/com/android/tools/r8/naming/InvalidObfuscationEntryTest.java
+++ b/src/test/java/com/android/tools/r8/naming/InvalidObfuscationEntryTest.java
@@ -48,7 +48,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimes().build();
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public InvalidObfuscationEntryTest(TestParameters parameters) {
@@ -65,13 +65,10 @@
.addKeepRules("-obfuscationdictionary " + dictionary.toString())
.addKeepAllClassesRuleWithAllowObfuscation()
.addKeepMainRule(Main.class)
- .setMinApi(parameters.getRuntime())
+ .allowDiagnosticInfoMessages()
+ .setMinApi(parameters.getApiLevel())
.compile()
- .inspectDiagnosticMessages(
- testDiagnosticMessages -> {
- testDiagnosticMessages.assertInfoMessageThatMatches(
- containsString("Invalid character"));
- })
+ .assertInfoMessageThatMatches(containsString("Invalid character"))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("Hello from a", "Hello from b")
.inspect(
diff --git a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
index 7828143..daa21a4 100644
--- a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
+++ b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.naming;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -67,12 +68,16 @@
public void test_example3() throws Exception {
TestKotlinClass ex3 = new TestKotlinClass("intrinsics_identifiers.Example3Kt");
String mainClassName = ex3.getClassName();
- TestCompileResult result = testForR8(Backend.DEX)
- .addProgramFiles(getKotlinJarFile(FOLDER))
- .addProgramFiles(getJavaJarFile(FOLDER))
- .addKeepMainRule(mainClassName)
- .minification(minification)
- .compile();
+ TestCompileResult result =
+ testForR8(Backend.DEX)
+ .addProgramFiles(getKotlinJarFile(FOLDER))
+ .addProgramFiles(getJavaJarFile(FOLDER))
+ .addKeepMainRule(mainClassName)
+ .allowDiagnosticWarningMessages()
+ .minification(minification)
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."));
CodeInspector codeInspector = result.inspector();
MethodSubject main = codeInspector.clazz(ex3.getClassName()).mainMethod();
assertThat(main, isPresent());
@@ -116,18 +121,23 @@
String targetFieldName,
String targetMethodName) throws Exception {
String mainClassName = testMain.getClassName();
- TestRunResult result = testForR8(Backend.DEX)
- .addProgramFiles(getKotlinJarFile(FOLDER))
- .addProgramFiles(getJavaJarFile(FOLDER))
- .enableProguardTestOptions()
- .addKeepMainRule(mainClassName)
- .addKeepRules(StringUtils.lines(
- "-neverclassinline class **." + targetClassName,
- "-nevermerge class **." + targetClassName,
- "-neverinline class **." + targetClassName + " { <methods>; }"
- ))
- .minification(minification)
- .run(mainClassName);
+ TestRunResult result =
+ testForR8(Backend.DEX)
+ .addProgramFiles(getKotlinJarFile(FOLDER))
+ .addProgramFiles(getJavaJarFile(FOLDER))
+ .enableProguardTestOptions()
+ .addKeepMainRule(mainClassName)
+ .addKeepRules(
+ StringUtils.lines(
+ "-neverclassinline class **." + targetClassName,
+ "-nevermerge class **." + targetClassName,
+ "-neverinline class **." + targetClassName + " { <methods>; }"))
+ .allowDiagnosticWarningMessages()
+ .minification(minification)
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .run(mainClassName);
CodeInspector codeInspector = result.inspector();
MethodSubject main = codeInspector.clazz(testMain.getClassName()).mainMethod();
diff --git a/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java b/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java
index 44e95ec..26811a4 100644
--- a/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java
+++ b/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java
@@ -21,6 +21,7 @@
.addKeepRules("-keep class NotPresent")
.addOptionsModification(
options -> options.testing.reportUnusedProguardConfigurationRules = true)
+ .allowDiagnosticMessages()
.allowUnusedProguardConfigurationRules()
.compile()
.inspectDiagnosticMessages(
diff --git a/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java b/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java
index 6da44a5..bfe9fe4 100644
--- a/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java
+++ b/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java
@@ -7,6 +7,7 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assume.assumeTrue;
+import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRunResult;
@@ -27,7 +28,7 @@
@Parameterized.Parameters(name = "{0}, separator: {1}")
public static List<Object[]> data() {
return buildParameters(
- getTestParameters().withAllRuntimes().build(), ImmutableList.of("$", "."));
+ getTestParameters().withAllRuntimesAndApiLevels().build(), ImmutableList.of("$", "."));
}
public InnerClassNameSeparatorTest(TestParameters parameters, String separator) {
@@ -37,17 +38,42 @@
@Test
public void testR8() throws Exception {
- TestRunResult<?> result =
- runTest(
- testForR8(parameters.getBackend())
- .addOptionsModification(InternalOptions::disableNameReflectionOptimization)
- .addOptionsModification(
- options -> {
- if (separator.equals(".")) {
- // R8 currently does not recognize the '.' as an inner class name separator.
- options.testing.allowUnusedProguardConfigurationRules = true;
- }
- }));
+ R8TestRunResult result =
+ testForR8(parameters.getBackend())
+ .addOptionsModification(InternalOptions::disableNameReflectionOptimization)
+ .addOptionsModification(
+ options -> {
+ if (separator.equals(".")) {
+ // R8 currently does not recognize the '.' as an inner class name separator.
+ options.testing.allowUnusedProguardConfigurationRules = true;
+ }
+ })
+ .apply(
+ builder -> {
+ if (separator.equals(".")) {
+ builder.allowDiagnosticInfoMessages();
+ }
+ })
+ .addProgramClassesAndInnerClasses(InnerClassNameSeparatorTestClass.class)
+ .addKeepMainRule(InnerClassNameSeparatorTestClass.class)
+ .addKeepRules(
+ "-keep,allowobfuscation class "
+ + InnerClassNameSeparatorTestClass.class.getTypeName()
+ + separator
+ + InnerClassNameSeparatorTestClass.Inner.class.getSimpleName()
+ + " {",
+ " <init>(...);",
+ "}")
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .inspectDiagnosticMessages(
+ diagnostics -> {
+ if (separator.equals(".")) {
+ diagnostics.assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"));
+ }
+ })
+ .run(parameters.getRuntime(), InnerClassNameSeparatorTestClass.class);
if (separator.equals("$")) {
result.assertSuccessWithOutputLines("Hello world!");
} else {
@@ -73,7 +99,7 @@
+ " {",
" <init>(...);",
"}")
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.compile()
.run(parameters.getRuntime(), InnerClassNameSeparatorTestClass.class);
}
diff --git a/src/test/java/com/android/tools/r8/resolution/LibraryExtendsProgramRefinedReceiverIsLibraryClass.java b/src/test/java/com/android/tools/r8/resolution/LibraryExtendsProgramRefinedReceiverIsLibraryClass.java
index db1864c..2bd5e75 100644
--- a/src/test/java/com/android/tools/r8/resolution/LibraryExtendsProgramRefinedReceiverIsLibraryClass.java
+++ b/src/test/java/com/android/tools/r8/resolution/LibraryExtendsProgramRefinedReceiverIsLibraryClass.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.resolution;
+import static org.hamcrest.CoreMatchers.containsString;
+
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -47,9 +49,11 @@
.enableInliningAnnotations()
.addKeepClassRules(ProgramClass.class)
.addKeepMainRule(ProgramTestRunnerWithoutPhi.class)
+ .allowDiagnosticWarningMessages()
.setMinApi(parameters.getApiLevel())
.debug()
.compile()
+ .assertAllWarningMessagesMatch(containsString("extends program class"))
.addRunClasspathClasses(LibraryClass.class)
.run(parameters.getRuntime(), ProgramTestRunnerWithoutPhi.class)
.assertSuccessWithOutput(StringUtils.lines("SUCCESS"));
@@ -64,8 +68,10 @@
.enableInliningAnnotations()
.addKeepClassRules(ProgramClass.class)
.addKeepMainRule(ProgramTestRunnerWithPhi.class)
+ .allowDiagnosticWarningMessages()
.setMinApi(parameters.getApiLevel())
.compile()
+ .assertAllWarningMessagesMatch(containsString("extends program class"))
.addRunClasspathClasses(LibraryClass.class)
.run(parameters.getRuntime(), ProgramTestRunnerWithPhi.class)
.assertSuccessWithOutput(StringUtils.lines("SUCCESS"));
diff --git a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
index 5d2a2d8..13190d9 100644
--- a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
+++ b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionInSameFileRetraceTests.java
@@ -10,6 +10,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineFrame;
import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineStack;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
@@ -86,8 +87,11 @@
.addKeepAttributes("SourceFile", "LineNumberTable")
.setMode(CompilationMode.RELEASE)
.addKeepMainRule(MAIN)
+ .allowDiagnosticWarningMessages()
.noMinification()
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), MAIN)
.assertFailureWithErrorThatMatches(containsString("main"))
.inspectStackTrace(
diff --git a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
index e2fe820..2d9f47b 100644
--- a/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/KotlinInlineFunctionRetraceTest.java
@@ -11,6 +11,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineFrame;
import static com.android.tools.r8.utils.codeinspector.Matchers.isInlineStack;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringContains.containsString;
@@ -81,9 +82,12 @@
.addProgramFiles(compilationResults.apply(parameters.getRuntime()))
.addProgramFiles(ToolHelper.getKotlinStdlibJar())
.addKeepAttributes("SourceFile", "LineNumberTable")
+ .allowDiagnosticWarningMessages()
.setMode(CompilationMode.RELEASE)
.addKeepMainRule(main)
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), main)
.assertFailureWithErrorThatMatches(containsString("inlineExceptionStatic"))
.inspectStackTrace(
@@ -106,9 +110,12 @@
.addProgramFiles(compilationResults.apply(parameters.getRuntime()))
.addProgramFiles(ToolHelper.getKotlinStdlibJar())
.addKeepAttributes("SourceFile", "LineNumberTable")
+ .allowDiagnosticWarningMessages()
.setMode(CompilationMode.RELEASE)
.addKeepMainRule(main)
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), main)
.assertFailureWithErrorThatMatches(containsString("inlineExceptionInstance"))
.inspectStackTrace(
@@ -131,9 +138,12 @@
.addProgramFiles(compilationResults.apply(parameters.getRuntime()))
.addProgramFiles(ToolHelper.getKotlinStdlibJar())
.addKeepAttributes("SourceFile", "LineNumberTable")
+ .allowDiagnosticWarningMessages()
.setMode(CompilationMode.RELEASE)
.addKeepMainRule(main)
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), main)
.assertFailureWithErrorThatMatches(containsString("inlineExceptionStatic"))
.inspectStackTrace(
@@ -158,9 +168,12 @@
.addProgramFiles(compilationResults.apply(parameters.getRuntime()))
.addProgramFiles(ToolHelper.getKotlinStdlibJar())
.addKeepAttributes("SourceFile", "LineNumberTable")
+ .allowDiagnosticWarningMessages()
.setMode(CompilationMode.RELEASE)
.addKeepMainRule(main)
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
.run(parameters.getRuntime(), main)
.assertFailureWithErrorThatMatches(containsString("inlineExceptionStatic"))
.inspectStackTrace(
diff --git a/src/test/java/com/android/tools/r8/rewrite/JavaScriptScriptEngineTest.java b/src/test/java/com/android/tools/r8/rewrite/JavaScriptScriptEngineTest.java
index 5143949..b299b76 100644
--- a/src/test/java/com/android/tools/r8/rewrite/JavaScriptScriptEngineTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/JavaScriptScriptEngineTest.java
@@ -4,6 +4,9 @@
package com.android.tools.r8.rewrite;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assume.assumeTrue;
import com.android.tools.r8.CompilationFailedException;
@@ -26,7 +29,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimes().build();
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public JavaScriptScriptEngineTest(TestParameters parameters) {
@@ -41,7 +44,7 @@
assumeTrue("Only run D8 for dex backend", parameters.isDexRuntime());
testForD8()
.addInnerClasses(JavaScriptScriptEngineTest.class)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.apply(this::addRhinoForAndroid)
.compile()
.run(parameters.getRuntime(), TestClassWithExplicitRhinoScriptEngineRegistration.class)
@@ -53,15 +56,21 @@
testForR8(parameters.getBackend())
.addInnerClasses(JavaScriptScriptEngineTest.class)
.addKeepMainRule(TestClass.class)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.apply(
b -> {
if (parameters.isDexRuntime()) {
addRhinoForAndroid(b);
addKeepRulesForAndroidRhino(b);
+ b.allowDiagnosticWarningMessages();
}
})
.compile()
+ .assertAllWarningMessagesMatch(
+ anyOf(
+ containsString("Missing class:"),
+ containsString("required for default or static interface methods desugaring"),
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists.")))
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(
parameters.isCfRuntime() ? EXPECTED_NASHORN_OUTPUT : EXPECTED_RHINO_OUTPUT);
diff --git a/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java b/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java
index 4e451ee..c7037ca 100644
--- a/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/ScriptEngineTest.java
@@ -4,12 +4,14 @@
package com.android.tools.r8.rewrite;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DataEntryResource;
-import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.origin.Origin;
@@ -41,7 +43,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimes().build();
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public ScriptEngineTest(TestParameters parameters) {
@@ -51,33 +53,37 @@
@Test
public void test() throws IOException, CompilationFailedException, ExecutionException {
Path path = temp.newFile("out.zip").toPath();
- R8FullTestBuilder builder =
- testForR8(parameters.getBackend())
- .addInnerClasses(ScriptEngineTest.class)
- .addKeepMainRule(TestClass.class)
- .setMinApi(parameters.getRuntime())
- .addDataEntryResources(
- DataEntryResource.fromBytes(
- StringUtils.lines(MyScriptEngine1FactoryImpl.class.getTypeName()).getBytes(),
- "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
- Origin.unknown()))
- .addDataEntryResources(
- DataEntryResource.fromBytes(
- StringUtils.lines(MyScriptEngine2FactoryImpl.class.getTypeName()).getBytes(),
- "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
- Origin.unknown()))
- .apply(
- b -> {
- if (parameters.isDexRuntime()) {
- addRhinoForAndroid(b);
- }
- })
- // TODO(b/136633154): This should work both with and without -dontobfuscate.
- .noMinification()
- // TODO(b/136633154): This should work both with and without -dontshrink.
- .noTreeShaking();
- builder
+ testForR8(parameters.getBackend())
+ .addInnerClasses(ScriptEngineTest.class)
+ .addKeepMainRule(TestClass.class)
+ .setMinApi(parameters.getApiLevel())
+ .addDataEntryResources(
+ DataEntryResource.fromBytes(
+ StringUtils.lines(MyScriptEngine1FactoryImpl.class.getTypeName()).getBytes(),
+ "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
+ Origin.unknown()))
+ .addDataEntryResources(
+ DataEntryResource.fromBytes(
+ StringUtils.lines(MyScriptEngine2FactoryImpl.class.getTypeName()).getBytes(),
+ "META-INF/services/" + ScriptEngineFactory.class.getTypeName(),
+ Origin.unknown()))
+ .apply(
+ b -> {
+ if (parameters.isDexRuntime()) {
+ addRhinoForAndroid(b);
+ b.allowDiagnosticWarningMessages();
+ }
+ })
+ // TODO(b/136633154): This should work both with and without -dontobfuscate.
+ .noMinification()
+ // TODO(b/136633154): This should work both with and without -dontshrink.
+ .noTreeShaking()
.compile()
+ .assertAllWarningMessagesMatch(
+ anyOf(
+ containsString("Missing class:"),
+ containsString("it is required for default or static interface methods desugaring"),
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists.")))
.writeToZip(path)
.run(parameters.getRuntime(), TestClass.class)
// TODO(b/136633154): This should provide 2 script engines on both runtimes. The use of
diff --git a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
index b42be41..5b119ce 100644
--- a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
@@ -7,6 +7,7 @@
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.core.IsNot.not;
import com.android.tools.r8.D8TestRunResult;
@@ -79,7 +80,9 @@
@Parameters(name = "{0}, mode: {1}, use interface: {2}")
public static Collection<Object[]> parameters() {
return buildParameters(
- getTestParameters().withAllRuntimes().build(), Mode.values(), BooleanUtils.values());
+ getTestParameters().withAllRuntimesAndApiLevels().build(),
+ Mode.values(),
+ BooleanUtils.values());
}
@Test
@@ -171,7 +174,8 @@
jasminBuilder.writeJar(inputJar);
if (parameters.isCfRuntime()) {
- TestRunResult<?> jvmResult = testForJvm().addClasspath(inputJar).run(mainClass.name);
+ TestRunResult<?> jvmResult =
+ testForJvm().addClasspath(inputJar).run(parameters.getRuntime(), mainClass.name);
checkTestRunResult(jvmResult, Compiler.JAVAC);
ProguardTestRunResult proguardResult =
@@ -184,10 +188,12 @@
} else {
assert parameters.isDexRuntime();
- DXTestRunResult dxResult = testForDX().addProgramFiles(inputJar).run(mainClass.name);
+ DXTestRunResult dxResult =
+ testForDX().addProgramFiles(inputJar).run(parameters.getRuntime(), mainClass.name);
checkTestRunResult(dxResult, Compiler.DX);
- D8TestRunResult d8Result = testForD8().addProgramFiles(inputJar).run(mainClass.name);
+ D8TestRunResult d8Result =
+ testForD8().addProgramFiles(inputJar).run(parameters.getRuntime(), mainClass.name);
checkTestRunResult(d8Result, Compiler.D8);
}
@@ -205,7 +211,14 @@
options.testing.allowTypeErrors = true;
}
})
- .setMinApi(parameters.getRuntime())
+ .allowDiagnosticWarningMessages(
+ mode == Mode.INVOKE_UNVERIFIABLE_METHOD && !useInterface)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo(
+ "The method `void UnverifiableClass.unverifiableMethod()` does not type check"
+ + " and will be assumed to be unreachable."))
.run(parameters.getRuntime(), mainClass.name);
checkTestRunResult(r8Result, Compiler.R8);
@@ -224,7 +237,14 @@
}
options.enableUninstantiatedTypeOptimizationForInterfaces = true;
})
- .setMinApi(parameters.getRuntime())
+ .allowDiagnosticWarningMessages(
+ mode == Mode.INVOKE_UNVERIFIABLE_METHOD && !useInterface)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo(
+ "The method `void UnverifiableClass.unverifiableMethod()` does not type check"
+ + " and will be assumed to be unreachable."))
.run(parameters.getRuntime(), mainClass.name);
checkTestRunResult(
r8ResultWithUninstantiatedTypeOptimizationForInterfaces,
diff --git a/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java b/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java
index 4c9b057..3355fab 100644
--- a/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/UsageInformationConsumerTest.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.TestBase;
@@ -11,8 +12,6 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.StringUtils;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -49,16 +48,16 @@
@Test
public void testRule() throws Exception {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
testForR8(parameters.getBackend())
- .redirectStdOut(new PrintStream(out))
+ .collectStdout()
.addProgramClasses(TestClass.class, UnusedClass.class)
.addKeepClassAndMembersRules(TestClass.class)
.addKeepRules("-printusage")
.setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertStdoutThatMatches(equalTo(StringUtils.lines(UnusedClass.class.getTypeName())))
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
- assertEquals(StringUtils.lines(UnusedClass.class.getTypeName()), out.toString());
}
static class UnusedClass {
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java b/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
index 5c6a305..84ceffa 100644
--- a/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/annotations/ReflectiveAnnotationUseTest.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -62,7 +63,7 @@
@Parameterized.Parameters(name = "{0} target: {1} minify: {2}")
public static Collection<Object[]> data() {
return buildParameters(
- getTestParameters().withAllRuntimes().build(),
+ getTestParameters().withAllRuntimesAndApiLevels().build(),
KotlinTargetVersion.values(),
BooleanUtils.values());
}
@@ -87,20 +88,22 @@
@Test
public void b120951621_keepAll() throws Exception {
- CodeInspector inspector = testForR8(parameters.getBackend())
- .addProgramFiles(getKotlinJarFile(FOLDER))
- .addProgramFiles(getJavaJarFile(FOLDER))
- .addKeepMainRule(MAIN_CLASS_NAME)
- .addKeepRules(KEEP_ANNOTATIONS)
- .addKeepRules(
- "-keep @interface " + ANNOTATION_NAME + " {",
- " *;",
- "}"
- )
- .minification(minify)
- .setMinApi(parameters.getRuntime())
- .run(parameters.getRuntime(), MAIN_CLASS_NAME)
- .assertSuccessWithOutput(JAVA_OUTPUT).inspector();
+ CodeInspector inspector =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(getKotlinJarFile(FOLDER))
+ .addProgramFiles(getJavaJarFile(FOLDER))
+ .addKeepMainRule(MAIN_CLASS_NAME)
+ .addKeepRules(KEEP_ANNOTATIONS)
+ .addKeepRules("-keep @interface " + ANNOTATION_NAME + " {", " *;", "}")
+ .allowDiagnosticWarningMessages()
+ .minification(minify)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .run(parameters.getRuntime(), MAIN_CLASS_NAME)
+ .assertSuccessWithOutput(JAVA_OUTPUT)
+ .inspector();
ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
assertThat(clazz, isPresent());
assertThat(clazz, not(isRenamed()));
@@ -126,20 +129,25 @@
@Test
public void b120951621_partiallyKeep() throws Exception {
- CodeInspector inspector = testForR8(parameters.getBackend())
- .addProgramFiles(getKotlinJarFile(FOLDER))
- .addProgramFiles(getJavaJarFile(FOLDER))
- .addKeepMainRule(MAIN_CLASS_NAME)
- .addKeepRules(KEEP_ANNOTATIONS)
- .addKeepRules(
- "-keep,allowobfuscation @interface " + ANNOTATION_NAME + " {",
- " java.lang.String *f2();",
- "}"
- )
- .minification(minify)
- .setMinApi(parameters.getRuntime())
- .run(parameters.getRuntime(), MAIN_CLASS_NAME)
- .assertSuccessWithOutput(JAVA_OUTPUT).inspector();
+ CodeInspector inspector =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(getKotlinJarFile(FOLDER))
+ .addProgramFiles(getJavaJarFile(FOLDER))
+ .addKeepMainRule(MAIN_CLASS_NAME)
+ .addKeepRules(KEEP_ANNOTATIONS)
+ .addKeepRules(
+ "-keep,allowobfuscation @interface " + ANNOTATION_NAME + " {",
+ " java.lang.String *f2();",
+ "}")
+ .allowDiagnosticWarningMessages()
+ .minification(minify)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .run(parameters.getRuntime(), MAIN_CLASS_NAME)
+ .assertSuccessWithOutput(JAVA_OUTPUT)
+ .inspector();
ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
assertThat(clazz, isPresent());
assertEquals(minify, clazz.isRenamed());
@@ -163,15 +171,21 @@
@Test
public void b120951621_keepAnnotation() throws Exception {
- CodeInspector inspector = testForR8(parameters.getBackend())
- .addProgramFiles(getKotlinJarFile(FOLDER))
- .addProgramFiles(getJavaJarFile(FOLDER))
- .addKeepMainRule(MAIN_CLASS_NAME)
- .addKeepRules(KEEP_ANNOTATIONS)
- .minification(minify)
- .setMinApi(parameters.getRuntime())
- .run(parameters.getRuntime(), MAIN_CLASS_NAME)
- .assertSuccessWithOutput(JAVA_OUTPUT).inspector();
+ CodeInspector inspector =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(getKotlinJarFile(FOLDER))
+ .addProgramFiles(getJavaJarFile(FOLDER))
+ .addKeepMainRule(MAIN_CLASS_NAME)
+ .addKeepRules(KEEP_ANNOTATIONS)
+ .allowDiagnosticWarningMessages()
+ .minification(minify)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .run(parameters.getRuntime(), MAIN_CLASS_NAME)
+ .assertSuccessWithOutput(JAVA_OUTPUT)
+ .inspector();
ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
assertThat(clazz, isPresent());
assertEquals(minify, clazz.isRenamed());
@@ -195,14 +209,20 @@
@Test
public void b120951621_noKeep() throws Exception {
- CodeInspector inspector = testForR8(parameters.getBackend())
- .addProgramFiles(getKotlinJarFile(FOLDER))
- .addProgramFiles(getJavaJarFile(FOLDER))
- .addKeepMainRule(MAIN_CLASS_NAME)
- .minification(minify)
- .setMinApi(parameters.getRuntime())
- .run(parameters.getRuntime(), MAIN_CLASS_NAME)
- .assertSuccessWithOutput(OUTPUT_WITHOUT_ANNOTATION).inspector();
+ CodeInspector inspector =
+ testForR8(parameters.getBackend())
+ .addProgramFiles(getKotlinJarFile(FOLDER))
+ .addProgramFiles(getJavaJarFile(FOLDER))
+ .addKeepMainRule(MAIN_CLASS_NAME)
+ .allowDiagnosticWarningMessages()
+ .minification(minify)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllWarningMessagesMatch(
+ equalTo("Resource 'META-INF/MANIFEST.MF' already exists."))
+ .run(parameters.getRuntime(), MAIN_CLASS_NAME)
+ .assertSuccessWithOutput(OUTPUT_WITHOUT_ANNOTATION)
+ .inspector();
ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
assertThat(clazz, isPresent());
assertEquals(minify, clazz.isRenamed());
diff --git a/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java b/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java
index fd2696f..bd29735 100644
--- a/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java
@@ -274,11 +274,15 @@
AndroidApiLevel.O_MR1,
AndroidApiLevel.O_MR1,
expectedResultForNative(AndroidApiLevel.O_MR1),
- builder ->
- builder.addOptionsModification(
- options ->
- // android.os.Build$VERSION only exists in the Android runtime.
- options.testing.allowUnusedProguardConfigurationRules = backend == Backend.CF),
+ builder -> {
+ // android.os.Build$VERSION only exists in the Android runtime.
+ if (backend == Backend.CF) {
+ builder
+ .addOptionsModification(
+ options -> options.testing.allowUnusedProguardConfigurationRules = true)
+ .allowDiagnosticInfoMessages();
+ }
+ },
this::compatCodeNotPresent,
ImmutableList.of(
"-assumevalues class android.os.Build$VERSION { public static final int SDK_INT return "
@@ -307,9 +311,14 @@
AndroidApiLevel.O_MR1,
AndroidApiLevel.O_MR1,
expectedResultForNative(AndroidApiLevel.O_MR1),
- builder ->
- builder.addOptionsModification(
- options -> options.testing.allowUnusedProguardConfigurationRules = true),
+ builder -> {
+ if (backend == Backend.CF) {
+ builder
+ .addOptionsModification(
+ options -> options.testing.allowUnusedProguardConfigurationRules = true)
+ .allowDiagnosticInfoMessages();
+ }
+ },
this::compatCodePresent,
ImmutableList.of(rule),
SynthesizedRule.NOT_PRESENT);
@@ -333,8 +342,10 @@
AndroidApiLevel.O_MR1,
expectedResultForNative(AndroidApiLevel.O_MR1),
builder ->
- builder.addOptionsModification(
- options -> options.testing.allowUnusedProguardConfigurationRules = true),
+ builder
+ .addOptionsModification(
+ options -> options.testing.allowUnusedProguardConfigurationRules = true)
+ .allowDiagnosticInfoMessages(),
this::compatCodeNotPresent,
ImmutableList.of(rule),
SynthesizedRule.PRESENT);
diff --git a/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java b/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
index 6d0d767..4ce41ce 100644
--- a/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/b134858535/EventPublisherTest.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.shaking.b134858535;
+import static org.hamcrest.CoreMatchers.containsString;
+
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -25,7 +27,9 @@
.addProgramClassFileData(EventPublisher$bDump.dump())
.addKeepClassRules(Interface.class)
.addKeepMainRule(Main.class)
+ .allowDiagnosticInfoMessages()
.setMinApi(AndroidApiLevel.L)
- .compile();
+ .compile()
+ .assertAllWarningMessagesMatch(containsString("Unrecognized Kotlin lambda"));
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/desugar/KeepRuleWarningTest.java b/src/test/java/com/android/tools/r8/shaking/desugar/KeepRuleWarningTest.java
index ab37cb0..27bb092 100644
--- a/src/test/java/com/android/tools/r8/shaking/desugar/KeepRuleWarningTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/desugar/KeepRuleWarningTest.java
@@ -8,9 +8,14 @@
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
@NeverMerge
interface I {
@@ -34,68 +39,82 @@
}
}
+@RunWith(Parameterized.class)
public class KeepRuleWarningTest extends TestBase {
+
private static final Class<?> MAIN = KeepRuleWarningTestRunner.class;
private static final String EXPECTED_OUTPUT = StringUtils.lines("static::foo", "default::bar");
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withDexRuntimes().withApiLevel(AndroidApiLevel.L).build();
+ }
+
+ public KeepRuleWarningTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
@Test
public void test_allMethods() throws Exception {
- testForR8(Backend.DEX)
+ testForR8(parameters.getBackend())
.addProgramClasses(I.class, C.class, MAIN)
- .setMinApi(AndroidApiLevel.L)
+ .setMinApi(parameters.getApiLevel())
.enableMergeAnnotations()
.addKeepMainRule(MAIN)
.addKeepRules("-keep interface **.I { <methods>; }")
.compile()
.inspectDiagnosticMessages(TestDiagnosticMessages::assertNoMessages)
- .run(MAIN)
+ .run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Test
public void test_asterisk() throws Exception {
- testForR8(Backend.DEX)
+ testForR8(parameters.getBackend())
.addProgramClasses(I.class, C.class, MAIN)
- .setMinApi(AndroidApiLevel.L)
+ .setMinApi(parameters.getApiLevel())
.enableMergeAnnotations()
.addKeepMainRule(MAIN)
.addKeepRules("-keep interface **.I { *(); }")
.compile()
.inspectDiagnosticMessages(TestDiagnosticMessages::assertNoMessages)
- .run(MAIN)
+ .run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Test
public void test_stillNotSpecific() throws Exception {
- testForR8(Backend.DEX)
+ testForR8(parameters.getBackend())
.addProgramClasses(I.class, C.class, MAIN)
- .setMinApi(AndroidApiLevel.L)
+ .setMinApi(parameters.getApiLevel())
.enableMergeAnnotations()
.addKeepMainRule(MAIN)
.addKeepRules("-keep interface **.I { *** f*(); }")
.compile()
.inspectDiagnosticMessages(TestDiagnosticMessages::assertNoMessages)
- .run(MAIN)
+ .run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Test
public void test_specific() throws Exception {
- testForR8(Backend.DEX)
+ testForR8(parameters.getBackend())
.addProgramClasses(I.class, C.class, MAIN)
- .setMinApi(AndroidApiLevel.L)
+ .setMinApi(parameters.getApiLevel())
.enableMergeAnnotations()
.addKeepMainRule(MAIN)
.addKeepRules("-keep interface **.I { static void foo(); }")
+ .allowDiagnosticWarningMessages()
.compile()
- .inspectDiagnosticMessages(m -> {
- m.assertWarningsCount(1)
- .assertWarningMessageThatMatches(containsString("static void foo()"))
- .assertWarningMessageThatMatches(containsString("is ignored"))
- .assertWarningMessageThatMatches(containsString("will be desugared"));
- })
- .run(MAIN)
+ .inspectDiagnosticMessages(
+ m ->
+ m.assertWarningsCount(1)
+ .assertWarningMessageThatMatches(containsString("static void foo()"))
+ .assertWarningMessageThatMatches(containsString("is ignored"))
+ .assertWarningMessageThatMatches(containsString("will be desugared")))
+ .run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED_OUTPUT);
}
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java
index 8cb1cf0..203dd3a 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAccessModifierTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.shaking.ifrule;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -47,6 +48,10 @@
}
private TestShrinkerBuilder<?, ?, ?, ?, ?> getTestBuilder() {
+ return getTestBuilder(false);
+ }
+
+ private TestShrinkerBuilder<?, ?, ?, ?, ?> getTestBuilder(boolean allowDiagnosticInfoMessages) {
switch (shrinker) {
case PROGUARD6:
assertTrue(parameters.isCfRuntime());
@@ -54,6 +59,7 @@
case R8:
return testForR8(parameters.getBackend())
.addTestingAnnotationsAsProgramClasses()
+ .allowDiagnosticInfoMessages(allowDiagnosticInfoMessages)
.allowUnusedProguardConfigurationRules()
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations();
@@ -66,7 +72,7 @@
public void ifOnPublic_noPublicClassForIfRule() throws Exception {
assumeFalse(shrinker.isProguard() && parameters.isDexRuntime());
- getTestBuilder()
+ getTestBuilder(shrinker.isR8())
.addProgramClasses(CLASSES)
.addKeepRules(
"-repackageclasses 'top'",
@@ -81,6 +87,13 @@
"}")
.setMinApi(parameters.getApiLevel())
.compile()
+ .apply(
+ compileResult -> {
+ if (shrinker.isR8()) {
+ compileResult.assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"));
+ }
+ })
.inspect(
inspector -> {
ClassSubject classSubject = inspector.clazz(ClassForIf.class);
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java
index 54fcadf..eab27a0 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java
@@ -9,6 +9,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPublic;
import static com.android.tools.r8.utils.codeinspector.Matchers.isStatic;
import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -17,15 +18,32 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
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 IfRuleWithInterfaceMethodDesugaringTest extends TestBase {
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withDexRuntimes().withApiLevel(AndroidApiLevel.M).build();
+ }
+
+ public IfRuleWithInterfaceMethodDesugaringTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
@Test
public void test() throws Exception {
String expectedOutput =
@@ -34,7 +52,7 @@
testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expectedOutput);
CodeInspector inspector =
- testForR8(Backend.DEX)
+ testForR8(parameters.getBackend())
.addInnerClasses(IfRuleWithInterfaceMethodDesugaringTest.class)
.addKeepMainRule(TestClass.class)
.addKeepRules(
@@ -46,12 +64,16 @@
" !public !static void virtualMethod();",
"}",
"-keep class " + Unused2.class.getTypeName())
+ .allowDiagnosticInfoMessages()
.allowUnusedProguardConfigurationRules()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableMergeAnnotations()
- .setMinApi(AndroidApiLevel.M)
- .run(TestClass.class)
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"))
+ .run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(expectedOutput)
.inspector();
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/RemovedClassTestRunner.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/RemovedClassTestRunner.java
index 37ba854..9edc64d 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/RemovedClassTestRunner.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/RemovedClassTestRunner.java
@@ -5,20 +5,19 @@
import static com.android.tools.r8.references.Reference.classFromClass;
import static com.android.tools.r8.references.Reference.methodFromMethod;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.graphinspector.GraphInspector;
import com.android.tools.r8.utils.graphinspector.GraphInspector.QueryNode;
import com.google.common.collect.ImmutableList;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.nio.charset.StandardCharsets;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,15 +33,15 @@
private static final String EXPECTED = StringUtils.lines("called bar");
- private final Backend backend;
+ private final TestParameters parameters;
@Parameters(name = "{0}")
- public static Backend[] data() {
- return ToolHelper.getBackends();
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
- public RemovedClassTestRunner(Backend backend) {
- this.backend = backend;
+ public RemovedClassTestRunner(TestParameters parameters) {
+ this.parameters = parameters;
}
@Test
@@ -51,22 +50,24 @@
MethodReference barMethod = methodFromMethod(CLASS.getDeclaredMethod("bar"));
MethodReference bazMethod = methodFromMethod(CLASS.getDeclaredMethod("baz"));
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
R8TestCompileResult compileResult =
- testForR8(backend)
+ testForR8(parameters.getBackend())
.enableGraphInspector()
.enableInliningAnnotations()
.addProgramClasses(CLASSES)
.addKeepMethodRules(mainMethod)
.addKeepRules("-whyareyoukeeping class " + REMOVED_CLASS.getTypeName())
- .redirectStdOut(new PrintStream(baos))
- .compile();
- String expectedOutput = StringUtils.lines("Nothing is keeping " + REMOVED_CLASS.getTypeName());
- String compileOutput = new String(baos.toByteArray(), StandardCharsets.UTF_8);
- assertEquals(expectedOutput, compileOutput);
+ .setMinApi(parameters.getApiLevel())
+ .collectStdout()
+ .compile()
+ .assertStdoutThatMatches(
+ equalTo(StringUtils.lines("Nothing is keeping " + REMOVED_CLASS.getTypeName())));
GraphInspector inspector =
- compileResult.run(CLASS).assertSuccessWithOutput(EXPECTED).graphInspector();
+ compileResult
+ .run(parameters.getRuntime(), CLASS)
+ .assertSuccessWithOutput(EXPECTED)
+ .graphInspector();
// The only root should be the keep main-method rule.
assertEquals(1, inspector.getRoots().size());
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java
index f4ed50c..2387e7c 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java
@@ -5,7 +5,6 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -13,7 +12,6 @@
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.utils.StringUtils;
import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.Test;
@@ -40,7 +38,7 @@
return getTestParameters().withNoneRuntime().build();
}
- final TestParameters parameters;
+ private final TestParameters parameters;
public WhyAreYouKeepingAllTest(TestParameters parameters) {
this.parameters = parameters;
@@ -53,13 +51,13 @@
.addProgramFiles(ToolHelper.R8_WITH_RELOCATED_DEPS_JAR)
.addKeepRuleFiles(MAIN_KEEP)
.addKeepRules(WHY_ARE_YOU_KEEPING_ALL)
- .redirectStdOut(new PrintStream(baos))
- .compile();
- assertThat(baos.toString(), containsString("referenced in keep rule"));
-
- // TODO(b/124655065): We should always know the reason for keeping.
- // It is OK if this starts failing while the kept-graph API is incomplete, in which case replace
- // the 'not(containsString(' by just 'containsString('.
- assertThat(baos.toString(), not(containsString("kept for unknown reasons")));
+ .collectStdout()
+ .compile()
+ .assertStdoutThatMatches(containsString("referenced in keep rule"))
+ // TODO(b/124655065): We should always know the reason for keeping.
+ // It is OK if this starts failing while the kept-graph API is incomplete, in which case
+ // replace
+ // the 'not(containsString(' by just 'containsString('.
+ .assertStdoutThatMatches(not(containsString("kept for unknown reasons")));
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingOverriddenMethodTest.java b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingOverriddenMethodTest.java
index 2914c4e..39d3aaf 100644
--- a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingOverriddenMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingOverriddenMethodTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.shaking.WhyAreYouKeepingConsumer;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
@@ -45,7 +46,6 @@
private void testViaConfig(Class<?> main, Class<?> targetClass, Class<?> subClass)
throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
testForR8(Backend.DEX)
.addInnerClasses(WhyAreYouKeepingOverriddenMethodTest.class)
.addKeepMainRule(main)
@@ -55,13 +55,12 @@
.enableInliningAnnotations()
.enableMergeAnnotations()
.minification(minification)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(AndroidApiLevel.B)
// Redirect the compilers stdout to intercept the '-whyareyoukeeping' output
- .redirectStdOut(new PrintStream(baos))
- .compile();
- String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
- assertThat(output, containsString(expectedMessage(targetClass)));
- assertThat(output, not(containsString(expectedNotContainingMessage(subClass))));
+ .collectStdout()
+ .compile()
+ .assertStdoutThatMatches(containsString(expectedMessage(targetClass)))
+ .assertStdoutThatMatches(not(containsString(expectedNotContainingMessage(subClass))));
}
private void testViaConsumer(
@@ -74,7 +73,7 @@
.enableInliningAnnotations()
.enableMergeAnnotations()
.minification(minification)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(AndroidApiLevel.B)
.setKeptGraphConsumer(graphConsumer)
.compile();
diff --git a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
index c230c00..92578d3 100644
--- a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
@@ -4,8 +4,10 @@
package com.android.tools.r8.shaking.whyareyoukeeping;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.NeverInline;
@@ -77,10 +79,9 @@
.addKeepMethodRules(Reference.methodFromMethod(A.class.getMethod("foo")))
.addKeepRules("-whyareyoukeeping class " + A.class.getTypeName())
// Redirect the compilers stdout to intercept the '-whyareyoukeeping' output
- .redirectStdOut(new PrintStream(baos))
- .compile();
- String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
- assertEquals(expected, output);
+ .collectStdout()
+ .compile()
+ .assertStdoutThatMatches(equalTo(expected));
}
@Test
@@ -108,10 +109,9 @@
.addKeepRules("-whyareyoukeeping class " + A.class.getTypeName() + " { baz(); }")
.addKeepMethodRules(Reference.methodFromMethod(A.class.getMethod("foo")))
// Redirect the compilers stdout to intercept the '-whyareyoukeeping' output
- .redirectStdOut(new PrintStream(baos))
- .compile();
- String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
- assertEquals(expected + expectedPathToBaz, output);
+ .collectStdout()
+ .compile()
+ .assertStdoutThatMatches(equalTo(expected + expectedPathToBaz));
}
@Test
@@ -138,13 +138,14 @@
.addProgramClasses(A.class)
.addKeepMethodRules(Reference.methodFromMethod(A.class.getMethod("foo")))
.addKeepRules("-whyareyoukeeping class NonExistentClass")
+ .allowDiagnosticInfoMessages()
.allowUnusedProguardConfigurationRules()
// Redirect the compilers stdout to intercept the '-whyareyoukeeping' output
- .redirectStdOut(new PrintStream(baos))
- .compile();
- String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
- // Expected outcome is empty.
- assertEquals("", output);
+ .collectStdout()
+ .compile()
+ .assertNoStdout()
+ .assertAllInfoMessagesMatch(
+ containsString("Proguard configuration rule does not match anything"));
}
@Test
@@ -156,10 +157,8 @@
.addKeepMethodRules(Reference.methodFromMethod(A.class.getMethod("foo")))
.addKeepRules("-whyareyoukeeping class " + aName + " { nonExistentMethod(); }")
// Redirect the compilers stdout to intercept the '-whyareyoukeeping' output
- .redirectStdOut(new PrintStream(baos))
- .compile();
- String output = new String(baos.toByteArray(), StandardCharsets.UTF_8);
- // Expected outcome is empty.
- assertFalse("b/122820741", output.isEmpty());
+ .collectStdout()
+ .compile()
+ .assertStdoutThatMatches(not(equalTo("")));
}
}
diff --git a/src/test/java/com/android/tools/r8/utils/ForwardingOutputStream.java b/src/test/java/com/android/tools/r8/utils/ForwardingOutputStream.java
new file mode 100644
index 0000000..082c947
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/ForwardingOutputStream.java
@@ -0,0 +1,54 @@
+// 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.utils;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.List;
+
+public class ForwardingOutputStream extends OutputStream {
+
+ private final List<OutputStream> listeners;
+
+ public ForwardingOutputStream(OutputStream... listeners) {
+ this.listeners = Arrays.asList(listeners);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ for (OutputStream out : listeners) {
+ out.write(b);
+ }
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ for (OutputStream out : listeners) {
+ out.write(b);
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ for (OutputStream out : listeners) {
+ out.write(b, off, len);
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ for (OutputStream out : listeners) {
+ out.flush();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ for (OutputStream out : listeners) {
+ out.close();
+ }
+ }
+}