summaryrefslogtreecommitdiffstats
path: root/jack-tests/src/com/android/jack/test/helper
diff options
context:
space:
mode:
Diffstat (limited to 'jack-tests/src/com/android/jack/test/helper')
-rw-r--r--jack-tests/src/com/android/jack/test/helper/CheckDexStructureTestHelper.java37
-rw-r--r--jack-tests/src/com/android/jack/test/helper/ErrorTestHelper.java75
-rw-r--r--jack-tests/src/com/android/jack/test/helper/GenericComparisonTestHelper.java45
-rw-r--r--jack-tests/src/com/android/jack/test/helper/IncrementalTestHelper.java169
-rw-r--r--jack-tests/src/com/android/jack/test/helper/JackDexMergerTestHelper.java97
-rw-r--r--jack-tests/src/com/android/jack/test/helper/RuntimeTestHelper.java373
-rw-r--r--jack-tests/src/com/android/jack/test/helper/SourceToDexComparisonTestHelper.java166
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);
+ }
+}