blob: 211121c84601c1c538e42b08ba3546e20b8140c8 [file] [log] [blame]
// Copyright (c) 2023, 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.retrace.partition;
import static com.android.tools.r8.naming.retrace.StackTrace.isSame;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.ProguardMapConsumer;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessagesImpl;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.naming.ProguardMapPartitionConsumer;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
import com.android.tools.r8.retrace.PartitionMappingSupplier;
import com.android.tools.r8.retrace.partition.testclasses.R8ZipContainerMappingFileTestClasses;
import com.android.tools.r8.retrace.partition.testclasses.R8ZipContainerMappingFileTestClasses.Main;
import com.android.tools.r8.utils.ZipUtils.ZipBuilder;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class R8ZipContainerMappingFileTest extends TestBase {
private static final String SOURCE_FILE = "R8ZipContainerMappingFileTestClasses.java";
private final StackTrace EXPECTED =
StackTrace.builder()
.add(
StackTraceLine.builder()
.setClassName(typeName(R8ZipContainerMappingFileTestClasses.Thrower.class))
.setMethodName("throwError")
.setFileName(SOURCE_FILE)
.setLineNumber(13)
.build())
.add(
StackTraceLine.builder()
.setClassName(typeName(R8ZipContainerMappingFileTestClasses.Main.class))
.setMethodName("main")
.setFileName(SOURCE_FILE)
.setLineNumber(21)
.build())
.build();
@Parameter() public TestParameters parameters;
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
@Test
public void testRuntime() throws Exception {
testForRuntime(parameters)
.addInnerClasses(R8ZipContainerMappingFileTestClasses.class)
.run(parameters.getRuntime(), Main.class)
.assertFailureWithErrorThatThrows(RuntimeException.class)
.inspectStackTrace(
stackTrace -> {
assertThat(stackTrace, isSame(EXPECTED));
});
}
@Test
public void testR8() throws Exception {
Path pgMapFile = temp.newFile("mapping.zip").toPath();
DiagnosticsHandler diagnosticsHandler = new TestDiagnosticMessagesImpl();
ProguardMapConsumer partitionZipConsumer =
createPartitionZipConsumer(pgMapFile, diagnosticsHandler);
StackTrace originalStackTrace =
testForR8(parameters.getBackend())
.addInnerClasses(R8ZipContainerMappingFileTestClasses.class)
.setMinApi(parameters)
.addKeepMainRule(Main.class)
.addKeepAttributeSourceFile()
.addKeepAttributeLineNumberTable()
.addOptionsModification(options -> options.proguardMapConsumer = partitionZipConsumer)
.run(parameters.getRuntime(), Main.class)
.assertFailureWithErrorThatThrows(RuntimeException.class)
.getOriginalStackTrace();
assertTrue(Files.exists(pgMapFile));
assertThat(
originalStackTrace.retrace(createMappingSupplierFromPartitionZip(pgMapFile)),
isSame(EXPECTED));
}
private ProguardMapConsumer createPartitionZipConsumer(
Path pgMapFile, DiagnosticsHandler diagnosticsHandler) throws IOException {
ZipBuilder zipBuilder = ZipBuilder.builder(pgMapFile);
return ProguardMapPartitionConsumer.builder()
.setMappingPartitionConsumer(
mappingPartition -> {
try {
zipBuilder.addBytes(mappingPartition.getKey(), mappingPartition.getPayload());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.setMetadataConsumer(
metadata -> {
try {
zipBuilder.addBytes("METADATA", metadata.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.setFinishedConsumer(
() -> {
try {
zipBuilder.build();
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.setDiagnosticsHandler(diagnosticsHandler)
.build();
}
private PartitionMappingSupplier createMappingSupplierFromPartitionZip(Path pgMapFile)
throws IOException {
ZipFile zipFile = new ZipFile(pgMapFile.toFile());
byte[] metadata = ByteStreams.toByteArray(zipFile.getInputStream(zipFile.getEntry("METADATA")));
return PartitionMappingSupplier.builder()
.setMetadata(metadata)
.setMappingPartitionFromKeySupplier(
key -> {
try {
// TODO(b/274735214): The key should exist.
ZipEntry entry = zipFile.getEntry(key);
return entry == null
? null
: ByteStreams.toByteArray(zipFile.getInputStream(entry));
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.build();
}
}