blob: 553ff0e94b97c6ef4507c6e92f776c81d7280df0 [file] [log] [blame]
// Copyright (c) 2017, 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.hamcrest.core.StringContains.containsString;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.android.tools.r8.utils.ZipUtils.OnEntryHandler;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class R8EntryPointTests extends TestBase {
private static final String MAPPING = "mapping.txt";
private static final String SEEDS = "seeds.txt";
private static final Path INPUT_JAR =
Paths.get(ToolHelper.EXAMPLES_BUILD_DIR, "minification" + FileUtils.JAR_EXTENSION);
private static final Path PROGUARD_FLAGS =
Paths.get(ToolHelper.EXAMPLES_DIR, "minification", "keep-rules.txt");
private Path testFlags;
@Before
public void setup() throws IOException {
testFlags = temp.newFile("local.flags").toPath();
FileUtils.writeTextFile(testFlags, ImmutableList.of(
"-printseeds " + SEEDS,
"-printmapping " + MAPPING));
}
@Test
public void testRun1Dir() throws Exception {
Path out = temp.newFolder("outdex").toPath();
R8.run(getCommand(out));
Assert.assertTrue(Files.isRegularFile(out.resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testRun1Zip() throws Exception {
Path out = temp.newFolder("outdex").toPath().resolve("dex.zip");
R8.run(getCommand(out));
Assert.assertTrue(Files.isRegularFile(out));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testRun2Dir() throws Exception {
Path out = temp.newFolder("outdex").toPath();
ExecutorService executor = Executors.newWorkStealingPool(2);
try {
R8.run(getCommand(out), executor);
} finally {
executor.shutdown();
}
Assert.assertTrue(Files.isRegularFile(out.resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testRun2Zip() throws Exception {
Path out = temp.newFolder("outdex").toPath().resolve("dex.zip");
ExecutorService executor = Executors.newWorkStealingPool(2);
try {
R8.run(getCommand(out), executor);
} finally {
executor.shutdown();
}
Assert.assertTrue(Files.isRegularFile(out));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testMainDir() throws IOException, InterruptedException {
Path out = temp.newFolder("outdex").toPath();
ProcessResult r8 = ToolHelper.forkR8(Paths.get("."),
"--lib", ToolHelper.getDefaultAndroidJar().toString(),
"--output", out.toString(),
"--pg-conf", PROGUARD_FLAGS.toString(),
"--pg-conf", testFlags.toString(),
INPUT_JAR.toString());
Assert.assertEquals(0, r8.exitCode);
Assert.assertTrue(Files.isRegularFile(out.resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testMainRelativeDir() throws IOException, InterruptedException {
temp.newFolder("outdex");
Path out = Paths.get("outdex");
Path workingDir = temp.getRoot().toPath();
ProcessResult r8 = ToolHelper.forkR8(workingDir,
"--lib", ToolHelper.getDefaultAndroidJar().toAbsolutePath().toString(),
"--output", out.toString(),
"--pg-conf", PROGUARD_FLAGS.toAbsolutePath().toString(),
"--pg-conf", testFlags.toAbsolutePath().toString(),
INPUT_JAR.toAbsolutePath().toString());
Assert.assertEquals(0, r8.exitCode);
Assert.assertTrue(
Files.isRegularFile(workingDir.resolve(out).resolve(ToolHelper.DEFAULT_DEX_FILENAME)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testMainZip() throws IOException, InterruptedException {
Path out = temp.newFolder("outdex").toPath().resolve("dex.zip");
ProcessResult r8 = ToolHelper.forkR8(Paths.get("."),
"--lib", ToolHelper.getDefaultAndroidJar().toString(),
"--output", out.toString(),
"--pg-conf", PROGUARD_FLAGS.toString(),
"--pg-conf", testFlags.toString(),
INPUT_JAR.toString());
Assert.assertEquals(0, r8.exitCode);
Assert.assertTrue(Files.isRegularFile(out));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(MAPPING)));
Assert.assertTrue(Files.isRegularFile(testFlags.getParent().resolve(SEEDS)));
}
@Test
public void testSpecifyClassfile() throws IOException, InterruptedException {
Path out = temp.newFile("classfile.zip").toPath();
ProcessResult r8 =
ToolHelper.forkR8(
Paths.get("."),
"--lib",
ToolHelper.getJava8RuntimeJar().toString(),
"--classfile",
"--output",
out.toString(),
"--pg-conf",
PROGUARD_FLAGS.toString(),
"--pg-conf",
testFlags.toString(),
INPUT_JAR.toString());
Assert.assertEquals(0, r8.exitCode);
}
@Test
public void testSpecifyDex() throws IOException, InterruptedException {
Path out = temp.newFile("dex.zip").toPath();
ProcessResult r8 =
ToolHelper.forkR8(
Paths.get("."),
"--lib",
ToolHelper.getDefaultAndroidJar().toString(),
"--dex",
"--output",
out.toString(),
"--pg-conf",
PROGUARD_FLAGS.toString(),
"--pg-conf",
testFlags.toString(),
INPUT_JAR.toString());
Assert.assertEquals(0, r8.exitCode);
}
@Test
public void testDumpInputs() throws IOException {
Path out = temp.newFile("dex.zip").toPath();
Path dump = temp.newFile("dump.zip").toPath();
ProcessResult r8 =
ToolHelper.forkR8WithJavaOptions(
Paths.get("."),
ImmutableList.of("-Dcom.android.tools.r8.dumpinputtofile=" + dump.toString()),
"--lib",
ToolHelper.getDefaultAndroidJar().toString(),
"--dex",
"--output",
out.toString(),
"--pg-conf",
PROGUARD_FLAGS.toString(),
"--pg-conf",
testFlags.toString(),
INPUT_JAR.toString());
List<ZipEntry> entries = new ArrayList<>();
ZipUtils.iter(
dump.toString(),
new OnEntryHandler() {
@Override
public void onEntry(ZipEntry entry, InputStream input) throws IOException {
entries.add(entry);
}
});
Assert.assertTrue(hasEntry(entries, "program.jar"));
Assert.assertTrue(hasEntry(entries, "library.jar"));
Assert.assertTrue(hasEntry(entries, "classpath.jar"));
Assert.assertTrue(hasEntry(entries, "proguard.config"));
Assert.assertTrue(hasEntry(entries, "r8-version"));
// When dumping the inputs we throw an error in the program to exit early.
Assert.assertNotEquals(0, r8.exitCode);
}
private boolean hasEntry(Collection<ZipEntry> entries, String name) {
for (ZipEntry entry : entries) {
if (entry.getName().equals(name)) {
return true;
}
}
return false;
}
@Test
public void testSpecifyDexAndClassfileNotAllowed() throws IOException, InterruptedException {
Path out = temp.newFile("dex.zip").toPath();
ProcessResult r8 =
ToolHelper.forkR8(
Paths.get("."),
"--lib",
ToolHelper.getDefaultAndroidJar().toString(),
"--dex",
"--classfile",
"--output",
out.toString(),
"--pg-conf",
PROGUARD_FLAGS.toString(),
"--pg-conf",
testFlags.toString(),
INPUT_JAR.toString());
Assert.assertEquals(1, r8.exitCode);
assertThat(
r8.stderr, containsString("Cannot compile in both --dex and --classfile output mode"));
}
private R8Command getCommand(Path out) throws IOException, CompilationFailedException {
return R8Command.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar())
.addProgramFiles(INPUT_JAR)
.setOutput(out, OutputMode.DexIndexed)
.addProguardConfigurationFiles(PROGUARD_FLAGS, testFlags)
.build();
}
}