diff options
Diffstat (limited to 'jack-tests/src/com/android/jack')
21 files changed, 886 insertions, 272 deletions
diff --git a/jack-tests/src/com/android/jack/test/category/ExtraTests.java b/jack-tests/src/com/android/jack/test/category/ExtraTests.java new file mode 100644 index 00000000..c1e5c951 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/category/ExtraTests.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.category; + +/** + * Tests that are not critical, so that we do not want to run them each time we submit a CL. + */ +public interface ExtraTests extends NonPreSubmitTests { + +} diff --git a/jack-tests/src/com/android/jack/test/category/KnownBugs.java b/jack-tests/src/com/android/jack/test/category/KnownBugs.java new file mode 100644 index 00000000..86c6910e --- /dev/null +++ b/jack-tests/src/com/android/jack/test/category/KnownBugs.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.category; + +/** + * Tests that show a known Jack bug. + */ +public interface KnownBugs extends NonPreSubmitTests { + +} diff --git a/jack-tests/src/com/android/jack/test/category/NonPreSubmitTests.java b/jack-tests/src/com/android/jack/test/category/NonPreSubmitTests.java new file mode 100644 index 00000000..70cf3cb4 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/category/NonPreSubmitTests.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.category; + +/** + * Tests that we do not need to run before submitting a CL. + */ +public interface NonPreSubmitTests { + +} diff --git a/jack-tests/src/com/android/jack/test/category/RedundantTests.java b/jack-tests/src/com/android/jack/test/category/RedundantTests.java new file mode 100644 index 00000000..42fac240 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/category/RedundantTests.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.category; + +/** + * Tests that are already covered by another test. They may be interesting on their own, but do not + * need to be included in a pre-submit test suite. + */ +public interface RedundantTests extends NonPreSubmitTests { + +} diff --git a/jack-tests/src/com/android/jack/test/category/SlowTests.java b/jack-tests/src/com/android/jack/test/category/SlowTests.java new file mode 100644 index 00000000..0a7fdbd3 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/category/SlowTests.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.category; + +/** + * Tests that are time-consuming, so that we do not want to run them each time we submit a CL. + */ +public interface SlowTests extends NonPreSubmitTests { + +} diff --git a/jack-tests/src/com/android/jack/test/comparator/ComparatorSeeds.java b/jack-tests/src/com/android/jack/test/comparator/ComparatorSeeds.java new file mode 100644 index 00000000..47dbe9d3 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/comparator/ComparatorSeeds.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.comparator; + +import com.android.jack.DifferenceFoundException; +import com.android.jack.shrob.SeedsComparator; + +import java.io.File; +import java.io.IOException; + +/** + * This {@link Comparator} is used to compare shrob seeds. + */ +public class ComparatorSeeds extends ComparatorFile { + + public ComparatorSeeds(File candidate, File reference) { + super(candidate, reference); + } + + @Override + public void compare() throws DifferenceFoundException, ComparatorException { + try { + SeedsComparator.compare(reference, candidate); + } catch (IOException e) { + throw new ComparatorException(e); + } + } + +} diff --git a/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java b/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java index f3858bf2..d00d3673 100644 --- a/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java +++ b/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java @@ -17,6 +17,8 @@ package com.android.jack.test.helper; +import com.android.jack.test.toolchain.AndroidToolchain; + import java.io.File; import javax.annotation.Nonnull; @@ -26,8 +28,74 @@ import javax.annotation.Nonnull; */ public class CheckDexStructureTestHelper extends SourceToDexComparisonTestHelper { - public CheckDexStructureTestHelper(@Nonnull File fileOrSourceList) throws Exception { - super(fileOrSourceList); + public CheckDexStructureTestHelper(@Nonnull File... filesOrSourceList) throws Exception { + super(filesOrSourceList); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setCandidateTestTools( + @Nonnull AndroidToolchain candidateTestTools) { + return (CheckDexStructureTestHelper) super.setCandidateTestTools(candidateTestTools); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setReferenceTestTools( + @Nonnull AndroidToolchain referenceTestTools) { + return (CheckDexStructureTestHelper) super.setReferenceTestTools(referenceTestTools); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setCandidateClasspath(@Nonnull File[] classpath) { + return (CheckDexStructureTestHelper) super.setCandidateClasspath(classpath); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setReferenceClasspath(@Nonnull File[] classpath) { + return (CheckDexStructureTestHelper) super.setReferenceClasspath(classpath); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setWithDebugInfo(boolean withDebugInfo) { + return (CheckDexStructureTestHelper) super.setWithDebugInfo(withDebugInfo); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setJarjarRulesFile(@Nonnull File jarjarRulesFile) { + return (CheckDexStructureTestHelper) super.setJarjarRulesFile(jarjarRulesFile); + } + + @Override + @Nonnull + public CheckDexStructureTestHelper setProguardFlags(@Nonnull File... proguardFlags) { + return (CheckDexStructureTestHelper) super.setProguardFlags(proguardFlags); + } + + @Override + @Nonnull + protected void executeCandidateToolchain() throws Exception { + if (withDebugInfos) { + getCandidateToolchain().disableDxOptimizations(); + } else { + getCandidateToolchain().enableDxOptimizations(); + } + super.executeCandidateToolchain(); + } + + @Override + @Nonnull + protected void executeReferenceToolchain() throws Exception { + if (withDebugInfos) { + getReferenceToolchain().disableDxOptimizations(); + } else { + getReferenceToolchain().enableDxOptimizations(); + } + super.executeReferenceToolchain(); } public void compare() throws Exception { diff --git a/jack-tests/src/com/android/jack/test/helper/FileChecker.java b/jack-tests/src/com/android/jack/test/helper/FileChecker.java new file mode 100644 index 00000000..89494c4e --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/FileChecker.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jack.test.helper; + +import java.io.File; + +import javax.annotation.Nonnull; + +/** + * This interface declares a callback method for the caller of a helper to + * add specific checks on a file. + */ +public interface FileChecker { + + void check(@Nonnull File file) throws Exception; + +} diff --git a/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java b/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java index 4f5e1724..39a2740e 100644 --- a/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java +++ b/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java @@ -17,10 +17,12 @@ package com.android.jack.test.helper; import com.android.jack.backend.jayce.JayceFileImporter; +import com.android.jack.library.FileType; import com.android.jack.test.runner.DalvikRunnerHost; import com.android.jack.test.runner.RuntimeRunnerFactory; import com.android.jack.test.toolchain.AbstractTestTools; -import com.android.jack.test.toolchain.JackBasedToolchain; +import com.android.jack.test.toolchain.IToolchain; +import com.android.jack.test.toolchain.JackApiToolchain; import com.android.jack.test.toolchain.JillBasedToolchain; import junit.framework.Assert; @@ -28,13 +30,16 @@ import junit.framework.Assert; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; /** @@ -58,6 +63,10 @@ public class IncrementalTestHelper { private final Set<File> javaFiles = new HashSet<File>(); @Nonnull private final Map<String, Long> fileModificationDate = new HashMap<String, Long>(); + @Nonnull + private OutputStream out = System.out; + @Nonnull + private OutputStream err = System.err; public IncrementalTestHelper(@Nonnull File testingFolder) throws IOException { this.testingFolder = testingFolder; @@ -77,10 +86,18 @@ public class IncrementalTestHelper { jackFolder = new File(compilerStateFolder, "jackFiles"); } + public void setOut(OutputStream out) { + this.out = out; + } + + public void setErr(OutputStream err) { + this.err = err; + } + @Nonnull public File addJavaFile(@Nonnull String packageName, @Nonnull String fileName, @Nonnull String fileContent) throws IOException { - File file = AbstractTestTools.createJavaFile(sourceFolder, packageName, fileName, fileContent); + File file = AbstractTestTools.createFile(sourceFolder, packageName, fileName, fileContent); javaFiles.add(file); return file; } @@ -130,8 +147,9 @@ public class IncrementalTestHelper { Long previousDate = fileModificationDate.get(jackFile.getAbsolutePath()); if (previousDate == null || jackFile.lastModified() > previousDate.longValue()) { String jackFileName = jackFile.getAbsolutePath(); - String binaryTypeName = jackFileName.substring(0, jackFileName.indexOf(".jack")); - binaryTypeName = binaryTypeName.substring(jackFolder.getAbsolutePath().length() + 1); + String binaryTypeName = jackFileName.substring(0, jackFileName.indexOf(".jayce")); + binaryTypeName = binaryTypeName.substring((jackFolder.getAbsolutePath() + File.separatorChar + + FileType.JAYCE.getPrefix()).length() + 1); fqnOfRebuiltTypes.add(binaryTypeName.replace(File.separatorChar, '.')); } } @@ -140,13 +158,32 @@ public class IncrementalTestHelper { } public void incrementalBuildFromFolder() throws Exception { - JackBasedToolchain jackToolchain = - AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, JillBasedToolchain.class); + incrementalBuildFromFolder(null, Collections.<File>emptyList()); + } + + public void incrementalBuildFromFolder(@Nonnull File[] classpath) throws Exception { + incrementalBuildFromFolder(classpath, Collections.<File>emptyList()); + } + + public void incrementalBuildFromFolder(@CheckForNull File[] classpath, + @Nonnull List<File> imports) throws Exception { + + List<Class<? extends IToolchain>> excludeList = new ArrayList<Class<? extends IToolchain>>(1); + excludeList.add(JillBasedToolchain.class); + + JackApiToolchain jackToolchain = + AbstractTestTools.getCandidateToolchain(JackApiToolchain.class, excludeList); jackToolchain.setIncrementalFolder(getCompilerStateFolder()); + jackToolchain.addStaticLibs(imports.toArray(new File[imports.size()])); + + jackToolchain.setOutputStream(out); + jackToolchain.setErrorStream(err); - jackToolchain.srcToExe( - AbstractTestTools.getClasspathAsString(jackToolchain.getDefaultBootClasspath()), dexOutDir, - sourceFolder); + File[] bootclasspath = jackToolchain.getDefaultBootClasspath(); + + jackToolchain.srcToExe(classpath == null ? AbstractTestTools.getClasspathAsString(bootclasspath) + : AbstractTestTools.getClasspathsAsString(bootclasspath, classpath), dexOutDir, + /* zipFile = */ false, sourceFolder); Thread.sleep(1000); } @@ -162,8 +199,18 @@ public class IncrementalTestHelper { } @Nonnull + public File getDexFile() { + return dexFile; + } + + @Nonnull + public File getJackFolder() { + return jackFolder; + } + + @Nonnull public List<File> getJackFiles() { - return AbstractTestTools.getFiles(jackFolder, ".jack"); + return AbstractTestTools.getFiles(jackFolder, ".jayce"); } } diff --git a/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java b/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java index 29236999..2d1a8738 100644 --- a/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java +++ b/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java @@ -18,6 +18,7 @@ package com.android.jack.test.helper; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; +import com.google.common.io.Files; import com.android.jack.test.runner.RuntimeRunner; import com.android.jack.test.runtime.RuntimeTestInfo; @@ -45,14 +46,11 @@ import javax.annotation.Nonnull; public class RuntimeTestHelper { @Nonnull - private AndroidToolchain candidateTestTools; - @Nonnull - private AndroidToolchain referenceTestTools; - - @Nonnull private List<File> baseDirs = new ArrayList<File>(1); @Nonnull private List<String> jUnitClasses = new ArrayList<String>(1); + @Nonnull + private List<File> referenceExtraSources = new ArrayList<File>(0); @Nonnull private String srcDirName = "jack"; @@ -65,6 +63,11 @@ public class RuntimeTestHelper { private boolean withDebugInfos = false; + private SourceLevel level = SourceLevel.JAVA_6; + + @Nonnull + private List<FileChecker> testExeCheckers = new ArrayList<FileChecker>(0); + @CheckForNull private String jarjarRulesFileName; @CheckForNull @@ -73,11 +76,6 @@ public class RuntimeTestHelper { @Nonnull private String propertyFileName = "test.properties"; - { - candidateTestTools = AbstractTestTools.getCandidateToolchain(AndroidToolchain.class); - referenceTestTools = AbstractTestTools.getReferenceToolchain(AndroidToolchain.class); - } - public RuntimeTestHelper(@Nonnull RuntimeTestInfo... rtTestInfos) { for (RuntimeTestInfo info : rtTestInfos) { baseDirs.add(info.directory); @@ -117,8 +115,7 @@ public class RuntimeTestHelper { @Nonnull public RuntimeTestHelper setSourceLevel(@Nonnull SourceLevel level) { - candidateTestTools.setSourceLevel(level); - referenceTestTools.setSourceLevel(level); + this.level = level; return this; } @@ -140,7 +137,25 @@ public class RuntimeTestHelper { return this; } + @Nonnull + public RuntimeTestHelper addTestExeFileChecker(@Nonnull FileChecker checker) { + this.testExeCheckers.add(checker); + return this; + } + + @Nonnull + public RuntimeTestHelper addReferenceExtraSources (@Nonnull File... extraSrc) { + for (File file : extraSrc) { + referenceExtraSources.add(file); + } + return this; + } + public void compileAndRunTest() throws Exception { + compileAndRunTest(/* checkStructure = */ false); + } + + public void compileAndRunTest(boolean checkStructure) throws Exception { Properties testProperties = new Properties(); try { loadTestProperties(testProperties); @@ -148,8 +163,19 @@ public class RuntimeTestHelper { // No file, no pb } - candidateTestTools.setWithDebugInfos(withDebugInfos); - referenceTestTools.setWithDebugInfos(withDebugInfos); +// AndroidToolchain candidateTestTools = +// AbstractTestTools.getCandidateToolchain(AndroidToolchain.class); +// AndroidToolchain referenceTestTools = +// AbstractTestTools.getReferenceToolchain(AndroidToolchain.class); +// +// candidateTestTools.setSourceLevel(level); +// referenceTestTools.setSourceLevel(level); +// +// candidateTestTools.setWithDebugInfos(withDebugInfos); +// referenceTestTools.setWithDebugInfos(withDebugInfos); + + AndroidToolchain candidateTestTools = createCandidateToolchain(); + AndroidToolchain referenceTestTools = createReferenceToolchain(); File[] candidateBootClasspath = candidateTestTools.getDefaultBootClasspath(); File[] referenceBootClasspath = referenceTestTools.getDefaultBootClasspath(); @@ -165,27 +191,30 @@ public class RuntimeTestHelper { File libLibCandidate = null; if (getLibSrc().length != 0) { libLibRef = - AbstractTestTools.createTempFile("-lib-ref", referenceTestTools.getLibraryExtension()); + AbstractTestTools.createTempFile("lib-ref", referenceTestTools.getLibraryExtension()); File libBinaryRefDir = AbstractTestTools.createTempDir(); libBinaryRef = new File(libBinaryRefDir, referenceTestTools.getBinaryFileName()); - referenceTestTools.srcToLib(referenceBootClasspathAsString, libLibRef, /* zipFiles = */true, + referenceTestTools.srcToLib(referenceBootClasspathAsString, libLibRef, /* zipFiles = */ true, getLibSrc()); - referenceTestTools.libToDex(libLibRef, libBinaryRefDir); + referenceTestTools.libToExe(libLibRef, libBinaryRefDir, /* zipFile */ false); - libLibCandidate = AbstractTestTools.createTempFile("-lib-candidate", + libLibCandidate = AbstractTestTools.createTempFile("lib-candidate", candidateTestTools.getLibraryExtension()); candidateTestTools.srcToLib(candidateBootClasspathAsString, libLibCandidate, - /* zipFiles = */true, getLibSrc()); + /* zipFiles = */ true, getLibSrc()); } // Compile test src + candidateTestTools = createCandidateToolchain(); + String candidateClasspathAsString; String referenceClasspathAsString; + File[] candidateClassPath = candidateBootClasspath; if (getLibSrc().length != 0) { - File[] candidateClassPath = new File[candidateBootClasspath.length + 1]; + candidateClassPath = new File[candidateBootClasspath.length + 1]; System.arraycopy(candidateBootClasspath, 0, candidateClassPath, 0, candidateBootClasspath.length); - candidateClassPath[candidateClassPath.length - 1] = libLibRef; + candidateClassPath[candidateClassPath.length - 1] = libLibCandidate; candidateClasspathAsString = AbstractTestTools.getClasspathAsString(candidateClassPath); File[] referenceClasspath = new File[referenceBootClasspath.length + 1]; System.arraycopy(referenceBootClasspath, 0, referenceClasspath, 0, @@ -202,28 +231,53 @@ public class RuntimeTestHelper { File testBinaryDir = AbstractTestTools.createTempDir(); File testBinary = new File(testBinaryDir, candidateTestTools.getBinaryFileName()); - if (jarjarRules != null) { - candidateTestTools.setJarjarRules(jarjarRules); + + if (checkStructure) { + CheckDexStructureTestHelper helper = new CheckDexStructureTestHelper(getSrcDir()); + helper.setCandidateClasspath(candidateClassPath); + helper.setCandidateTestTools(candidateTestTools); + if (jarjarRules != null) { + helper.setJarjarRulesFile(jarjarRules); + } + helper.setProguardFlags(proguargFlags.toArray(new File[proguargFlags.size()])); + helper.compare(); + Files.copy(helper.getCandidateDex(), + new File(testBinaryDir, helper.getCandidateDex().getName())); + } else { + if (jarjarRules != null) { + candidateTestTools.setJarjarRules(jarjarRules); + } + candidateTestTools.addProguardFlags(proguargFlags.toArray(new File [proguargFlags.size()])); + candidateTestTools.srcToExe(candidateClasspathAsString, testBinaryDir, /* zipFile = */ false, + getSrcDir()); + } + + for (FileChecker checker : testExeCheckers) { + checker.check(testBinary); } - candidateTestTools.addProguardFlags(proguargFlags.toArray(new File [proguargFlags.size()])); - candidateTestTools.srcToExe(candidateClasspathAsString, testBinaryDir, getSrcDir()); + referenceTestTools = createReferenceToolchain(); File testLib = AbstractTestTools.createTempFile("testRef", referenceTestTools.getLibraryExtension()); - referenceTestTools.srcToLib(referenceClasspathAsString, testLib, /* zipFiles = */true, + referenceTestTools.srcToLib(referenceClasspathAsString, testLib, /* zipFiles = */ true, getSrcDir()); // Compile link src + candidateTestTools = createCandidateToolchain(); + File linkBinary = null; if (getLinkSrc().length != 0) { File linkBinaryDir = AbstractTestTools.createTempDir(); linkBinary = new File(linkBinaryDir, candidateTestTools.getBinaryFileName()); candidateTestTools.setJarjarRules(jarjarRules); candidateTestTools.addProguardFlags(proguargFlags.toArray(new File [proguargFlags.size()])); - candidateTestTools.srcToExe(candidateBootClasspathAsString, linkBinaryDir, getLinkSrc()); + candidateTestTools.srcToExe(candidateBootClasspathAsString, linkBinaryDir, + /* zipFile = */ false, getLinkSrc()); } // Compile ref part src + referenceTestTools = createReferenceToolchain(); + List<File> referenceClasspath = new ArrayList<File>(); for (File f : referenceBootClasspath) { referenceClasspath.add(f); @@ -234,12 +288,29 @@ public class RuntimeTestHelper { if (testLib != null) { referenceClasspath.add(testLib); } + referenceClasspathAsString = AbstractTestTools.getClasspathAsString( referenceClasspath.toArray(new File[referenceClasspath.size()])); + + File [] refSources = getRefSrcDir(); +// File [] sources = new File [referenceExtraSources.size() + refSources.length]; + List<File> sources = new ArrayList<File>(referenceExtraSources.size() + refSources.length); + sources = Lists.addAll(sources, refSources); + sources = Lists.addAll(sources, referenceExtraSources); + File refPartBinaryDir = AbstractTestTools.createTempDir(); +// File [] sources = new File [referenceExtraSources.size() + 1]; +// sources[0] = getRefSrcDir()[0]; +// for (int i = 1; i < sources.length; i++) { +// sources[i] = referenceExtraSources.get(i - 1); +// } File refPartBinary = new File(refPartBinaryDir, referenceTestTools.getBinaryFileName()); - referenceTestTools.srcToExe(referenceClasspathAsString, refPartBinaryDir, getRefSrcDir()); + referenceTestTools.srcToExe( + referenceClasspathAsString, + refPartBinaryDir, + /* zipFile = */ false, + sources.toArray(new File[sources.size()])); List<File> rtClasspath = new ArrayList<File>(); rtClasspath.add(new File(AbstractTestTools.getJackRootDir(), @@ -264,13 +335,32 @@ public class RuntimeTestHelper { rtClasspath.toArray(new File[rtClasspath.size()])); } + @Nonnull + private AndroidToolchain createCandidateToolchain() { + AndroidToolchain candidateTestTools = + AbstractTestTools.getCandidateToolchain(AndroidToolchain.class); + candidateTestTools.setSourceLevel(level); + candidateTestTools.setWithDebugInfos(withDebugInfos); + return candidateTestTools; + } + + @Nonnull + private AndroidToolchain createReferenceToolchain() { + AndroidToolchain referenceTestTools = + AbstractTestTools.getReferenceToolchain(AndroidToolchain.class); + referenceTestTools.setSourceLevel(level); + referenceTestTools.setWithDebugInfos(withDebugInfos); + return referenceTestTools; + } + private static void runOnRuntimeEnvironments(@Nonnull List<String> jUnitClasses, @Nonnull Properties testProperties, @Nonnull File... classpathFiles) throws Exception { List<RuntimeRunner> runnerList = AbstractTestTools.listRuntimeTestRunners(testProperties); + String[] names = Lists.add(jUnitClasses, 0, AbstractTestTools.JUNIT_RUNNER_NAME).toArray( + new String[jUnitClasses.size()]); for (RuntimeRunner runner : runnerList) { Assert.assertEquals(0, runner.run( - getRuntimeArgs(runner.getClass().getSimpleName(), testProperties), Lists.add(jUnitClasses, - 0, AbstractTestTools.JUNIT_RUNNER_NAME).toArray(new String[jUnitClasses.size() + 1]), + getRuntimeArgs(runner.getClass().getSimpleName(), testProperties), names, classpathFiles)); } } diff --git a/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java b/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java index 72d9108a..87db1bea 100644 --- a/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java +++ b/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java @@ -47,7 +47,7 @@ public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper private File[] referenceClasspath; @Nonnull - private File fileOrSourceList; + private File[] filesOrSourceList; @CheckForNull private File jarjarRulesFile = null; @@ -61,9 +61,9 @@ public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper protected boolean withDebugInfos = false; - public SourceToDexComparisonTestHelper(@Nonnull File fileOrSourceList) throws Exception { + public SourceToDexComparisonTestHelper(@Nonnull File... filesOrSourceList) throws Exception { - this.fileOrSourceList = fileOrSourceList; + this.filesOrSourceList = filesOrSourceList; candidateTestTools = getCandidateToolchain(); referenceTestTools = getReferenceToolchain(); @@ -120,6 +120,22 @@ public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper return this; } + public File getCandidateDex() { + return candidateDex; + } + + public File getCandidateDexDir() { + return candidateDexDir; + } + + public File getReferenceDex() { + return refDex; + } + + public File getReferenceDexDir() { + return refDexDir; + } + @Nonnull public Comparator createDexFileComparator() { ComparatorDex comparator = new ComparatorDex(candidateDex, refDex); @@ -138,7 +154,7 @@ public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper } @Nonnull - public SourceToDexComparisonTestHelper setProguardFlags(@Nonnull File[] proguardFlags) { + public SourceToDexComparisonTestHelper setProguardFlags(@Nonnull File... proguardFlags) { this.proguardFlagFiles = proguardFlags; return this; } @@ -149,9 +165,10 @@ public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper if (jarjarRulesFile != null) { candidateTestTools.setJarjarRules(jarjarRulesFile); } + candidateTestTools.setWithDebugInfos(withDebugInfos); candidateTestTools.addProguardFlags(proguardFlagFiles).srcToExe( AbstractTestTools.getClasspathAsString(candidateClasspath), candidateDexDir, - fileOrSourceList); + /* zipFile = */ false, filesOrSourceList); } @Override @@ -160,7 +177,9 @@ public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper if (jarjarRulesFile != null) { referenceTestTools.setJarjarRules(jarjarRulesFile); } + referenceTestTools.setWithDebugInfos(withDebugInfos); referenceTestTools.addProguardFlags(proguardFlagFiles).srcToExe( - AbstractTestTools.getClasspathAsString(referenceClasspath), refDexDir, fileOrSourceList); + AbstractTestTools.getClasspathAsString(referenceClasspath), refDexDir, + /* zipFile = */ false, filesOrSourceList); } } diff --git a/jack-tests/src/com/android/jack/test/runtime/RuntimeTest.java b/jack-tests/src/com/android/jack/test/runtime/RuntimeTest.java index 3fdb14ae..d1d20768 100644 --- a/jack-tests/src/com/android/jack/test/runtime/RuntimeTest.java +++ b/jack-tests/src/com/android/jack/test/runtime/RuntimeTest.java @@ -19,6 +19,7 @@ package com.android.jack.test.runtime; import java.util.ArrayList; import java.util.List; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; /** @@ -27,15 +28,15 @@ import javax.annotation.Nonnull; */ public abstract class RuntimeTest { - @Nonnull - protected List<RuntimeTestInfo> rtTestInfos = new ArrayList<RuntimeTestInfo>(); - - protected RuntimeTest() { - fillRtTestInfos(); - } + @CheckForNull + protected List<RuntimeTestInfo> rtTestInfos = null; @Nonnull public final List<RuntimeTestInfo> getRuntimeTestInfos() { + if (rtTestInfos == null) { + rtTestInfos = new ArrayList<RuntimeTestInfo>(); + fillRtTestInfos(); + } return rtTestInfos; } diff --git a/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java b/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java index ed0f6b07..448927a5 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java +++ b/jack-tests/src/com/android/jack/test/toolchain/AbstractTestTools.java @@ -50,13 +50,14 @@ public abstract class AbstractTestTools { @Nonnull public static final String JUNIT_RUNNER_NAME = "org.junit.runner.JUnitCore"; - @Nonnull - public static final String TESTS_CONFIGURATION_FILE_VARIABLE = "TESTS_CONFIGURATION_FILE"; @Nonnull private static HashMap<String, ToolchainBuilder> toolchainBuilders; @Nonnull + private static final File JACK_ROOT_DIR; + + @Nonnull private static final String JACK_TESTS_FOLDER = "toolchain" + File.separator + "jack" + File.separator + "jack-tests"; @@ -85,6 +86,57 @@ public abstract class AbstractTestTools { private static final Map<String, File> runtimeEnvironmentLocations = new HashMap<String, File>(); + static { + + toolchainBuilders = new HashMap<String, ToolchainBuilder>(); + toolchainBuilders.put("jack-cli" , new JackCliToolchainBuilder()); + toolchainBuilders.put("jack-api" , new JackApiToolchainBuilder()); + toolchainBuilders.put("legacy" , new LegacyToolchainBuilder()); + toolchainBuilders.put("jill-legacy", new LegacyJillToolchainBuilder()); + + testsProperties = new Properties(); + String filePath = System.getProperty("tests.config"); + + if (filePath == null) { + throw new TestConfigurationException( + "Configuration file not specified. It must be passed with -Dtests.config on command" + + "line."); + } + + File propertyFile; + propertyFile = new File(filePath); + if (!propertyFile.isAbsolute()) { + propertyFile = + new File(System.getenv("user.dir") , filePath); + } + + if (!propertyFile.exists()) { + throw new TestConfigurationException("Configuration file not found: '" + filePath + "'"); + } + + try { + testsProperties.load(new FileInputStream(propertyFile)); + runtimes.addAll(parseRuntimeList(testsProperties.getProperty(RUNTIME_LIST_KEY))); + } catch (FileNotFoundException e) { + throw new TestConfigurationException(e); + } catch (IOException e) { + throw new TestConfigurationException(e); + } catch (SecurityException e) { + throw new TestConfigurationException(e); + } catch (IllegalArgumentException e) { + throw new TestConfigurationException(e); + } catch (RuntimeRunnerException e) { + throw new TestConfigurationException(e); + } + + String jackHome = testsProperties.getProperty("jack.home"); + + if (jackHome == null) { + throw new TestConfigurationException("'jack.home' property is not set"); + } + JACK_ROOT_DIR = new File(jackHome); + } + private interface ToolchainBuilder { IToolchain build(); } @@ -126,12 +178,15 @@ public abstract class AbstractTestTools { } } - private static File getPrebuilt(@Nonnull String prebuiltName) { - String prebuiltPath = getProperty(TOOLCHAIN_PREBUILT_PREFIX + prebuiltName); + public static File getPrebuilt(@Nonnull String prebuiltName) { + String prebuiltVarName = TOOLCHAIN_PREBUILT_PREFIX + prebuiltName; + String prebuiltPath; - if (prebuiltPath == null) { + try { + prebuiltPath = getProperty(prebuiltVarName); + } catch (TestConfigurationException e) { throw new TestConfigurationException( - "Cannot find path for prebuilt 'prebuiltName' in test.properties"); + "Cannot find path for prebuilt '" + prebuiltName + "'", e); } File result = new File(prebuiltPath); @@ -146,56 +201,10 @@ public abstract class AbstractTestTools { return result; } - static { - toolchainBuilders = new HashMap<String, ToolchainBuilder>(); - toolchainBuilders.put("jack-cli" , new JackCliToolchainBuilder()); - toolchainBuilders.put("jack-api" , new JackApiToolchainBuilder()); - toolchainBuilders.put("legacy" , new LegacyToolchainBuilder()); - toolchainBuilders.put("jill-legacy", new LegacyJillToolchainBuilder()); - - testsProperties = new Properties(); - String filePath = System.getenv(TESTS_CONFIGURATION_FILE_VARIABLE); - File propertyFile; - if (filePath != null) { - propertyFile = new File(filePath); - if (!propertyFile.isAbsolute()) { - propertyFile = new File(System.getProperty("user.dir"), filePath); - } - } else { - filePath = JACK_TESTS_FOLDER + File.separatorChar + "tests.properties"; - propertyFile = - new File(getJackRootDir(), filePath); - } - - if (!propertyFile.exists()) { - throw new TestConfigurationException("Configuration file not found: '" + filePath + "'"); - } - - try { - testsProperties.load(new FileInputStream(propertyFile)); - runtimes.addAll(parseRuntimeList(testsProperties.getProperty(RUNTIME_LIST_KEY))); - } catch (FileNotFoundException e) { - throw new TestConfigurationException(e); - } catch (IOException e) { - throw new TestConfigurationException(e); - } catch (SecurityException e) { - throw new TestConfigurationException(e); - } catch (IllegalArgumentException e) { - throw new TestConfigurationException(e); - } catch (RuntimeRunnerException e) { - throw new TestConfigurationException(e); - } - } @Nonnull public static final File getJackRootDir() { - String pwdPath = System.getProperty("user.dir"); - String[] splitPath = pwdPath.split(JACK_TESTS_FOLDER); - if (splitPath[0].equals(pwdPath)) { - assert splitPath.length == 1; - throw new AssertionError("Unable to compute tests root directory"); - } - return new File(splitPath[0]); + return JACK_ROOT_DIR; } @Nonnull @@ -208,42 +217,59 @@ public abstract class AbstractTestTools { return new File(getTestsRootDir(), packageName.replace(".", File.separator)); } - /** - * Return the {@link IToolchain} specified in the tests configuration file if it matches the - * requirements expressed in paramters. Otherwise, test is ignored. - * - * @param classes Optional list of types. The first one is used to check that the candidate type - * is of this type. Otherwise JUnit test will be ignored. If more types are provided, they - * serve to narrow the expected type set, and are used for exclusion, i.e. if returned - * type is of one of these types, test is ignored. - * @return The candidate toolchain that fulfills the requirements. - */ @SuppressWarnings("unchecked") @Nonnull - public static final <T extends IToolchain> T getCandidateToolchain( - @Nonnull Class<? extends IToolchain>... classes) { + public static final <T extends IToolchain> T getCandidateToolchain() { IToolchain result = createToolchain("candidate.toolchain"); - if (classes.length > 0) { - Assume.assumeTrue(classes[0].isAssignableFrom(result.getClass())); - for (int i = 1; i < classes.length; i++) { - Assume.assumeTrue(!classes[i].isAssignableFrom(result.getClass())); - } - } return (T) result; } @Nonnull - public static final IToolchain getReferenceToolchain() { - return createToolchain("reference.toolchain"); + public static final <T extends IToolchain> T getCandidateToolchain( + @Nonnull Class<? extends IToolchain> clazz) { + T result = getCandidateToolchain(); + Assume.assumeTrue(clazz.isAssignableFrom(result.getClass())); + return result; + } + + @Nonnull + public static final <T extends IToolchain> T getCandidateToolchain( + @Nonnull Class<? extends IToolchain> clazz, + @Nonnull List<Class<? extends IToolchain>> excludeClazz) { + T result = getCandidateToolchain(clazz); + + for (Class<? extends IToolchain> c : excludeClazz) { + Assume.assumeTrue(!c.isAssignableFrom(result.getClass())); + } + + return result; } @SuppressWarnings("unchecked") @Nonnull + public static final <T extends IToolchain> T getReferenceToolchain() { + return (T) createToolchain("reference.toolchain"); + } + + @Nonnull public static final <T extends IToolchain> T getReferenceToolchain( - @Nonnull Class<?> expectedClass) { - IToolchain result = getReferenceToolchain(); - Assume.assumeTrue(expectedClass.isAssignableFrom(result.getClass())); - return (T) result; + @Nonnull Class<? extends IToolchain> clazz) { + T result = getReferenceToolchain(); + Assume.assumeTrue(clazz.isAssignableFrom(result.getClass())); + return result; + } + + @Nonnull + public static final <T extends IToolchain> T getReferenceToolchain( + @Nonnull Class<? extends IToolchain> clazz, + @Nonnull List<Class<? extends IToolchain>> excludeClazz) { + T result = getReferenceToolchain(clazz); + + for (Class<? extends IToolchain> c : excludeClazz) { + Assume.assumeTrue(!c.isAssignableFrom(result.getClass())); + } + + return result; } @Nonnull @@ -374,7 +400,7 @@ public abstract class AbstractTestTools { } @Nonnull - public static File createJavaFile(@Nonnull File folder, @Nonnull String packageName, + public static File createFile(@Nonnull File folder, @Nonnull String packageName, @Nonnull String fileName, @Nonnull String fileContent) throws IOException { File packageFolder = new File(folder, packageName.replace('.', File.separatorChar)); if (!packageFolder.exists() && !packageFolder.mkdirs()) { @@ -549,7 +575,8 @@ public abstract class AbstractTestTools { if (rtLocationPath == null) { throw new TestConfigurationException( - "Location for runtime '" + rtName + "' is not specified"); + "Location for runtime '" + rtName + "' is not specified. Set property '" + + RUNTIME_LOCATION_PREFIX + rtName + "'"); } File rtLocation = new File(rtLocationPath); if (!rtLocation.exists()) { diff --git a/jack-tests/src/com/android/jack/test/toolchain/DummyToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/DummyToolchain.java index 9e130688..f66578fe 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/DummyToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/DummyToolchain.java @@ -18,6 +18,7 @@ package com.android.jack.test.toolchain; import java.io.File; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; /** @@ -34,24 +35,24 @@ public class DummyToolchain extends AndroidToolchain { @Override @Nonnull - public void srcToExe(@Nonnull String classpath, @Nonnull File out, - @Nonnull File... sources) throws Exception { + public void srcToExe(@CheckForNull String classpath, @Nonnull File out, + boolean zipFile, @Nonnull File... sources) throws Exception { } @Override @Nonnull - public void srcToLib(@Nonnull String classpath, @Nonnull File out, + public void srcToLib(@CheckForNull String classpath, @Nonnull File out, boolean zipFiles, @Nonnull File... sources) throws Exception { } @Override @Nonnull - public void libToDex(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToExe(@Nonnull File in, @Nonnull File out, boolean zipFile) throws Exception { } @Override @Nonnull - public void libToLib(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToLib(@Nonnull File[] in, @Nonnull File out, boolean zipFiles) throws Exception { } @Override @@ -73,4 +74,5 @@ public class DummyToolchain extends AndroidToolchain { // Do nothing return this; } + } diff --git a/jack-tests/src/com/android/jack/test/toolchain/IToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/IToolchain.java index 8c35d1dc..184682b6 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/IToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/IToolchain.java @@ -20,7 +20,9 @@ import com.android.jack.test.toolchain.Toolchain.SourceLevel; import java.io.File; import java.io.OutputStream; +import java.util.List; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.processing.Processor; @@ -31,18 +33,24 @@ import javax.annotation.processing.Processor; public interface IToolchain { @Nonnull - void srcToExe(@Nonnull String classpath, @Nonnull File out, @Nonnull File... sources) - throws Exception; + void srcToExe(@CheckForNull String classpath, @Nonnull File out, boolean zipFile, + @Nonnull File... sources) throws Exception; @Nonnull - void srcToLib(@Nonnull String classpath, @Nonnull File out, boolean zipFiles, + void srcToLib(@CheckForNull String classpath, @Nonnull File out, boolean zipFiles, @Nonnull File... sources) throws Exception; @Nonnull - void libToDex(@Nonnull File in, @Nonnull File out) throws Exception; + void libToExe(@Nonnull File in, @Nonnull File out, boolean zipFile) throws Exception; + + @Nonnull + void libToLib(@Nonnull File in, @Nonnull File out, boolean zipFiles) throws Exception; + + @Nonnull + void libToLib(@Nonnull File[] in, @Nonnull File out, boolean zipFiles) throws Exception; @Nonnull - void libToLib(@Nonnull File in, @Nonnull File out) throws Exception; + void libToLib(@Nonnull List<File> in, @Nonnull File out, boolean zipFiles) throws Exception; @Nonnull IToolchain addStaticLibs(@Nonnull File... staticLibs); diff --git a/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchain.java index 7466b937..4e3b167d 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/JackApiToolchain.java @@ -18,15 +18,16 @@ package com.android.jack.test.toolchain; import com.android.jack.Jack; import com.android.jack.Options; +import com.android.jack.backend.dex.rop.CodeItemBuilder; import com.android.jack.experimental.incremental.JackIncremental; import com.android.jack.shrob.spec.Flags; import java.io.File; import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Map.Entry; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; /** @@ -39,36 +40,26 @@ public class JackApiToolchain extends JackBasedToolchain { JackApiToolchain() {} - @Override @Nonnull - public JackApiToolchain disableDxOptimizations() { - jackOptions.disableDxOptimizations(); + public JackApiToolchain setVerbosityLevel(@Nonnull Options.VerbosityLevel level) { + jackOptions.setVerbosityLevel(level); return this; } @Override @Nonnull - public JackApiToolchain enableDxOptimizations() { - jackOptions.enableDxOptimizations(); - return this; - } - - @Override - @Nonnull - public void srcToExe(@Nonnull String classpath, @Nonnull File out, @Nonnull File... sources) - throws Exception { + public void srcToExe(@CheckForNull String classpath, @Nonnull File out, boolean zipFile, + @Nonnull File... sources) throws Exception { try { - System.setOut(outRedirectStream); - System.setErr(errRedirectStream); - addProperties(properties, jackOptions); if (jackOptions.getFlags() != null) { jackOptions.applyShrobFlags(); } - jackOptions.setEcjArguments(AbstractTestTools.buildEcjArgs()); + // jackOptions.setEcjArguments(AbstractTestTools.buildEcjArgs()); + jackOptions.setEcjArguments(new ArrayList<String>()); if (annotationProcessorClass != null) { jackOptions.getEcjArguments().add("-processor"); @@ -88,25 +79,26 @@ public class JackApiToolchain extends JackBasedToolchain { /* mustExist = */false, sources); jackOptions.setClasspath(classpath); - // !zip - jackOptions.setOutputDir(out); + if (zipFile) { + jackOptions.setOutputZip(out); + } else { + jackOptions.setOutputDir(out); + } jackOptions.setJayceImports(staticLibs); jackOptions.setJarjarRulesFile(jarjarRules); - List<File> proguardFlagsFiles = new ArrayList<File>(); - - for (File flagFile : proguardFlagsFiles) { - proguardFlagsFiles.add(flagFile); - } - if (proguardFlagsFiles.size() > 0) { - jackOptions.setProguardFlagsFile(proguardFlagsFiles); + if (proguardFlags.size() > 0) { + jackOptions.setProguardFlagsFile(proguardFlags); } jackOptions.addProperty(Options.EMIT_LOCAL_DEBUG_INFO.getName(), Boolean.toString(withDebugInfos)); + System.setOut(outRedirectStream); + System.setErr(errRedirectStream); + if (jackOptions.getIncrementalFolder() != null) { JackIncremental.run(jackOptions); } else { @@ -121,51 +113,63 @@ public class JackApiToolchain extends JackBasedToolchain { @Override @Nonnull - public void srcToLib(@Nonnull String classpath, @Nonnull File out, boolean zipFiles, + public void srcToLib(@CheckForNull String classpath, @Nonnull File out, boolean zipFiles, @Nonnull File... sources) throws Exception { try { - Options options = jackOptions; + addProperties(properties, jackOptions); - addProperties(properties, options); + if (jackOptions.getFlags() != null) { + jackOptions.applyShrobFlags(); + } - options.setClasspath(classpath); + jackOptions.setClasspath(classpath); if (zipFiles) { - options.setJayceOutputZip(out); + jackOptions.setJayceOutputZip(out); } else { - options.setJayceOutputDir(out); + jackOptions.setJayceOutputDir(out); } - options.setEcjArguments(AbstractTestTools.buildEcjArgs()); + jackOptions.setEcjArguments(new ArrayList<String>()); if (annotationProcessorClass != null) { - options.getEcjArguments().add("-processor"); - options.getEcjArguments().add(annotationProcessorClass.getName()); + jackOptions.getEcjArguments().add("-processor"); + jackOptions.getEcjArguments().add(annotationProcessorClass.getName()); } if (annotationProcessorOutDir != null) { - options.getEcjArguments().add("-d"); - options.getEcjArguments().add(annotationProcessorOutDir.getAbsolutePath()); + jackOptions.getEcjArguments().add("-d"); + jackOptions.getEcjArguments().add(annotationProcessorOutDir.getAbsolutePath()); } for (String ecjArg : extraEcjArgs) { - options.getEcjArguments().add(ecjArg); + jackOptions.getEcjArguments().add(ecjArg); } - AbstractTestTools.addFile(options.getEcjArguments(), + AbstractTestTools.addFile(jackOptions.getEcjArguments(), /* mustExist = */false, sources); - options.addProperty(Options.EMIT_LOCAL_DEBUG_INFO.getName(), + + jackOptions.setJarjarRulesFile(jarjarRules); + + if (proguardFlags.size() > 0) { + jackOptions.setProguardFlagsFile(proguardFlags); + } + + jackOptions.addProperty(Options.EMIT_LOCAL_DEBUG_INFO.getName(), Boolean.toString(withDebugInfos)); + jackOptions.addProperty(CodeItemBuilder.DEX_OPTIMIZE.getName(), + Boolean.toString(!withDebugInfos)); + System.setOut(outRedirectStream); System.setErr(errRedirectStream); - if (options.getIncrementalFolder() != null) { - JackIncremental.run(options); + if (jackOptions.getIncrementalFolder() != null) { + JackIncremental.run(jackOptions); } else { - Jack.run(options); + Jack.run(jackOptions); } } finally { @@ -176,24 +180,36 @@ public class JackApiToolchain extends JackBasedToolchain { @Override @Nonnull - public void libToDex(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToExe(@Nonnull File in, @Nonnull File out, boolean zipFile) throws Exception { System.setOut(outRedirectStream); System.setErr(errRedirectStream); try { - Options options = jackOptions; - addProperties(properties, options); + addProperties(properties, jackOptions); + + if (jackOptions.getFlags() != null) { + jackOptions.applyShrobFlags(); + } + + jackOptions.setJarjarRulesFile(jarjarRules); - options.getJayceImport().add(in); - options.getJayceImport().addAll(staticLibs); + if (proguardFlags.size() > 0) { + jackOptions.setProguardFlagsFile(proguardFlags); + } + + jackOptions.getJayceImport().add(in); + jackOptions.getJayceImport().addAll(staticLibs); - // !zip - options.setOutputDir(out); + if (zipFile) { + jackOptions.setOutputZip(out); + } else { + jackOptions.setOutputDir(out); + } - if (options.getIncrementalFolder() != null) { - JackIncremental.run(options); + if (jackOptions.getIncrementalFolder() != null) { + JackIncremental.run(jackOptions); } else { - Jack.run(options); + Jack.run(jackOptions); } } finally { @@ -204,8 +220,38 @@ public class JackApiToolchain extends JackBasedToolchain { @Override @Nonnull - public void libToLib(@Nonnull File in, @Nonnull File out) throws Exception { - throw new AssertionError("Not Yet Implemented"); + public void libToLib(@Nonnull File[] in, @Nonnull File out, boolean zipFiles) throws Exception { + addProperties(properties, jackOptions); + + jackOptions.setJarjarRulesFile(jarjarRules); + + if (jackOptions.getFlags() != null) { + jackOptions.applyShrobFlags(); + } + + if (proguardFlags.size() > 0) { + jackOptions.setProguardFlagsFile(proguardFlags); + } + + for (File staticLib : in) { + jackOptions.getJayceImport().add(staticLib); + } + + for (File staticLib : staticLibs) { + jackOptions.getJayceImport().add(staticLib); + } + + if (zipFiles) { + jackOptions.setJayceOutputZip(out); + } else { + jackOptions.setJayceOutputDir(out); + } + + if (jackOptions.getIncrementalFolder() != null) { + JackIncremental.run(jackOptions); + } else { + Jack.run(jackOptions); + } } @Nonnull diff --git a/jack-tests/src/com/android/jack/test/toolchain/JackBasedToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JackBasedToolchain.java index 729eb89c..3e13d9e7 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/JackBasedToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/JackBasedToolchain.java @@ -16,6 +16,10 @@ package com.android.jack.test.toolchain; +import com.android.jack.backend.dex.DexFileWriter; +import com.android.jack.backend.dex.MultiDexLegacy; +import com.android.jack.backend.dex.rop.CodeItemBuilder; + import java.io.File; import java.util.ArrayList; import java.util.HashMap; @@ -30,6 +34,15 @@ import javax.annotation.Nonnull; */ public abstract class JackBasedToolchain extends AndroidToolchain { + /** + * Available mode for the multidex feature + */ + public enum MultiDexKind { + NONE, + NATIVE, + LEGACY + } + @Nonnull protected final Map<String, String> properties = new HashMap<String, String>(); @CheckForNull @@ -44,6 +57,23 @@ public abstract class JackBasedToolchain extends AndroidToolchain { return this; } + public final JackBasedToolchain setMultiDexKind(@Nonnull MultiDexKind kind) { + switch (kind) { + case NATIVE: + addProperty(DexFileWriter.DEX_WRITING_POLICY.getName(), "multidex"); + break; + case LEGACY: + addProperty(DexFileWriter.DEX_WRITING_POLICY.getName(), "multidex"); + addProperty(MultiDexLegacy.MULTIDEX_LEGACY.getName(), "true"); + break; + case NONE: + break; + default: + throw new AssertionError("Unsupported multi dex kind: '" + kind.name() + "'"); + } + return this; + } + @Nonnull public final JackBasedToolchain addEcjArgs(@Nonnull String arg) { extraEcjArgs.add(arg); @@ -79,10 +109,24 @@ public abstract class JackBasedToolchain extends AndroidToolchain { @Override @Nonnull + public JackBasedToolchain disableDxOptimizations() { + addProperty(CodeItemBuilder.DEX_OPTIMIZE.getName(), "false"); + return this; + } + + @Override + @Nonnull + public JackBasedToolchain enableDxOptimizations() { + addProperty(CodeItemBuilder.DEX_OPTIMIZE.getName(), "true"); + return this; + } + + @Override + @Nonnull public File[] getDefaultBootClasspath() { return new File[] {new File(AbstractTestTools.getJackRootDir(), "toolchain/jack/jack-tests/libs/core-stubs-mini.jar"), new File( AbstractTestTools.getJackRootDir(), - "toolchain/jack/jack-tests/prebuilts/junit4-hostdex.jar")}; + "toolchain/jack/jack-tests/prebuilts/junit4-targetdex-jack.zip")}; } } diff --git a/jack-tests/src/com/android/jack/test/toolchain/JackCliToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/JackCliToolchain.java index 17f11dd7..34d974f9 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/JackCliToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/JackCliToolchain.java @@ -16,7 +16,6 @@ package com.android.jack.test.toolchain; -import com.android.jack.backend.dex.rop.CodeItemBuilder; import com.android.jack.util.ExecuteFile; import java.io.File; @@ -47,8 +46,8 @@ public class JackCliToolchain extends JackBasedToolchain { @Override @Nonnull - public void srcToExe(@Nonnull String classpath, @Nonnull File out, - @Nonnull File... sources) throws Exception { + public void srcToExe(@CheckForNull String classpath, @Nonnull File out, + boolean zipFile, @Nonnull File... sources) throws Exception { List<String> args = new ArrayList<String>(); args.add("java"); @@ -63,41 +62,37 @@ public class JackCliToolchain extends JackBasedToolchain { args.add(com.android.jack.Main.class.getName()); } - if (withDebugInfos) { - args.add("-D"); - args.add("jack.dex.optimize=false"); - } else { - args.add("-D"); - args.add("jack.dex.optimize=true"); - } - addProperties(properties, args); - args.add("--classpath"); - args.add(classpath); + if (classpath != null) { + args.add("--classpath"); + args.add(classpath); + } - args.add("-o"); + if (zipFile) { + args.add("--output-dex-zip"); + } else { + args.add("--output-dex"); + } args.add(out.getAbsolutePath()); if (jarjarRules != null) { - args.add("--jarjar-rules"); + args.add("--config-jarjar"); args.add(jarjarRules.getAbsolutePath()); } for (File flags : proguardFlags) { - args.add("--proguard-flags"); + args.add("--config-proguard"); args.add(flags.getAbsolutePath()); } for (File staticLib : staticLibs) { - args.add("--import-jack"); + args.add("--import"); args.add(staticLib.getAbsolutePath()); } args.addAll(extraJackArgs); - args.add("--ecj"); - if (withDebugInfos) { args.add("-g"); } @@ -129,7 +124,7 @@ public class JackCliToolchain extends JackBasedToolchain { @Override @Nonnull - public void srcToLib(@Nonnull String classpath, @Nonnull File out, + public void srcToLib(@CheckForNull String classpath, @Nonnull File out, boolean zipFiles, @Nonnull File... sources) throws Exception { List<String> args = new ArrayList<String>(); @@ -147,19 +142,29 @@ public class JackCliToolchain extends JackBasedToolchain { addProperties(properties, args); - args.add("--classpath"); - args.add(classpath); + if (classpath != null) { + args.add("--classpath"); + args.add(classpath); + } if (zipFiles) { - args.add("--jack-output-zip"); + args.add("--output-jack"); } else { - args.add("--jack-output"); + args.add("--output-jack-dir"); } args.add(out.getAbsolutePath()); args.addAll(extraJackArgs); - args.add("--ecj"); + if (jarjarRules != null) { + args.add("--config-jarjar"); + args.add(jarjarRules.getAbsolutePath()); + } + + for (File flags : proguardFlags) { + args.add("--config-proguard"); + args.add(flags.getAbsolutePath()); + } if (withDebugInfos) { args.add("-g"); @@ -192,7 +197,7 @@ public class JackCliToolchain extends JackBasedToolchain { @Override @Nonnull - public void libToDex(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToExe(@Nonnull File in, @Nonnull File out, boolean zipFile) throws Exception { List<String> args = new ArrayList<String>(); args.add("java"); @@ -217,15 +222,20 @@ public class JackCliToolchain extends JackBasedToolchain { addProperties(properties, args); - args.add("--import-jack"); + args.add("--import"); args.add(in.getAbsolutePath()); for (File staticLib : staticLibs) { - args.add("--import-jack"); + args.add("--import"); args.add(staticLib.getAbsolutePath()); } - args.add("-o"); + if (zipFile) { + args.add("--output-dex-zip"); + } else { + args.add("--output-dex"); + } + args.add(out.getAbsolutePath()); ExecuteFile exec = new ExecuteFile(args.toArray(new String[args.size()])); @@ -240,22 +250,58 @@ public class JackCliToolchain extends JackBasedToolchain { @Override @Nonnull - public void libToLib(@Nonnull File in, @Nonnull File out) throws Exception { - throw new AssertionError("Not Yet Implemented"); - } + public void libToLib(@Nonnull File[] in, @Nonnull File out, boolean zipFiles) throws Exception { + List<String> args = new ArrayList<String>(); + args.add("java"); + args.add("-cp"); + args.add(jackPrebuilt.getAbsolutePath()); - @Override - @Nonnull - public JackCliToolchain disableDxOptimizations() { - addProperty(CodeItemBuilder.DEX_OPTIMIZE.getName(), "false"); - return this; - } + if (incrementalFolder != null) { + args.add(com.android.jack.experimental.incremental.Main.class.getName()); + args.add("--incremental-folder"); + args.add(incrementalFolder.getAbsolutePath()); + } else { + args.add(com.android.jack.Main.class.getName()); + } + + addProperties(properties, args); + + if (jarjarRules != null) { + args.add("--config-jarjar"); + args.add(jarjarRules.getAbsolutePath()); + } + + for (File flags : proguardFlags) { + args.add("--config-proguard"); + args.add(flags.getAbsolutePath()); + } + + for (File staticlib : in) { + args.add("--import"); + args.add(staticlib.getAbsolutePath()); + } + + for (File staticLib : staticLibs) { + args.add("--import"); + args.add(staticLib.getAbsolutePath()); + } + + if (zipFiles) { + args.add("--output-jack"); + } else { + args.add("--output-jack-dir"); + } + args.add(out.getAbsolutePath()); + + ExecuteFile exec = new ExecuteFile(args.toArray(new String[args.size()])); + exec.setErr(outRedirectStream); + exec.setOut(errRedirectStream); + exec.setVerbose(true); + + if (!exec.run()) { + throw new RuntimeException("Jack compiler exited with an error"); + } - @Override - @Nonnull - public JackCliToolchain enableDxOptimizations() { - addProperty(CodeItemBuilder.DEX_OPTIMIZE.getName(), "true"); - return this; } @Nonnull @@ -278,4 +324,5 @@ public class JackCliToolchain extends JackBasedToolchain { args.add(entry.getKey() + "=" + entry.getValue()); } } + } diff --git a/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java index 5ebf6e4f..ebf83f8f 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/LegacyJillToolchain.java @@ -45,8 +45,8 @@ public class LegacyJillToolchain extends JillBasedToolchain { @Override @Nonnull - public void srcToExe(@Nonnull String classpath, @Nonnull File out, @Nonnull File... sources) - throws Exception { + public void srcToExe(@Nonnull String classpath, @Nonnull File out, boolean zipFile, + @Nonnull File... sources) throws Exception { try { File jarFile = AbstractTestTools.createTempFile("legacyLib", ".jar"); @@ -71,7 +71,7 @@ public class LegacyJillToolchain extends JillBasedToolchain { File jillLib = AbstractTestTools.createTempFile("jillLib", ".jar"); executeJill(jarFileProguard, jillLib, true); - libToDex(jillLib, out); + libToExe(jillLib, out, zipFile); } catch (IOException e) { throw new RuntimeException("Legacy toolchain exited with an error", e); @@ -112,7 +112,7 @@ public class LegacyJillToolchain extends JillBasedToolchain { @Override @Nonnull - public void libToLib(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToLib(@Nonnull File[] in, @Nonnull File out, boolean zipFiles) throws Exception { throw new AssertionError("Not Yet Implemented"); } diff --git a/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java b/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java index 3a5a231d..19fcf927 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/LegacyToolchain.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; /** @@ -50,8 +51,8 @@ public class LegacyToolchain extends AndroidToolchain { @Override @Nonnull - public void srcToExe(@Nonnull String classpath, @Nonnull File out, - @Nonnull File... sources) throws Exception { + public void srcToExe(@CheckForNull String classpath, @Nonnull File out, + boolean zipFile, @Nonnull File... sources) throws Exception { try { @@ -74,7 +75,7 @@ public class LegacyToolchain extends AndroidToolchain { jarFileProguard = jarFileJarjar; } - libToDex(jarFileProguard, out); + libToExe(jarFileProguard, out, zipFile); } catch (IOException e) { throw new RuntimeException("Legacy toolchain exited with an error", e); @@ -83,7 +84,7 @@ public class LegacyToolchain extends AndroidToolchain { @Override @Nonnull - public void srcToLib(@Nonnull String classpath, @Nonnull File out, + public void srcToLib(@CheckForNull String classpath, @Nonnull File out, boolean zipFiles, @Nonnull File... sources) throws Exception { try { @@ -113,10 +114,10 @@ public class LegacyToolchain extends AndroidToolchain { @Override @Nonnull - public void libToDex(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToExe(@Nonnull File in, @Nonnull File out, boolean zipFile) throws Exception { try { - compileWithDx(in, out); + compileWithDx(in, out, zipFile); } catch (IOException e) { throw new RuntimeException("Legacy toolchain exited with an error", e); } @@ -124,7 +125,7 @@ public class LegacyToolchain extends AndroidToolchain { @Override @Nonnull - public void libToLib(@Nonnull File in, @Nonnull File out) throws Exception { + public void libToLib(@Nonnull File[] in, @Nonnull File out, boolean zipFiles) throws Exception { throw new AssertionError("Not Yet Implemented"); } @@ -170,8 +171,10 @@ public class LegacyToolchain extends AndroidToolchain { args.add(inJar.getAbsolutePath()); args.add("-outjars"); args.add(outJar.getAbsolutePath()); - args.add("-libraryjars"); - args.add(bootclasspathStr); + if (bootclasspathStr != null) { + args.add("-libraryjars"); + args.add(bootclasspathStr); + } args.add("-verbose"); args.add("-forceprocessing"); args.add("-dontoptimize"); @@ -194,10 +197,22 @@ public class LegacyToolchain extends AndroidToolchain { } } - private void compileWithEcj(@Nonnull File[] sources, @Nonnull String classpath, + private void compileWithEcj(@Nonnull File[] sources, @CheckForNull String classpath, @Nonnull File out) { - - throw new AssertionError("Not yet implemented"); + List<String> args = new ArrayList<String>(4 + sources.length); + if (classpath != null) { + args.add("-classpath"); + args.add(classpath); + } + addSourceLevel(sourceLevel, args); + args.add("-noExit"); + args.add("-preserveAllLocals"); + args.add("-d"); + args.add(out.getAbsolutePath()); + for (File sourceFile : sources) { + args.add(sourceFile.getAbsolutePath()); + } + org.eclipse.jdt.internal.compiler.batch.Main.main(args.toArray(new String[args.size()])); } @Override @@ -229,7 +244,7 @@ public class LegacyToolchain extends AndroidToolchain { } private void compileWithExternalRefCompiler(@Nonnull File[] sources, - @Nonnull String classpath, @Nonnull File out) { + @CheckForNull String classpath, @Nonnull File out) { List<String> arguments = new ArrayList<String>(); @@ -265,7 +280,7 @@ public class LegacyToolchain extends AndroidToolchain { } } - private void compileWithDx(File in, File out) + private void compileWithDx(@Nonnull File in, @Nonnull File out, boolean zipFile) throws IOException { try { @@ -274,7 +289,7 @@ public class LegacyToolchain extends AndroidToolchain { Arguments arguments = new Arguments(); - arguments.jarOutput = false; + arguments.jarOutput = zipFile; arguments.outName = new File(out, getBinaryFileName()).getAbsolutePath(); arguments.optimize = !withDebugInfos && useDxOptimization; // this only means we deactivate the check that no core classes are included diff --git a/jack-tests/src/com/android/jack/test/toolchain/Toolchain.java b/jack-tests/src/com/android/jack/test/toolchain/Toolchain.java index d35d814b..6954f276 100644 --- a/jack-tests/src/com/android/jack/test/toolchain/Toolchain.java +++ b/jack-tests/src/com/android/jack/test/toolchain/Toolchain.java @@ -67,21 +67,32 @@ public abstract class Toolchain implements IToolchain { @Override @Nonnull - public abstract void srcToExe(@Nonnull String classpath, @Nonnull File out, - @Nonnull File... sources) throws Exception; + public abstract void srcToExe(@CheckForNull String classpath, @Nonnull File out, + boolean zipFile, @Nonnull File... sources) throws Exception; @Override @Nonnull - public abstract void srcToLib(@Nonnull String classpath, @Nonnull File out, + public abstract void srcToLib(@CheckForNull String classpath, @Nonnull File out, boolean zipFiles, @Nonnull File... sources) throws Exception; @Override @Nonnull - public abstract void libToDex(@Nonnull File in, @Nonnull File out) throws Exception; + public abstract void libToExe(@Nonnull File in, @Nonnull File out, boolean zipFile) + throws Exception; @Override @Nonnull - public abstract void libToLib(@Nonnull File in, @Nonnull File out) throws Exception; + public final void libToLib(@Nonnull File in, @Nonnull File out, boolean zipFiles) + throws Exception { + libToLib(new File[] {in}, out, zipFiles); + } + + @Override + @Nonnull + public final void libToLib(@Nonnull List<File> in, @Nonnull File out, boolean zipFiles) + throws Exception { + libToLib(in.toArray(new File[in.size()]), out, zipFiles); + } @Override @Nonnull @@ -135,9 +146,6 @@ public abstract class Toolchain implements IToolchain { @Override @Nonnull public final Toolchain setOutputStream(@Nonnull OutputStream outputStream) { - if (outRedirectStream != null) { - outRedirectStream.close(); - } outRedirectStream = new PrintStream(outputStream); return this; } @@ -145,9 +153,6 @@ public abstract class Toolchain implements IToolchain { @Override @Nonnull public final Toolchain setErrorStream(@Nonnull OutputStream errorStream) { - if (errRedirectStream != null) { - errRedirectStream.close(); - } errRedirectStream = new PrintStream(errorStream); return this; } |