blob: c244702ff46d61a2237040a72cf0681f033fecca [file] [log] [blame]
/*
* Copyright (C) 2016 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.experimental.incremental;
import com.google.common.io.ByteStreams;
import com.android.jack.frontend.FrontendCompilationException;
import com.android.jack.library.FileType;
import com.android.jack.library.InputJackLibrary;
import com.android.jack.library.LibraryIOException;
import com.android.jack.test.helper.IncrementalTestHelper;
import com.android.jack.test.toolchain.AbstractTestTools;
import com.android.jack.test.toolchain.IToolchain;
import com.android.jack.test.toolchain.IncrementalToolchain;
import com.android.jack.test.toolchain.JackApiToolchainBase;
import com.android.jack.test.toolchain.JackBasedToolchain;
import com.android.jack.test.toolchain.JillBasedToolchain;
import com.android.jack.test.toolchain.TwoStepsToolchain;
import com.android.sched.vfs.InputVFile;
import junit.framework.Assert;
import org.junit.Test;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
/**
* JUnit tests checking errors and incremental support.
*/
public class DependenciesTest017 {
/**
* Check that an incremental build can recover after an exception.
*/
@Test
public void testError1() throws Exception {
IncrementalTestHelper helper =
new IncrementalTestHelper(AbstractTestTools.createTempDir());
File source1 = helper.addJavaFile("jack.source", "Source1.java", "package jack.source; \n"
+ "public class Source1 { \n"
+ "public m(){} }"); // missing return type
helper.addJavaFile("jack.source", "Source2.java", "package jack.source; \n"
+ "public class Source2 extends Source1 { \n"
+ "@Override public void m(){} }");
File outputDex1 = AbstractTestTools.createTempDir();
List<Class<? extends IToolchain>> excludeList = new ArrayList<Class<? extends IToolchain>>(3);
excludeList.add(JillBasedToolchain.class);
excludeList.add(IncrementalToolchain.class);
excludeList.add(TwoStepsToolchain.class);
// API-only because we catch an exception
JackBasedToolchain toolchain =
AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class, excludeList);
File outputJack = AbstractTestTools.createTempFile("output", toolchain.getLibraryExtension());
File[] defaultClasspath = toolchain.getDefaultBootClasspath();
toolchain.setIncrementalFolder(helper.getCompilerStateFolder());
toolchain.setOutputJack(outputJack, /* zipFiles = */ true);
toolchain.setErrorStream(ByteStreams.nullOutputStream()); // ignore stderr
try {
toolchain.addToClasspath(defaultClasspath).srcToExe(outputDex1,
/* zipFiles = */ false, helper.getSourceFolder());
Assert.fail();
} catch (FrontendCompilationException e) {
// expected
}
// check the content of the incremental dir
Assert.assertEquals(0, getCount(helper.getCompilerStateFolder(), FileType.JAYCE));
Thread.sleep(1000);
source1 = helper.addJavaFile("jack.source", "Source1.java", "package jack.source; \n"
+ "public class Source1 { \n"
+ "public void m(){} }");
File outputDex2 = AbstractTestTools.createTempDir();
toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, excludeList);
toolchain.setIncrementalFolder(helper.getCompilerStateFolder());
toolchain.setOutputJack(outputJack, /* zipFiles = */ true);
toolchain.addToClasspath(defaultClasspath).srcToExe(outputDex2,
/* zipFiles = */ false, helper.getSourceFolder());
// check the content of the incremental dir
Assert.assertEquals(2, getCount(helper.getCompilerStateFolder(), FileType.JAYCE));
// check the content of the output jack lib
Assert.assertEquals(2, getCount(outputJack, FileType.JAYCE));
}
/**
* Check that an incremental build can recover after an exception, after a first successful run.
*/
@Test
public void testError2() throws Exception {
IncrementalTestHelper helper =
new IncrementalTestHelper(AbstractTestTools.createTempDir());
File source1 = helper.addJavaFile("jack.source", "Source1.java", "package jack.source; \n"
+ "public class Source1 { \n"
+ "public void m(){} }");
helper.addJavaFile("jack.source", "Source2.java", "package jack.source; \n"
+ "public class Source2 extends Source1 { \n"
+ "@Override public void m(){} }");
helper.addJavaFile("jack.source", "UnrelatedSource.java", "package jack.source; \n"
+ "public class UnrelatedSource { \n"
+ "public void u(){} }");
File outputDex1 = AbstractTestTools.createTempDir();
List<Class<? extends IToolchain>> excludeList = new ArrayList<Class<? extends IToolchain>>(3);
excludeList.add(JillBasedToolchain.class);
excludeList.add(IncrementalToolchain.class);
excludeList.add(TwoStepsToolchain.class);
// API-only because we catch an exception
JackBasedToolchain toolchain =
AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class, excludeList);
File outputJack = AbstractTestTools.createTempFile("output", toolchain.getLibraryExtension());
File[] defaultClasspath = toolchain.getDefaultBootClasspath();
toolchain.setIncrementalFolder(helper.getCompilerStateFolder());
toolchain.setOutputJack(outputJack, /* zipFiles = */ true);
toolchain.addToClasspath(defaultClasspath).srcToExe(outputDex1, /* zipFiles = */ false,
helper.getSourceFolder());
// check the content of the incremental dir
Assert.assertEquals(3, getCount(helper.getCompilerStateFolder(), FileType.JAYCE));
Thread.sleep(1000);
source1 = helper.addJavaFile("jack.source", "Source1.java", "package jack.source; \n"
+ "public class Source1 { \n"
+ "public m(){} }"); // missing return type
File outputDex2 = AbstractTestTools.createTempDir();
toolchain =
AbstractTestTools.getCandidateToolchain(JackApiToolchainBase.class, excludeList);
outputJack = AbstractTestTools.createTempFile("output", toolchain.getLibraryExtension());
toolchain.setIncrementalFolder(helper.getCompilerStateFolder());
toolchain.setOutputJack(outputJack, /* zipFiles = */ true);
toolchain.setErrorStream(ByteStreams.nullOutputStream()); // ignore stderr
try {
toolchain.addToClasspath(defaultClasspath).srcToExe(outputDex2,
/* zipFiles = */ false, helper.getSourceFolder());
Assert.fail();
} catch (FrontendCompilationException e) {
// expected
}
// check the content of the incremental dir
int numJayce = 1; // Source1 was modified and Source2 depends on it so both have been deleted
Assert.assertEquals(numJayce, getCount(helper.getCompilerStateFolder(), FileType.JAYCE));
Thread.sleep(1000);
source1 = helper.addJavaFile("jack.source", "Source1.java", "package jack.source; \n"
+ "public class Source1 { \n"
+ "public void m(){}; public void n(){}; }");
helper.addJavaFile("jack.source", "Source3.java", "package jack.source; \n"
+ "public class Source3 extends Source1 { \n"
+ "@Override public void m(){}; @Override public void n(){}; }");
helper.addJavaFile("jack.source", "Source4.java", "package jack.source; \n"
+ "public class Source4 extends Source2 { \n"
+ "@Override public void m(){};}");
File outputDex3 = AbstractTestTools.createTempDir();
toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class, excludeList);
toolchain.setIncrementalFolder(helper.getCompilerStateFolder());
toolchain.setOutputJack(outputJack, /* zipFiles = */ true);
toolchain.addToClasspath(defaultClasspath).srcToExe(outputDex3,
/* zipFiles = */ false, helper.getSourceFolder());
// check the content of the incremental dir
Assert.assertEquals(5, getCount(helper.getCompilerStateFolder(), FileType.JAYCE));
// check the content of the output jack lib
Assert.assertEquals(5, getCount(outputJack, FileType.JAYCE));
}
@Nonnegative
private int getCount(@Nonnull File lib, @Nonnull FileType fileType) throws LibraryIOException {
int size = 0;
try (InputJackLibrary compilerStateLib = AbstractTestTools.getInputJackLibrary(lib)) {
Iterator<InputVFile> jayceIter = compilerStateLib.iterator(fileType);
while (jayceIter.hasNext()) {
size++;
jayceIter.next();
}
}
return size;
}
}