mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
TeaVM test runner as a separate mojo
This commit is contained in:
parent
5522f55c68
commit
d007b0c8ac
|
@ -86,9 +86,14 @@
|
|||
<java.util.Locale.available>en, en_US, en_GB, ru, ru_RU</java.util.Locale.available>
|
||||
</properties>
|
||||
<incremental>${teavm.test.incremental}</incremental>
|
||||
<seleniumURL>http://127.0.0.1:4444/wd/hub</seleniumURL>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>run-javascript-tests</id>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
|
|
@ -364,7 +364,8 @@ public class TeaVMTestTool implements BaseTeaVMTool {
|
|||
testClass.getMethods().add(testMethod);
|
||||
|
||||
String debugTable = debugInformationGenerated ? testMethod.getFileName() + ".teavmdbg" : null;
|
||||
cases.add(new TestCase(ref, testMethod.getFileName(), debugTable, testMethod.getExpectedExceptions()));
|
||||
cases.add(new TestCase(ref.toString(), testMethod.getFileName(), debugTable,
|
||||
testMethod.getExpectedExceptions()));
|
||||
++testCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,20 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TestCase {
|
||||
private MethodReference testMethod;
|
||||
private String testMethod;
|
||||
private String testScript;
|
||||
private String debugTable;
|
||||
private List<String> expectedExceptions = new ArrayList<>();
|
||||
|
||||
@JsonCreator
|
||||
public TestCase(
|
||||
@JsonProperty("testMethod") MethodReference testMethod,
|
||||
@JsonProperty("testMethod") String testMethod,
|
||||
@JsonProperty("script") String testScript,
|
||||
@JsonProperty("debugTable") String debugTable,
|
||||
@JsonProperty("expectedExceptions") List<String> expectedExceptions) {
|
||||
|
@ -46,7 +45,7 @@ public class TestCase {
|
|||
}
|
||||
|
||||
@JsonGetter
|
||||
public MethodReference getTestMethod() {
|
||||
public String getTestMethod() {
|
||||
return testMethod;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.teavm.tooling.testing;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -32,15 +33,17 @@ public class TestPlan {
|
|||
@JsonCreator
|
||||
public TestPlan(
|
||||
@JsonProperty("runtimeScript") String runtimeScript,
|
||||
@JsonProperty("groupList") List<TestGroup> groups) {
|
||||
@JsonProperty("groups") List<TestGroup> groups) {
|
||||
this.runtimeScript = runtimeScript;
|
||||
this.groups = Collections.unmodifiableList(new ArrayList<>(groups));
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public String getRuntimeScript() {
|
||||
return runtimeScript;
|
||||
}
|
||||
|
||||
@JsonGetter
|
||||
public List<TestGroup> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
|
|
@ -15,12 +15,15 @@
|
|||
*/
|
||||
package org.teavm.maven;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
|
@ -42,6 +45,7 @@ import org.teavm.testing.JUnitTestAdapter;
|
|||
import org.teavm.testing.TestAdapter;
|
||||
import org.teavm.tooling.TeaVMToolException;
|
||||
import org.teavm.tooling.testing.TeaVMTestTool;
|
||||
import org.teavm.tooling.testing.TestPlan;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -84,11 +88,6 @@ public class BuildJavascriptTestMojo extends AbstractJavascriptMojo {
|
|||
@Parameter
|
||||
private boolean incremental;
|
||||
|
||||
@Parameter
|
||||
private URL seleniumURL;
|
||||
|
||||
private SeleniumTestRunner seleniumRunner;
|
||||
|
||||
private TeaVMTestTool tool = new TeaVMTestTool();
|
||||
|
||||
@Override
|
||||
|
@ -111,29 +110,19 @@ public class BuildJavascriptTestMojo extends AbstractJavascriptMojo {
|
|||
if (additionalScripts != null) {
|
||||
tool.getAdditionalScripts().addAll(Arrays.asList(additionalScripts));
|
||||
}
|
||||
tool.generate();
|
||||
writePlan(tool.generate());
|
||||
} catch (TeaVMToolException e) {
|
||||
throw new MojoFailureException("Error occured generating JavaScript files", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processReport(List<TestResult> report) throws MojoExecutionException {
|
||||
if (report.isEmpty()) {
|
||||
getLog().info("No tests ran");
|
||||
return;
|
||||
}
|
||||
|
||||
int failedTests = 0;
|
||||
for (TestResult result : report) {
|
||||
if (result.getStatus() != TestStatus.PASSED) {
|
||||
failedTests++;
|
||||
}
|
||||
}
|
||||
|
||||
if (failedTests > 0) {
|
||||
throw new MojoExecutionException(failedTests + " of " + report.size() + " test(s) failed");
|
||||
} else {
|
||||
getLog().info("All of " + report.size() + " tests successfully passed");
|
||||
private void writePlan(TestPlan plan) throws MojoExecutionException {
|
||||
File file = new File(targetDirectory, "plan.json");
|
||||
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.writeValue(writer, plan);
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Error writing test plan", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,17 +15,71 @@
|
|||
*/
|
||||
package org.teavm.maven;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.teavm.tooling.testing.TestPlan;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
@Mojo(name = "run-tests", defaultPhase = LifecyclePhase.TEST)
|
||||
public class RunTestsMojo {
|
||||
@Parameter(defaultValue = "${project.build.directory}/javascript-tests")
|
||||
private File targetDirectory;
|
||||
@Mojo(name = "test", defaultPhase = LifecyclePhase.TEST)
|
||||
public class RunTestsMojo extends AbstractMojo {
|
||||
@Parameter(defaultValue = "${project.build.directory}/javascript-test")
|
||||
private File testDirectory;
|
||||
|
||||
@Parameter
|
||||
private URL seleniumURL;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
SeleniumTestRunner runner = new SeleniumTestRunner();
|
||||
runner.setLog(getLog());
|
||||
runner.setDirectory(testDirectory);
|
||||
runner.setUrl(seleniumURL);
|
||||
|
||||
TestPlan plan;
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
File file = new File(testDirectory, "plan.json");
|
||||
try (Reader reader = new InputStreamReader(new FileInputStream(file), "UTF-8")) {
|
||||
plan = mapper.readValue(reader, TestPlan.class);
|
||||
} catch (IOException e) {
|
||||
throw new MojoExecutionException("Error reading test plan", e);
|
||||
}
|
||||
|
||||
runner.run(plan);
|
||||
processReport(runner.getReport());
|
||||
}
|
||||
|
||||
private void processReport(List<TestResult> report) throws MojoExecutionException {
|
||||
if (report.isEmpty()) {
|
||||
getLog().info("No tests ran");
|
||||
return;
|
||||
}
|
||||
|
||||
int failedTests = 0;
|
||||
for (TestResult result : report) {
|
||||
if (result.getStatus() != TestStatus.PASSED) {
|
||||
failedTests++;
|
||||
}
|
||||
}
|
||||
|
||||
if (failedTests > 0) {
|
||||
throw new MojoExecutionException(failedTests + " of " + report.size() + " test(s) failed");
|
||||
} else {
|
||||
getLog().info("All of " + report.size() + " tests successfully passed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.openqa.selenium.JavascriptExecutor;
|
|||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebDriverException;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.tooling.testing.TestCase;
|
||||
import org.teavm.tooling.testing.TestGroup;
|
||||
import org.teavm.tooling.testing.TestPlan;
|
||||
|
@ -48,7 +49,7 @@ public class SeleniumTestRunner {
|
|||
private int numThreads = 1;
|
||||
private ThreadLocal<WebDriver> webDriver = new ThreadLocal<>();
|
||||
private BlockingQueue<Runnable> seleniumTaskQueue = new LinkedBlockingQueue<>();
|
||||
private CountDownLatch latch = new CountDownLatch(1);
|
||||
private CountDownLatch latch;
|
||||
private volatile boolean seleniumStopped = false;
|
||||
private Log log;
|
||||
private List<TestResult> report = new CopyOnWriteArrayList<>();
|
||||
|
@ -95,15 +96,16 @@ public class SeleniumTestRunner {
|
|||
}
|
||||
|
||||
private void initSelenium() {
|
||||
latch = new CountDownLatch(numThreads);
|
||||
for (int i = 0; i < numThreads; ++i) {
|
||||
new Thread(() -> {
|
||||
ChromeDriver driver = new ChromeDriver();
|
||||
webDriver.set(driver);
|
||||
localReport.set(new ArrayList<>());
|
||||
while (!seleniumStopped) {
|
||||
while (!seleniumStopped || !seleniumTaskQueue.isEmpty()) {
|
||||
Runnable task;
|
||||
try {
|
||||
task = seleniumTaskQueue.poll(1, TimeUnit.SECONDS);
|
||||
task = seleniumTaskQueue.poll(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
|
@ -113,22 +115,19 @@ public class SeleniumTestRunner {
|
|||
}
|
||||
report.addAll(localReport.get());
|
||||
localReport.remove();
|
||||
webDriver.get().close();
|
||||
webDriver.remove();
|
||||
latch.countDown();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void addSeleniumTask(Runnable runnable) {
|
||||
if (url != null) {
|
||||
seleniumTaskQueue.add(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopSelenium() {
|
||||
addSeleniumTask(() -> {
|
||||
seleniumStopped = true;
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
|
||||
private void waitForCompletion() {
|
||||
|
@ -145,7 +144,7 @@ public class SeleniumTestRunner {
|
|||
|
||||
private void runImpl(String runtimeScript, TestCase testCase) {
|
||||
webDriver.get().manage().timeouts().setScriptTimeout(2, TimeUnit.SECONDS);
|
||||
JavascriptExecutor js = (JavascriptExecutor) webDriver;
|
||||
JavascriptExecutor js = (JavascriptExecutor) webDriver.get();
|
||||
try {
|
||||
String result = (String) js.executeAsyncScript(
|
||||
readResource("teavm-selenium.js"),
|
||||
|
@ -155,15 +154,16 @@ public class SeleniumTestRunner {
|
|||
ObjectMapper mapper = new ObjectMapper();
|
||||
ObjectNode resultObject = (ObjectNode) mapper.readTree(result);
|
||||
String status = resultObject.get("status").asText();
|
||||
MethodReference ref = MethodReference.parse(testCase.getTestMethod());
|
||||
switch (status) {
|
||||
case "ok":
|
||||
log.info("Test passed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.passed(testCase.getTestMethod()));
|
||||
localReport.get().add(TestResult.passed(ref));
|
||||
break;
|
||||
case "exception": {
|
||||
String stack = resultObject.get("stack").asText();
|
||||
log.info("Test failed: " + testCase.getTestMethod());
|
||||
localReport.get().add(TestResult.error(testCase.getTestMethod(), stack));
|
||||
localReport.get().add(TestResult.error(ref, stack));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user