blob: 129de09418a7221cd4653a30eed83287a9649a2a [file]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.debug.DebugTestConfig;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.internal.StringUtils;
import com.android.tools.r8.utils.internal.ThrowingConsumer;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Path;
import java.util.function.Predicate;
import org.hamcrest.Matcher;
public class SingleTestRunResult extends TestRunResult<SingleTestRunResult> {
private final TestRuntime runtime;
private final ProcessResult result;
public SingleTestRunResult(
AndroidApp app, TestRuntime runtime, ProcessResult result, TestState state) {
this(app, runtime, result, null, state);
}
public SingleTestRunResult(
AndroidApp app,
TestRuntime runtime,
ProcessResult result,
String proguardMap,
TestState state) {
super(app, proguardMap, state);
this.runtime = runtime;
this.result = result;
}
@Override
protected SingleTestRunResult self() {
return this;
}
@Override
public SingleTestRunResult asSingleRuntimeResult() {
return self();
}
public TestRuntime runtime() {
return runtime;
}
public ProcessResult getResult() {
return result;
}
public String getStdOut() {
return result.stdout;
}
public String getStdErr() {
return result.stderr;
}
public int getExitCode() {
return result.exitCode;
}
public StackTrace getStackTrace() {
StackTrace original = getOriginalStackTrace();
return proguardMap == null ? original : original.retraceAllowExperimentalMapping(proguardMap);
}
public StackTrace getOriginalStackTrace() {
if (runtime.isDex()) {
return StackTrace.extractFromArt(getStdErr(), runtime.asDex().getVm());
} else {
return StackTrace.extractFromJvm(getStdErr());
}
}
@Override
public <E extends Throwable> SingleTestRunResult inspectStdOut(
ThrowingConsumer<String, E> consumer) throws E {
consumer.accept(getStdOut());
return self();
}
@Override
public <E extends Throwable> SingleTestRunResult inspectStackTrace(
ThrowingConsumer<StackTrace, E> consumer) throws E {
consumer.accept(getStackTrace());
return self();
}
@Override
public <E extends Throwable> SingleTestRunResult inspectOriginalStackTrace(
ThrowingConsumer<StackTrace, E> consumer) throws E {
consumer.accept(getOriginalStackTrace());
return self();
}
@Override
public SingleTestRunResult assertSuccess() {
assertEquals(errorMessage("Expected run to succeed."), 0, result.exitCode);
return self();
}
@Override
public SingleTestRunResult assertStdoutMatches(Matcher<String> matcher) {
assertThat(errorMessage("Run stdout incorrect.", matcher.toString()), result.stdout, matcher);
return self();
}
@Override
public SingleTestRunResult assertStdoutLinesMatchesUnordered(Iterable<Matcher<String>> lines) {
assertThat(
StringUtils.splitLines(result.stdout), UnorderedCollectionMatcher.matchesOneToOne(lines));
return self();
}
@Override
public SingleTestRunResult assertFailure() {
assertNotEquals(errorMessage("Expected run to fail."), 0, result.exitCode);
return self();
}
@Override
public SingleTestRunResult assertStderrMatches(Matcher<String> matcher) {
assertThat(errorMessage("Run stderr incorrect.", matcher.toString()), result.stderr, matcher);
return self();
}
@Override
void appendProcessResult(StringBuilder builder) {
builder.append("COMMAND: ").append(result.command).append('\n').append(result);
}
@Override
public SingleTestRunResult writeProcessResult(PrintStream ps) {
StringBuilder sb = new StringBuilder();
appendProcessResult(sb);
ps.println(sb.toString());
return self();
}
private boolean matchesDexVersion(Predicate<DexVm.Version> predicate) {
return runtime.isDex() && predicate.test(runtime.asDex().getVm().getVersion());
}
@Override
public <
S extends Throwable,
T extends Throwable,
U extends Throwable,
V extends Throwable,
W extends Throwable>
SingleTestRunResult applyIfDexRuntime(
Predicate<DexVm.Version> condition1,
ThrowingConsumer<? super SingleTestRunResult, S> thenConsumer1,
Predicate<DexVm.Version> condition2,
ThrowingConsumer<? super SingleTestRunResult, T> thenConsumer2,
Predicate<DexVm.Version> condition3,
ThrowingConsumer<? super SingleTestRunResult, U> thenConsumer3,
Predicate<DexVm.Version> condition4,
ThrowingConsumer<? super SingleTestRunResult, W> thenConsumer4,
ThrowingConsumer<? super SingleTestRunResult, V> elseConsumer)
throws S, T, U, V, W {
if (matchesDexVersion(condition1)) {
thenConsumer1.accept(this);
} else if (matchesDexVersion(condition2)) {
thenConsumer2.accept(this);
} else if (matchesDexVersion(condition3)) {
thenConsumer3.accept(this);
} else if (matchesDexVersion(condition4)) {
thenConsumer4.accept(this);
} else {
elseConsumer.accept(this);
}
return self();
}
@Override
public <E extends Throwable> SingleTestRunResult debugger(
ThrowingConsumer<DebugTestConfig, E> consumer) throws E, IOException {
Path out = getState().getNewTempFolder().resolve("out.zip");
app.writeToZipForTesting(out, runtime.isCf() ? OutputMode.ClassFile : OutputMode.DexIndexed);
DebugTestConfig config = DebugTestConfig.create(runtime, out);
consumer.accept(config);
return self();
}
}