Use gradle build instead of ant one for android test module
This commit is contained in:
@@ -8,5 +8,5 @@
|
|||||||
# For customization when using a Version Control System, please read the
|
# For customization when using a Version Control System, please read the
|
||||||
# header note.
|
# header note.
|
||||||
#sdk.dir=compiler/android-tests/android-module/android-sdk/android-sdk-windows
|
#sdk.dir=compiler/android-tests/android-module/android-sdk/android-sdk-windows
|
||||||
#sdk.dir.relative=android-sdk/android-sdk-windows
|
sdk.dir=../../../android.tests.dependencies/android-sdk
|
||||||
|
|
||||||
|
|||||||
+71
-139
@@ -19,25 +19,27 @@ package org.jetbrains.kotlin.android.tests;
|
|||||||
import com.intellij.util.PlatformUtils;
|
import com.intellij.util.PlatformUtils;
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.android.tests.ant.AntRunner;
|
import org.jetbrains.kotlin.android.tests.ant.AntRunner;
|
||||||
import org.jetbrains.kotlin.android.tests.download.SDKDownloader;
|
import org.jetbrains.kotlin.android.tests.download.SDKDownloader;
|
||||||
import org.jetbrains.kotlin.android.tests.emulator.Emulator;
|
import org.jetbrains.kotlin.android.tests.emulator.Emulator;
|
||||||
|
import org.jetbrains.kotlin.android.tests.gradle.GradleRunner;
|
||||||
import org.jetbrains.kotlin.android.tests.run.PermissionManager;
|
import org.jetbrains.kotlin.android.tests.run.PermissionManager;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.ArrayList;
|
||||||
import java.util.regex.Matcher;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class CodegenTestsOnAndroidRunner {
|
public class CodegenTestsOnAndroidRunner {
|
||||||
private static final Pattern ERROR_IN_TEST_OUTPUT_PATTERN =
|
|
||||||
Pattern.compile("([\\s]+at .*| Caused .*| java.lang.RuntimeException: File: .*|[\\s]+\\.\\.\\. .* more| Error in .*)");
|
|
||||||
private static final Pattern NUMBER_OF_TESTS_IF_FAILED = Pattern.compile("Tests run: ([0-9]*), Failures: ([0-9]*), Errors: ([0-9]*)");
|
|
||||||
private static final Pattern NUMBER_OF_TESTS_OK = Pattern.compile(" OK \\(([0-9]*) tests\\)");
|
|
||||||
|
|
||||||
private final PathManager pathManager;
|
private final PathManager pathManager;
|
||||||
|
|
||||||
@@ -53,123 +55,22 @@ public class CodegenTestsOnAndroidRunner {
|
|||||||
TestSuite suite = new TestSuite("MySuite");
|
TestSuite suite = new TestSuite("MySuite");
|
||||||
|
|
||||||
String resultOutput = runTests();
|
String resultOutput = runTests();
|
||||||
if (resultOutput == null) return suite;
|
|
||||||
|
|
||||||
//Fix problem with exception parsing cause 'at' pattern
|
String reportFolder = pathManager.getTmpFolder() + "/build/outputs/androidTest-results/connected";
|
||||||
resultOutput = resultOutput.replaceAll("\\[checkenv\\] Installed at", "[checkenv] Installed_at");
|
try {
|
||||||
|
List<TestCase> testCases = parseSingleReportInFolder(reportFolder);
|
||||||
// Test name -> stackTrace
|
for (TestCase aCase : testCases) {
|
||||||
Map<String, String> resultMap = parseOutputForFailedTests(resultOutput);
|
suite.addTest(aCase);
|
||||||
final Statistics statistics;
|
}
|
||||||
|
Assert.assertNotEquals("There is no test results in report", 0, testCases.size());
|
||||||
// If map is empty => there are no failed tests
|
|
||||||
if (resultMap.isEmpty()) {
|
|
||||||
statistics = parseOutputForTestsNumberIfTestsPassed(resultOutput);
|
|
||||||
}
|
}
|
||||||
else {
|
catch (Exception e) {
|
||||||
statistics = parseOutputForTestsNumberIfThereIsFailedTests(resultOutput);
|
throw new RuntimeException("Can't parse test results in " + reportFolder +"\n" + resultOutput);
|
||||||
|
|
||||||
for (final Map.Entry<String, String> entry : resultMap.entrySet()) {
|
|
||||||
|
|
||||||
suite.addTest(new TestCase("run") {
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return entry.getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void runTest() throws Throwable {
|
|
||||||
Assert.fail(entry.getValue() + "See more information in log above.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.assertNotNull("Cannot parse number of failed tests from final line", statistics);
|
|
||||||
Assert.assertEquals("Number of stackTraces != failed tests on the final line", resultMap.size(),
|
|
||||||
statistics.failed + statistics.errors);
|
|
||||||
|
|
||||||
suite.addTest(new TestCase("run") {
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "testAll: Total: " + statistics.total + ", Failures: " + statistics.failed + ", Errors: " + statistics.errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void runTest() throws Throwable {
|
|
||||||
Assert.assertTrue(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Output example:
|
|
||||||
[exec] Error in testKt344:
|
|
||||||
[exec] java.lang.RuntimeException: File: compiler\testData\codegen\box\regressions\kt344.kt
|
|
||||||
[exec] at org.jetbrains.kotlin.android.tests.AbstractCodegenTestCaseOnAndroid.invokeBoxMethod(AbstractCodegenTestCaseOnAndroid.java:38)
|
|
||||||
[exec] at org.jetbrains.kotlin.android.tests.CodegenTestCaseOnAndroid.testKt344(CodegenTestCaseOnAndroid.java:595)
|
|
||||||
[exec] at java.lang.reflect.Method.invokeNative(Native Method)
|
|
||||||
[exec] at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
|
|
||||||
[exec] Caused by: java.lang.reflect.InvocationTargetException
|
|
||||||
[exec] at java.lang.reflect.Method.invokeNative(Native Method)
|
|
||||||
[exec] at org.jetbrains.kotlin.android.tests.AbstractCodegenTestCaseOnAndroid.invokeBoxMethod(AbstractCodegenTestCaseOnAndroid.java:35)
|
|
||||||
[exec] ... 13 more
|
|
||||||
[exec] Caused by: java.lang.VerifyError: compiler_testData_codegen_box_regressions_kt344_kt.Compiler_testData_codegen_box_regressions_kt344_ktPackage$t6$foo$1
|
|
||||||
[exec] at compiler_testData_codegen_box_regressions_kt344_kt.Compiler_testData_codegen_box_regressions_kt344_ktPackage.t6(dummy.kt:94)
|
|
||||||
[exec] at compiler_testData_codegen_box_regressions_kt344_kt.Compiler_testData_codegen_box_regressions_kt344_ktPackage.box(dummy.kt:185)
|
|
||||||
[exec] ... 16 more
|
|
||||||
[exec] ...............
|
|
||||||
[exec] Error in testKt529:
|
|
||||||
*/
|
|
||||||
private static Map<String, String> parseOutputForFailedTests(@NotNull String output) {
|
|
||||||
Map<String, String> result = new HashMap<String, String>();
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
String failedTestNamePrefix = " Error in ";
|
|
||||||
String lastFailedTestName = "";
|
|
||||||
Matcher matcher = ERROR_IN_TEST_OUTPUT_PATTERN.matcher(output);
|
|
||||||
while (matcher.find()) {
|
|
||||||
String groupValue = matcher.group();
|
|
||||||
if (groupValue.startsWith(failedTestNamePrefix)) {
|
|
||||||
if (builder.length() > 0) {
|
|
||||||
result.put(lastFailedTestName, builder.toString());
|
|
||||||
builder.delete(0, builder.length());
|
|
||||||
}
|
|
||||||
lastFailedTestName = groupValue.substring(failedTestNamePrefix.length());
|
|
||||||
}
|
|
||||||
builder.append(groupValue);
|
|
||||||
builder.append("\n");
|
|
||||||
}
|
|
||||||
if (builder.length() > 0) {
|
|
||||||
result.put(lastFailedTestName, builder.toString());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//[exec] Tests run: 225, Failures: 0, Errors: 2
|
|
||||||
@Nullable
|
|
||||||
private static Statistics parseOutputForTestsNumberIfThereIsFailedTests(String output) {
|
|
||||||
Matcher matcher = NUMBER_OF_TESTS_IF_FAILED.matcher(output);
|
|
||||||
if (matcher.find()) {
|
|
||||||
return new Statistics(Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)),
|
|
||||||
Integer.parseInt(matcher.group(3)));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//[exec] OK (223 tests)
|
|
||||||
@Nullable
|
|
||||||
private static Statistics parseOutputForTestsNumberIfTestsPassed(String output) {
|
|
||||||
Matcher matcher = NUMBER_OF_TESTS_OK.matcher(output);
|
|
||||||
if (matcher.find()) {
|
|
||||||
return new Statistics(Integer.parseInt(matcher.group(1)), 0, 0);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String runTests() {
|
public String runTests() {
|
||||||
File rootForAndroidDependencies = new File(pathManager.getDependenciesRoot());
|
File rootForAndroidDependencies = new File(pathManager.getDependenciesRoot());
|
||||||
@@ -178,27 +79,26 @@ public class CodegenTestsOnAndroidRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDKDownloader downloader = new SDKDownloader(pathManager);
|
SDKDownloader downloader = new SDKDownloader(pathManager);
|
||||||
Emulator emulator = new Emulator(pathManager, Emulator.ARM);
|
|
||||||
AntRunner antRunner = new AntRunner(pathManager);
|
|
||||||
downloader.downloadAll();
|
downloader.downloadAll();
|
||||||
downloader.unzipAll();
|
downloader.unzipAll();
|
||||||
|
PermissionManager.setPermissions(pathManager);
|
||||||
|
|
||||||
|
AntRunner antRunner = new AntRunner(pathManager);
|
||||||
|
antRunner.packLibraries();
|
||||||
|
Emulator emulator = new Emulator(pathManager, Emulator.ARM);
|
||||||
|
GradleRunner gradleRunner = new GradleRunner(pathManager);
|
||||||
|
gradleRunner.clean();
|
||||||
|
gradleRunner.build();
|
||||||
|
|
||||||
|
emulator.createEmulator();
|
||||||
|
|
||||||
String platformPrefixProperty = System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, "Idea");
|
String platformPrefixProperty = System.setProperty(PlatformUtils.PLATFORM_PREFIX_KEY, "Idea");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PermissionManager.setPermissions(pathManager);
|
|
||||||
|
|
||||||
antRunner.packLibraries();
|
|
||||||
|
|
||||||
emulator.createEmulator();
|
|
||||||
emulator.startEmulator();
|
emulator.startEmulator();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
emulator.waitEmulatorStart();
|
emulator.waitEmulatorStart();
|
||||||
antRunner.cleanOutput();
|
return gradleRunner.connectedDebugAndroidTest();
|
||||||
antRunner.compileSources();
|
|
||||||
antRunner.installApplicationOnEmulator();
|
|
||||||
return antRunner.runTestsOnEmulator();
|
|
||||||
}
|
}
|
||||||
catch (RuntimeException e) {
|
catch (RuntimeException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -223,15 +123,47 @@ public class CodegenTestsOnAndroidRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Statistics {
|
private static List<TestCase> parseSingleReportInFolder(String reportFolder) throws
|
||||||
public final int total;
|
IOException,
|
||||||
public final int errors;
|
SAXException,
|
||||||
public final int failed;
|
ParserConfigurationException {
|
||||||
|
File folder = new File(reportFolder);
|
||||||
|
File[] files = folder.listFiles();
|
||||||
|
assert files != null;
|
||||||
|
assert files.length == 1;
|
||||||
|
File reportFile = files[0];
|
||||||
|
|
||||||
private Statistics(int total, int failed, int errors) {
|
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||||
this.total = total;
|
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||||
this.failed = failed;
|
Document doc = dBuilder.parse(reportFile);
|
||||||
this.errors = errors;
|
Element root = doc.getDocumentElement();
|
||||||
|
NodeList testCases = root.getElementsByTagName("testcase");
|
||||||
|
List<TestCase> result = new ArrayList(testCases.getLength());
|
||||||
|
|
||||||
|
for (int i = 0; i < testCases.getLength(); i++) {
|
||||||
|
Element item = (Element) testCases.item(i);
|
||||||
|
final NodeList failure = item.getElementsByTagName("failure");
|
||||||
|
String name = item.getAttribute("name");
|
||||||
|
String clazz = item.getAttribute("classname");
|
||||||
|
|
||||||
|
if (failure.getLength() == 0) {
|
||||||
|
result.add(new TestCase(name) {
|
||||||
|
@Override
|
||||||
|
protected void runTest() throws Throwable {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.add(new TestCase(name) {
|
||||||
|
@Override
|
||||||
|
protected void runTest() throws Throwable {
|
||||||
|
Assert.fail(failure.item(0).getTextContent());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ public class SDKDownloader {
|
|||||||
|
|
||||||
private void downloadAbi() {
|
private void downloadAbi() {
|
||||||
download("http://dl.google.com/android/repository/sys-img/android/sysimg_armv7a-" + ANDROID_VERSION + "_r04.zip", armImage); //Same for all platforms
|
download("http://dl.google.com/android/repository/sys-img/android/sysimg_armv7a-" + ANDROID_VERSION + "_r04.zip", armImage); //Same for all platforms
|
||||||
download("https://dl.google.com/android/repository/sys-img/android/sysimg_x86-" + ANDROID_VERSION + "_r02.zip", x86Image); //Same for all platforms
|
download("http://dl.google.com/android/repository/sys-img/android/sysimg_x86-" + ANDROID_VERSION + "_r02.zip", x86Image); //Same for all platforms
|
||||||
}
|
}
|
||||||
|
|
||||||
public void downloadPlatformTools() {
|
public void downloadPlatformTools() {
|
||||||
|
|||||||
Reference in New Issue
Block a user