diff options
Diffstat (limited to 'jack-tests/src/com/android/jack/test/helper')
7 files changed, 962 insertions, 0 deletions
diff --git a/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java b/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java new file mode 100644 index 0000000..f3858bf --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java @@ -0,0 +1,37 @@ +/* + * 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 {@link SourceToDexComparisonTestHelper} is used to compare dex files structures. + */ +public class CheckDexStructureTestHelper extends SourceToDexComparisonTestHelper { + + public CheckDexStructureTestHelper(@Nonnull File fileOrSourceList) throws Exception { + super(fileOrSourceList); + } + + public void compare() throws Exception { + runTest(createDexFileComparator()); + } + +} diff --git a/jack-tests/src/com/android/jack/test/helper/ErrorTestHelper.java b/jack-tests/src/com/android/jack/test/helper/ErrorTestHelper.java new file mode 100644 index 0000000..d7142f5 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/ErrorTestHelper.java @@ -0,0 +1,75 @@ +/* + * 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 com.android.jack.test.toolchain.AbstractTestTools; + +import java.io.File; +import java.io.IOException; + +import javax.annotation.Nonnull; + +/** + * This class is used by error tests, it basically handles the directory structure. + */ +public class ErrorTestHelper { + + @Nonnull + private final File testingFolder; + @Nonnull + private final File sourceFolder; + @Nonnull + private final File jackFolder; + @Nonnull + private final File outputDexFolder; + + public ErrorTestHelper() throws IOException { + this.testingFolder = AbstractTestTools.createTempDir(); + this.sourceFolder = new File(testingFolder, "src"); + if (!this.sourceFolder.mkdirs()) { + throw new IOException("Failed to create folder " + this.sourceFolder.getPath()); + } + this.jackFolder = new File(testingFolder, "jack"); + if (!this.jackFolder.mkdirs()) { + throw new IOException("Failed to create folder " + this.jackFolder.getPath()); + } + this.outputDexFolder = new File(this.testingFolder, "dex"); + if (!this.outputDexFolder.mkdirs()) { + throw new IOException("Failed to create folder " + this.outputDexFolder.getPath()); + } + } + + @Nonnull + public File getSourceFolder() { + return sourceFolder; + } + + @Nonnull + public File getJackFolder() { + return jackFolder; + } + + @Nonnull + public File getTestingFolder() { + return testingFolder; + } + + @Nonnull + public File getOutputDexFolder() { + return outputDexFolder; + } +} diff --git a/jack-tests/src/com/android/jack/test/helper/GenericComparisonTestHelper.java b/jack-tests/src/com/android/jack/test/helper/GenericComparisonTestHelper.java new file mode 100644 index 0000000..0b947ee --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/GenericComparisonTestHelper.java @@ -0,0 +1,45 @@ +/* + * 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 com.android.jack.test.comparator.Comparator; + +import javax.annotation.Nonnull; + +/** + * This class implements a pattern of tests where two compilers are used on the same + * sources and the result is then compared with a variety of {@link Comparator}s. + */ +public abstract class GenericComparisonTestHelper { + + @Nonnull + protected abstract void executeCandidateToolchain() throws Exception; + @Nonnull + protected abstract void executeReferenceToolchain() throws Exception; + + public final void runTest(@Nonnull Comparator... comparators) throws Exception { + + assert comparators.length > 0 : "You must provide at least one comparator"; + + executeCandidateToolchain(); + executeReferenceToolchain(); + + for (Comparator comparator : comparators) { + comparator.compare(); + } + } +} diff --git a/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java b/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java new file mode 100644 index 0000000..4f5e172 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java @@ -0,0 +1,169 @@ +/* + * 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 com.android.jack.backend.jayce.JayceFileImporter; +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.JillBasedToolchain; + +import junit.framework.Assert; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nonnull; + +/** + * This class is used to write tests on incremental compilation. + */ +public class IncrementalTestHelper { + + @Nonnull + private final File testingFolder; + @Nonnull + private final File sourceFolder; + @Nonnull + private final File dexOutDir; + @Nonnull + private final File dexFile; + @Nonnull + private final File compilerStateFolder; + @Nonnull + private final File jackFolder; + @Nonnull + private final Set<File> javaFiles = new HashSet<File>(); + @Nonnull + private final Map<String, Long> fileModificationDate = new HashMap<String, Long>(); + + public IncrementalTestHelper(@Nonnull File testingFolder) throws IOException { + this.testingFolder = testingFolder; + this.sourceFolder = new File(testingFolder, "src"); + if (!this.sourceFolder.mkdirs()) { + throw new IOException("Failed to create folder " + this.sourceFolder.getAbsolutePath()); + } + compilerStateFolder = new File(testingFolder, "compileState"); + if (!compilerStateFolder.exists() && !compilerStateFolder.mkdir()) { + throw new IOException("Failed to create folder " + compilerStateFolder.getAbsolutePath()); + } + dexOutDir = new File(testingFolder, "outputBinary"); + if (!dexOutDir.exists() && !dexOutDir.mkdir()) { + throw new IOException("Failed to create folder " + dexOutDir.getAbsolutePath()); + } + dexFile = new File(dexOutDir, "classes.dex"); + jackFolder = new File(compilerStateFolder, "jackFiles"); + } + + @Nonnull + public File addJavaFile(@Nonnull String packageName, @Nonnull String fileName, + @Nonnull String fileContent) throws IOException { + File file = AbstractTestTools.createJavaFile(sourceFolder, packageName, fileName, fileContent); + javaFiles.add(file); + return file; + } + + public void deleteJavaFile(@Nonnull File javaFile) + throws IOException { + AbstractTestTools.deleteFile(javaFile); + javaFiles.remove(javaFile); + } + + @Nonnull + public File getCompilerStateFolder() { + return compilerStateFolder; + } + + public void cleanSnapshot() { + fileModificationDate.clear(); + } + + public void snapshotJackFilesModificationDate() { + List<File> jackFiles = new ArrayList<File>(); + fillJackFiles(jackFolder, jackFiles); + for (File jackFile : jackFiles) { + fileModificationDate.put(jackFile.getAbsolutePath(), Long.valueOf(jackFile.lastModified())); + } + } + + private void fillJackFiles(@Nonnull File file, @Nonnull List<File> jackFiles) { + if (file.isDirectory()) { + for (File subFile : file.listFiles()) { + fillJackFiles(subFile, jackFiles); + } + } else if (file.getName().endsWith(JayceFileImporter.JAYCE_FILE_EXTENSION)) { + jackFiles.add(file); + } + } + + @Nonnull + public List<String> getFQNOfRebuiltTypes() { + assert !fileModificationDate.isEmpty(); + + List<String> fqnOfRebuiltTypes = new ArrayList<String>(); + List<File> jackFiles = new ArrayList<File>(); + fillJackFiles(jackFolder, jackFiles); + + for (File jackFile : jackFiles) { + 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); + fqnOfRebuiltTypes.add(binaryTypeName.replace(File.separatorChar, '.')); + } + } + + return (fqnOfRebuiltTypes); + } + + public void incrementalBuildFromFolder() throws Exception { + JackBasedToolchain jackToolchain = + AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, JillBasedToolchain.class); + jackToolchain.setIncrementalFolder(getCompilerStateFolder()); + + jackToolchain.srcToExe( + AbstractTestTools.getClasspathAsString(jackToolchain.getDefaultBootClasspath()), dexOutDir, + sourceFolder); + + Thread.sleep(1000); + } + + @Nonnull + public String run(@Nonnull String mainClass) throws Exception { + DalvikRunnerHost runner = + (DalvikRunnerHost) RuntimeRunnerFactory.create("dalvik-fast-host"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + runner.setOutputStream(out); + Assert.assertEquals(0, runner.run(new String [0], new String[] {mainClass}, dexFile)); + return out.toString(); + } + + @Nonnull + public List<File> getJackFiles() { + return AbstractTestTools.getFiles(jackFolder, ".jack"); + } + +} diff --git a/jack-tests/src/com/android/jack/test/helper/JackDexMergerTestHelper.java b/jack-tests/src/com/android/jack/test/helper/JackDexMergerTestHelper.java new file mode 100644 index 0000000..b9d8669 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/JackDexMergerTestHelper.java @@ -0,0 +1,97 @@ +/* + * 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 com.android.jack.Options; +import com.android.jack.TestTools; +import com.android.jack.backend.dex.rop.CodeItemBuilder; +import com.android.jack.test.comparator.Comparator; +import com.android.jack.test.comparator.ComparatorComposite; +import com.android.jack.test.comparator.ComparatorDex; +import com.android.jack.test.comparator.ComparatorDexAnnotations; +import com.android.jack.test.comparator.ComparatorDiff; +import com.android.jack.test.toolchain.AbstractTestTools; +import com.android.jack.test.toolchain.JackBasedToolchain; +import com.android.sched.scheduler.ScheduleInstance; + +import java.io.File; +import java.io.IOException; + +import javax.annotation.Nonnull; + +/** + * This class defines a helper for dex merger tests. + */ +public class JackDexMergerTestHelper extends SourceToDexComparisonTestHelper { + + public JackDexMergerTestHelper(@Nonnull File fileOrSourceList) throws Exception { + super(fileOrSourceList); + } + + @Override + @Nonnull + protected JackBasedToolchain getCandidateToolchain() { + // Mono dex + JackBasedToolchain toolchain = + AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); + toolchain.addProperty(Options.EMIT_LINE_NUMBER_DEBUG_INFO.getName(), + Boolean.toString(withDebugInfos)); + toolchain.addProperty(ScheduleInstance.DEFAULT_RUNNER.getName(), "single-threaded"); + toolchain.addProperty(CodeItemBuilder.FORCE_JUMBO.getName(), "true"); + + return toolchain; + } + + @Override + @Nonnull + protected JackBasedToolchain getReferenceToolchain() { + // One dex per type + JackBasedToolchain toolchain = + AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); + File oneDexPerTypeFolder; + try { + oneDexPerTypeFolder = TestTools.createTempDir("oneDexPerType", "dex"); + toolchain.addProperty(Options.EMIT_LINE_NUMBER_DEBUG_INFO.getName(), + Boolean.toString(withDebugInfos)); + toolchain.addProperty(ScheduleInstance.DEFAULT_RUNNER.getName(), "single-threaded"); + toolchain.addProperty(Options.TYPEDEX_DIR.getName(), + oneDexPerTypeFolder.getAbsolutePath()); + } catch (IOException e) { + throw new AssertionError(e); + } + return toolchain; + } + + @Override + @Nonnull + public Comparator createDexFileComparator() { + ComparatorDex comparatorDex = new ComparatorDex(candidateDex, refDex); + comparatorDex.setWithDebugInfo(false); + comparatorDex.setStrict(true); + comparatorDex.setCompareDebugInfoBinary(false); + comparatorDex.setCompareInstructionNumber(true); + comparatorDex.setInstructionNumberTolerance(0); + ComparatorDexAnnotations comparatorAnnotations = + new ComparatorDexAnnotations(candidateDex, refDex); + ComparatorDiff comparatorDiff = new ComparatorDiff(candidateDex, refDex); + return new ComparatorComposite(comparatorDex, comparatorAnnotations, comparatorDiff); + } + + public void compare() throws Exception { + runTest(createDexFileComparator()); + } +} diff --git a/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java b/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java new file mode 100644 index 0000000..2923699 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java @@ -0,0 +1,373 @@ +/* + * 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 com.google.common.base.CharMatcher; +import com.google.common.base.Splitter; + +import com.android.jack.test.runner.RuntimeRunner; +import com.android.jack.test.runtime.RuntimeTestInfo; +import com.android.jack.test.toolchain.AbstractTestTools; +import com.android.jack.test.toolchain.AndroidToolchain; +import com.android.jack.test.toolchain.Toolchain.SourceLevel; +import com.android.sched.util.collect.Lists; + +import junit.framework.Assert; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * This class is used to write runtime tests. + */ +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 String srcDirName = "jack"; + @Nonnull + private String libDirName = "lib"; + @Nonnull + private String refDirName = "dx"; + @Nonnull + private String linkDirName = "link"; + + private boolean withDebugInfos = false; + + @CheckForNull + private String jarjarRulesFileName; + @CheckForNull + private String[] proguardFlagsFileNames; + + @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); + jUnitClasses.add(info.jUnit); + } + } + + @Nonnull + public RuntimeTestHelper setSrcDirName(@Nonnull String srcDirName) { + this.srcDirName = srcDirName; + return this; + } + + @Nonnull + public RuntimeTestHelper setLibDirName(@Nonnull String libDirName) { + this.libDirName = libDirName; + return this; + } + + @Nonnull + public RuntimeTestHelper setRefDirName(@Nonnull String refDirName) { + this.refDirName = refDirName; + return this; + } + + @Nonnull + public RuntimeTestHelper setLinkDirName(@Nonnull String linkDirName) { + this.linkDirName = linkDirName; + return this; + } + + @Nonnull + public RuntimeTestHelper setWithDebugInfos(boolean withDebugInfos) { + this.withDebugInfos = withDebugInfos; + return this; + } + + @Nonnull + public RuntimeTestHelper setSourceLevel(@Nonnull SourceLevel level) { + candidateTestTools.setSourceLevel(level); + referenceTestTools.setSourceLevel(level); + return this; + } + + @Nonnull + public RuntimeTestHelper setPropertyFileName(@Nonnull String propertyFileName) { + this.propertyFileName = propertyFileName; + return this; + } + + @Nonnull + public RuntimeTestHelper setJarjarRulesFileName(@Nonnull String name) { + this.jarjarRulesFileName = name; + return this; + } + + @Nonnull + public RuntimeTestHelper setProguardFlagsFileNames(@Nonnull String[] proguardFlagsFileNames) { + this.proguardFlagsFileNames = proguardFlagsFileNames; + return this; + } + + public void compileAndRunTest() throws Exception { + Properties testProperties = new Properties(); + try { + loadTestProperties(testProperties); + } catch (FileNotFoundException e) { + // No file, no pb + } + + candidateTestTools.setWithDebugInfos(withDebugInfos); + referenceTestTools.setWithDebugInfos(withDebugInfos); + + File[] candidateBootClasspath = candidateTestTools.getDefaultBootClasspath(); + File[] referenceBootClasspath = referenceTestTools.getDefaultBootClasspath(); + + String candidateBootClasspathAsString = + AbstractTestTools.getClasspathAsString(candidateTestTools.getDefaultBootClasspath()); + String referenceBootClasspathAsString = + AbstractTestTools.getClasspathAsString(referenceTestTools.getDefaultBootClasspath()); + + // Compile lib src + File libLibRef = null; + File libBinaryRef = null; + File libLibCandidate = null; + if (getLibSrc().length != 0) { + libLibRef = + AbstractTestTools.createTempFile("-lib-ref", referenceTestTools.getLibraryExtension()); + File libBinaryRefDir = AbstractTestTools.createTempDir(); + libBinaryRef = new File(libBinaryRefDir, referenceTestTools.getBinaryFileName()); + referenceTestTools.srcToLib(referenceBootClasspathAsString, libLibRef, /* zipFiles = */true, + getLibSrc()); + referenceTestTools.libToDex(libLibRef, libBinaryRefDir); + + libLibCandidate = AbstractTestTools.createTempFile("-lib-candidate", + candidateTestTools.getLibraryExtension()); + candidateTestTools.srcToLib(candidateBootClasspathAsString, libLibCandidate, + /* zipFiles = */true, getLibSrc()); + } + + // Compile test src + String candidateClasspathAsString; + String referenceClasspathAsString; + if (getLibSrc().length != 0) { + File[] candidateClassPath = new File[candidateBootClasspath.length + 1]; + System.arraycopy(candidateBootClasspath, 0, candidateClassPath, 0, + candidateBootClasspath.length); + candidateClassPath[candidateClassPath.length - 1] = libLibRef; + candidateClasspathAsString = AbstractTestTools.getClasspathAsString(candidateClassPath); + File[] referenceClasspath = new File[referenceBootClasspath.length + 1]; + System.arraycopy(referenceBootClasspath, 0, referenceClasspath, 0, + referenceBootClasspath.length); + referenceClasspath[referenceClasspath.length - 1] = libLibRef; + referenceClasspathAsString = AbstractTestTools.getClasspathAsString(referenceClasspath); + } else { + candidateClasspathAsString = candidateBootClasspathAsString; + referenceClasspathAsString = referenceBootClasspathAsString; + } + + File jarjarRules = getJarjarRules(); + List<File> proguargFlags = getProguardFlags(); + + File testBinaryDir = AbstractTestTools.createTempDir(); + File testBinary = new File(testBinaryDir, candidateTestTools.getBinaryFileName()); + if (jarjarRules != null) { + candidateTestTools.setJarjarRules(jarjarRules); + } + candidateTestTools.addProguardFlags(proguargFlags.toArray(new File [proguargFlags.size()])); + candidateTestTools.srcToExe(candidateClasspathAsString, testBinaryDir, getSrcDir()); + + File testLib = + AbstractTestTools.createTempFile("testRef", referenceTestTools.getLibraryExtension()); + referenceTestTools.srcToLib(referenceClasspathAsString, testLib, /* zipFiles = */true, + getSrcDir()); + + // Compile link src + 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()); + } + + // Compile ref part src + List<File> referenceClasspath = new ArrayList<File>(); + for (File f : referenceBootClasspath) { + referenceClasspath.add(f); + } + if (libLibRef != null) { + referenceClasspath.add(libLibRef); + } + if (testLib != null) { + referenceClasspath.add(testLib); + } + referenceClasspathAsString = AbstractTestTools.getClasspathAsString( + referenceClasspath.toArray(new File[referenceClasspath.size()])); + + File refPartBinaryDir = AbstractTestTools.createTempDir(); + File refPartBinary = new File(refPartBinaryDir, referenceTestTools.getBinaryFileName()); + referenceTestTools.srcToExe(referenceClasspathAsString, refPartBinaryDir, getRefSrcDir()); + + List<File> rtClasspath = new ArrayList<File>(); + rtClasspath.add(new File(AbstractTestTools.getJackRootDir(), + "toolchain/jack/jack-tests/prebuilts/core-hostdex.jar")); + rtClasspath.add(new File(AbstractTestTools.getJackRootDir(), + "toolchain/jack/jack-tests/prebuilts/junit4-hostdex.jar")); + if (refPartBinary != null) { + rtClasspath.add(refPartBinary); + } + if (linkBinary != null) { + rtClasspath.add(linkBinary); + } + if (testBinary != null) { + rtClasspath.add(testBinary); + } + if (libBinaryRef != null) { + rtClasspath.add(libBinaryRef); + } + + // Run JUnit on runtime env(s) + runOnRuntimeEnvironments(jUnitClasses, testProperties, + rtClasspath.toArray(new File[rtClasspath.size()])); + } + + private static void runOnRuntimeEnvironments(@Nonnull List<String> jUnitClasses, + @Nonnull Properties testProperties, @Nonnull File... classpathFiles) throws Exception { + List<RuntimeRunner> runnerList = AbstractTestTools.listRuntimeTestRunners(testProperties); + 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]), + classpathFiles)); + } + } + + @Nonnull + private static final String[] getRuntimeArgs(@Nonnull String rtName, + @Nonnull Properties properties) { + + String args = properties.getProperty("rt.args." + rtName); + List<String> result = new ArrayList<String>(0); + if (args != null) { + for (String arg : Splitter.on(CharMatcher.WHITESPACE).split(args)) { + result.add(arg); + } + } + return result.toArray(new String[result.size()]); + } + + private void loadTestProperties(@Nonnull Properties properties) throws FileNotFoundException, + IOException { + File[] propertyFile = getDirectoryOrFile(propertyFileName); + if (propertyFile.length != 0) { + if (baseDirs.size() > 1) { + throw new AssertionError("Non regression test found"); + } + if (propertyFile[0].exists()) { + properties.load(new FileInputStream(propertyFile[0])); + } + } + } + + @Nonnull + private File[] getSrcDir() { + return getDirectoryOrFile(srcDirName); + } + + @Nonnull + private File[] getLibSrc() { + return getDirectoryOrFile(libDirName); + } + + @Nonnull + private File[] getLinkSrc() { + File[] result = getDirectoryOrFile(linkDirName); + if (result.length != 0 && baseDirs.size() > 1) { + throw new AssertionError("Not a regression test"); + } + return result; + } + + @Nonnull + private File[] getRefSrcDir() { + return getDirectoryOrFile(refDirName); + } + + @CheckForNull + private File getJarjarRules() { + File[] result = getDirectoryOrFile(jarjarRulesFileName); + if (result.length != 0) { + if (baseDirs.size() > 1) { + throw new AssertionError("Not a regression test"); + } + return result[0]; + } + return null; + } + + @Nonnull + private List<File> getProguardFlags() { + List<File> result = new ArrayList<File>(); + if (proguardFlagsFileNames != null) { + for (String s : proguardFlagsFileNames) { + File[] f = getDirectoryOrFile(s); + if (f.length != 0 && f[0].exists()) { + result.add(f[0]); + } + } + } + + if (!result.isEmpty() && baseDirs.size() > 1) { + throw new AssertionError("Not a regression test"); + } + + return result; + } + + @Nonnull + private File[] getDirectoryOrFile(@CheckForNull String name) { + List<File> result = new ArrayList<File>(); + if (name != null) { + for (File f : baseDirs) { + File absFile = new File(f, name); + if (absFile.exists()) { + result.add(absFile); + } + } + } + return result.toArray(new File[result.size()]); + } +} diff --git a/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java b/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java new file mode 100644 index 0000000..72d9108 --- /dev/null +++ b/jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java @@ -0,0 +1,166 @@ +/* + * 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 com.android.jack.test.comparator.Comparator; +import com.android.jack.test.comparator.ComparatorDex; +import com.android.jack.test.toolchain.AbstractTestTools; +import com.android.jack.test.toolchain.AndroidToolchain; + +import java.io.File; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * This class is a {@link GenericComparisonTestHelper} where the two compilers perform + * a source-to-dex compilation. + */ +public class SourceToDexComparisonTestHelper extends GenericComparisonTestHelper { + + @Nonnull + private File candidateDexDir; + @Nonnull + protected File candidateDex; + @Nonnull + private File refDexDir; + @Nonnull + protected File refDex; + + @Nonnull + private File[] candidateClasspath; + @Nonnull + private File[] referenceClasspath; + + @Nonnull + private File fileOrSourceList; + + @CheckForNull + private File jarjarRulesFile = null; + @Nonnull + private File[] proguardFlagFiles = new File[0]; + + @Nonnull + private AndroidToolchain candidateTestTools; + @Nonnull + private AndroidToolchain referenceTestTools; + + protected boolean withDebugInfos = false; + + public SourceToDexComparisonTestHelper(@Nonnull File fileOrSourceList) throws Exception { + + this.fileOrSourceList = fileOrSourceList; + + candidateTestTools = getCandidateToolchain(); + referenceTestTools = getReferenceToolchain(); + + candidateClasspath = candidateTestTools.getDefaultBootClasspath(); + referenceClasspath = referenceTestTools.getDefaultBootClasspath(); + + candidateDexDir = AbstractTestTools.createTempDir(); + refDexDir = AbstractTestTools.createTempDir(); + + candidateDex = new File(candidateDexDir, candidateTestTools.getBinaryFileName()); + refDex = new File(refDexDir, referenceTestTools.getBinaryFileName()); + } + + @Nonnull + protected AndroidToolchain getCandidateToolchain() { + return AbstractTestTools.getCandidateToolchain(AndroidToolchain.class); + } + + @Nonnull + protected AndroidToolchain getReferenceToolchain() { + return AbstractTestTools.getReferenceToolchain(AndroidToolchain.class); + } + + @Nonnull + public SourceToDexComparisonTestHelper setCandidateTestTools( + @Nonnull AndroidToolchain candidateTestTools) { + this.candidateTestTools = candidateTestTools; + return this; + } + + @Nonnull + public SourceToDexComparisonTestHelper setReferenceTestTools( + @Nonnull AndroidToolchain referenceTestTools) { + this.referenceTestTools = referenceTestTools; + return this; + } + + @Nonnull + public SourceToDexComparisonTestHelper setCandidateClasspath(@Nonnull File[] classpath) { + candidateClasspath = classpath; + return this; + } + + @Nonnull + public SourceToDexComparisonTestHelper setReferenceClasspath(@Nonnull File[] classpath) { + referenceClasspath = classpath; + return this; + } + + @Nonnull + public SourceToDexComparisonTestHelper setWithDebugInfo(boolean withDebugInfo) { + this.withDebugInfos = withDebugInfo; + return this; + } + + @Nonnull + public Comparator createDexFileComparator() { + ComparatorDex comparator = new ComparatorDex(candidateDex, refDex); + comparator.setWithDebugInfo(withDebugInfos); + comparator.setStrict(false); + comparator.setCompareDebugInfoBinary(false); + comparator.setCompareInstructionNumber(false); + comparator.setInstructionNumberTolerance(0f); + return comparator; + } + + @Nonnull + public SourceToDexComparisonTestHelper setJarjarRulesFile(@Nonnull File jarjarRulesFile) { + this.jarjarRulesFile = jarjarRulesFile; + return this; + } + + @Nonnull + public SourceToDexComparisonTestHelper setProguardFlags(@Nonnull File[] proguardFlags) { + this.proguardFlagFiles = proguardFlags; + return this; + } + + @Override + @Nonnull + protected void executeCandidateToolchain() throws Exception { + if (jarjarRulesFile != null) { + candidateTestTools.setJarjarRules(jarjarRulesFile); + } + candidateTestTools.addProguardFlags(proguardFlagFiles).srcToExe( + AbstractTestTools.getClasspathAsString(candidateClasspath), candidateDexDir, + fileOrSourceList); + } + + @Override + @Nonnull + protected void executeReferenceToolchain() throws Exception { + if (jarjarRulesFile != null) { + referenceTestTools.setJarjarRules(jarjarRulesFile); + } + referenceTestTools.addProguardFlags(proguardFlagFiles).srcToExe( + AbstractTestTools.getClasspathAsString(referenceClasspath), refDexDir, fileOrSourceList); + } +} |