CompatDxTests.java revision 418d1ca139ea11316113beafbb3b3dd3fd5587a
1418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file 2418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// for details. All rights reserved. Use of this source code is governed by a 3418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// BSD-style license that can be found in the LICENSE file. 4418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpackage com.android.tools.r8.compatdx; 5418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 6418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport static org.junit.Assert.assertEquals; 7418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport static org.junit.Assert.assertNotEquals; 8418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport static org.junit.Assert.assertTrue; 9418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 10418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.ToolHelper; 11418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.errors.CompilationError; 12418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.maindexlist.MainDexListTests; 13418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.utils.FileUtils; 14418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.utils.StringUtils; 15418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.utils.StringUtils.BraceType; 16418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.io.IOException; 17418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.nio.file.Files; 18418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.nio.file.Path; 19418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.nio.file.Paths; 20418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.ArrayList; 21418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.Collections; 22418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.List; 23418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.Set; 24418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.stream.Collectors; 25418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.zip.ZipEntry; 26418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport java.util.zip.ZipFile; 27418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport org.junit.Rule; 28418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport org.junit.Test; 29418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport org.junit.rules.ExpectedException; 30418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport org.junit.rules.TemporaryFolder; 31418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 32418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpublic class CompatDxTests { 33418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private static final String EXAMPLE_JAR_FILE1 = "build/test/examples/arithmetic.jar"; 34418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private static final String EXAMPLE_JAR_FILE2 = "build/test/examples/barray.jar"; 35418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 36418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private static final String NO_LOCALS = "--no-locals"; 37418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private static final String NO_POSITIONS = "--positions=none"; 38418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private static final String MULTIDEX = "--multi-dex"; 39418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private static final String NUM_THREADS_5 = "--num-threads=5"; 40418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 41418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Rule 42418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public ExpectedException thrown = ExpectedException.none(); 43418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 44418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Rule 45418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public TemporaryFolder temp = ToolHelper.getTemporaryFolderForTest(); 46418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 47418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 48418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void noFilesTest() throws IOException { 49418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer("--no-files"); 50418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 51418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 52418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 53418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void noOutputTest() throws IOException { 54418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexerWithoutOutput(NO_POSITIONS, NO_LOCALS, MULTIDEX, EXAMPLE_JAR_FILE1); 55418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 56418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 57418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 58418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void singleJarInputFile() throws IOException { 59418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(NO_POSITIONS, NO_LOCALS, MULTIDEX, EXAMPLE_JAR_FILE1); 60418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 61418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 62418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 63418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void multipleJarInputFiles() throws IOException { 64418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(NO_POSITIONS, NO_LOCALS, MULTIDEX, EXAMPLE_JAR_FILE1, EXAMPLE_JAR_FILE2); 65418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 66418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 67418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 68418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void outputZipFile() throws IOException { 69418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexerWithOutput("foo.dex.zip", NO_POSITIONS, NO_LOCALS, MULTIDEX, EXAMPLE_JAR_FILE1); 70418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 71418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 72418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 73418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void useMultipleThreads() throws IOException { 74418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(NUM_THREADS_5, NO_POSITIONS, NO_LOCALS, EXAMPLE_JAR_FILE1); 75418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 76418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 77418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 78418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void withPositions() throws IOException { 79418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(NO_LOCALS, MULTIDEX, EXAMPLE_JAR_FILE1); 80418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 81418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 82418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 83418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void withLocals() throws IOException { 84418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(NO_POSITIONS, MULTIDEX, EXAMPLE_JAR_FILE1); 85418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 86418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 87418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 88418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void withoutMultidex() throws IOException { 89418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(NO_POSITIONS, NO_LOCALS, EXAMPLE_JAR_FILE1); 90418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 91418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 92418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 93418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void writeToNamedDexFile() throws IOException { 94418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexerWithOutput("named-output.dex", EXAMPLE_JAR_FILE1); 95418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 96418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 97418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Test 98418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void singleDexProgramIsTooLarge() throws IOException { 99418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager thrown.expect(CompilationError.class); 100418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexer(MainDexListTests.getTwoLargeClassesAppPath().toString()); 101418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 102418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 103418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private void runDexer(String... args) throws IOException { 104418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexerWithOutput("", args); 105418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 106418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 107418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private void runDexerWithoutOutput(String... args) throws IOException { 108418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager runDexerWithOutput(null, args); 109418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 110418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 111418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private void runDexerWithOutput(String out, String... args) throws IOException { 112418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Path d8Out = null; 113418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Path dxOut = null; 114418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (out != null) { 115418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager d8Out = temp.newFolder("d8-out").toPath().resolve(out); 116418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager dxOut = temp.newFolder("dx-out").toPath().resolve(out); 117418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assertNotEquals(d8Out, dxOut); 118418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 119418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 120418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager List<String> d8Args = new ArrayList<>(args.length + 2); 121418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager d8Args.add("--dex"); 122418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (d8Out != null) { 123418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager d8Args.add("--output=" + d8Out); 124418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 125418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Collections.addAll(d8Args, args); 126418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager System.out.println("running: d8 " + StringUtils.join(d8Args, " ")); 127418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager CompatDx.main(d8Args.toArray(new String[d8Args.size()])); 128418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 129418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager List<String> dxArgs = new ArrayList<>(args.length + 2); 130418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (dxOut != null) { 131418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager dxArgs.add("--output=" + dxOut); 132418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 133418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Collections.addAll(dxArgs, args); 134418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager System.out.println("running: dx " + StringUtils.join(dxArgs, " ")); 135418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager ToolHelper.runDX(dxArgs.toArray(new String[dxArgs.size()])); 136418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 137418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (out == null) { 138418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // Can't check output if explicitly not writing any. 139418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return; 140418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 141418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 142418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager List<Path> d8Files = Files.list(Files.isDirectory(d8Out) ? d8Out : d8Out.getParent()) 143418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager .sorted().collect(Collectors.toList()); 144418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager List<Path> dxFiles = Files.list(Files.isDirectory(dxOut) ? dxOut : dxOut.getParent()) 145418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager .sorted().collect(Collectors.toList()); 146418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assertEquals("Out file names differ", 147418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager StringUtils.join(dxFiles, "\n", BraceType.NONE, (file) -> 148418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager file.getFileName().toString()), 149418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager StringUtils.join(d8Files, "\n", BraceType.NONE, (file) -> 150418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager file.getFileName().toString())); 151418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 152418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager for (int i = 0; i < d8Files.size(); i++) { 153418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (FileUtils.isArchive(d8Files.get(i))) { 154418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager compareArchiveFiles(d8Files.get(i), dxFiles.get(i)); 155418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 156418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 157418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 158418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 159418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager private void compareArchiveFiles(Path d8File, Path dxFile) throws IOException { 160418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager ZipFile d8Zip = new ZipFile(d8File.toFile()); 161418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager ZipFile dxZip = new ZipFile(dxFile.toFile()); 162418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager // TODO(zerny): This should test resource containment too once supported. 163418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Set<String> d8Content = d8Zip.stream().map(ZipEntry::getName).collect(Collectors.toSet()); 164418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager Set<String> dxContent = dxZip.stream().map(ZipEntry::getName).collect(Collectors.toSet()); 165418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager for (String entry : d8Content) { 166418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assertTrue("Expected dx output to contain " + entry, dxContent.contains(entry)); 167418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 168418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager for (String entry : dxContent) { 169418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (FileUtils.isDexFile(Paths.get(entry))) { 170418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assertTrue("Expected d8 output to contain " + entry, d8Content.contains(entry)); 171418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 172418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 173418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 174418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager} 175