Skip to content

Commit

Permalink
Caffeine junit & testng suites seem to pass
Browse files Browse the repository at this point in the history
  • Loading branch information
lihaoyi committed Apr 9, 2018
1 parent db8d967 commit 11122c4
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 107 deletions.
1 change: 1 addition & 0 deletions ci/test-mill-2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ set -eux
# Starting from scratch...
git clean -xdf

mill testng.publishLocal # Needed for CaffeineTests
# Run tests
mill integration.test "mill.integration.local.{AcyclicTests,AmmoniteTests,CaffeineTests}"
2 changes: 2 additions & 0 deletions integration/test/resources/caffeine/build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ trait CaffeineModule extends MavenModule{
def testFrameworks = Seq("com.novocode.junit.JUnitFramework")
def ivyDeps = Agg(
ivy"com.novocode:junit-interface:0.11",
ivy"com.lihaoyi:mill-testng:0.1.7-79-91f790",
libraries.guava,
testLibraries.mockito,
testLibraries.hamcrest,
Expand Down Expand Up @@ -73,6 +74,7 @@ object caffeine extends CaffeineModule {
}

object test extends Tests{
def testFrameworks = Seq("mill.testng.TestNGFramework")
def ivyDeps = super.ivyDeps() ++ Agg(
libraries.ycsb,
libraries.fastutil,
Expand Down
20 changes: 15 additions & 5 deletions integration/test/src/mill/integration/CaffeineTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ class CaffeineTests(fork: Boolean) extends IntegrationTestSuite("MILL_CAFFEINE_R
// Caffeine only can build using Java 9 or up. Java 8 results in weird
// type inference issues during the compile
if (mill.client.ClientServer.isJava9OrAbove){
assert(eval(s"caffeine.test.compile"))
assert(eval(s"caffeine.test"))
assert(eval(s"guava.test.compile"))
assert(eval(s"jcache.test.compile"))
assert(eval(s"simulator.test.compile"))
assert(eval("caffeine.test.compile"))
assert(eval("guava.test"))
val suites = Seq(
"com.github.benmanes.caffeine.SingleConsumerQueueTest",
"com.github.benmanes.caffeine.cache.AsyncTest",
"com.github.benmanes.caffeine.cache.CaffeineTest",
"com.github.benmanes.caffeine.cache.TimerWheelTest"
)
assert(eval(
"caffeine.test",
"-testclass", suites.mkString(",")
))
assert(eval("guava.test.compile"))
assert(eval("jcache.test.compile"))
assert(eval("simulator.test.compile"))
}
}

Expand Down
4 changes: 2 additions & 2 deletions scalalib/src/mill/scalalib/Lib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,12 @@ object Lib{
!cls.isInterface &&
(f.isModule == cls.getName.endsWith("$")) &&
cl.loadClass(f.superclassName()).isAssignableFrom(cls) &&
cls.getConstructors.count(c => c.getParameterCount == 0 && Modifier.isPublic(c.getModifiers)) == 1
(f.isModule || cls.getConstructors.count(c => c.getParameterCount == 0 && Modifier.isPublic(c.getModifiers)) == 1)

case f: AnnotatedFingerprint =>
val annotationCls = cl.loadClass(f.annotationName()).asInstanceOf[Class[Annotation]]
(f.isModule == cls.getName.endsWith("$")) &&
cls.getConstructors.count(c => c.getParameterCount == 0 && Modifier.isPublic(c.getModifiers)) == 1 &&
(f.isModule || cls.getConstructors.count(c => c.getParameterCount == 0 && Modifier.isPublic(c.getModifiers)) == 1)
(
cls.isAnnotationPresent(annotationCls) ||
cls.getDeclaredMethods.exists(_.isAnnotationPresent(annotationCls))
Expand Down
40 changes: 0 additions & 40 deletions testng/src/mill/testng/EventRecorder.java

This file was deleted.

7 changes: 2 additions & 5 deletions testng/src/mill/testng/TestNGFramework.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ public Fingerprint[] fingerprints() {

@Override
public Runner runner(String[] args, String[] remoteArgs, ClassLoader classLoader) {
return new TestNGRunner(args, remoteArgs, classLoader, sharedState);
return new TestNGRunner(args, remoteArgs, classLoader);
}


private TestRunState sharedState = new TestRunState();
}

class Annotated implements AnnotatedFingerprint{
Expand All @@ -29,4 +26,4 @@ public Annotated(String annotationName) {
}
public String annotationName(){return annotationName;}
public boolean isModule(){return false;}
}
}
80 changes: 56 additions & 24 deletions testng/src/mill/testng/TestNGInstance.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,74 @@
package mill.testng;


import org.testng.*;
import sbt.testing.EventHandler;
import sbt.testing.Logger;

import org.testng.CommandLineArgs;
import org.testng.TestNG;

import com.beust.jcommander.JCommander;

public class TestNGInstance {
Logger[] loggers;
ConfigurableTestNG configurableTestNG = new ConfigurableTestNG();
public TestNGInstance(Logger[] loggers){
this.loggers = loggers;
import java.net.URLClassLoader;
import java.util.Arrays;

class TestNGListener implements ITestListener{
EventHandler basket;
String lastName = "";
public TestNGListener(EventHandler basket){
this.basket = basket;
}
TestNGInstance loadingClassesFrom(ClassLoader testClassLoader){
configurableTestNG.addClassLoader(testClassLoader);
return TestNGInstance.this;
public void onTestStart(ITestResult iTestResult) {
String newName = iTestResult.getTestClass().getName() + " " + iTestResult.getName() + " ";
if(!newName.equals(lastName)){
if (!lastName.equals("")){
System.out.println();
}
lastName = newName;
System.out.print(lastName);
}
}
TestNGInstance using(String[] testOptions){
CommandLineArgs args = new CommandLineArgs();
new JCommander(args, testOptions); // args is an output parameter of the constructor!
configurableTestNG.configure(args);
return TestNGInstance.this;

public void onTestSuccess(ITestResult iTestResult) {
System.out.print('+');
basket.handle(ResultEvent.success(iTestResult));
}

public void onTestFailure(ITestResult iTestResult) {
System.out.print('X');
basket.handle(ResultEvent.failure(iTestResult));
}

TestNGInstance storingEventsIn(EventRecorder basket){
configurableTestNG.addListener(basket);
return TestNGInstance.this;
public void onTestSkipped(ITestResult iTestResult) {
System.out.print('-');
basket.handle(ResultEvent.skipped(iTestResult));
}

static void start(TestNGInstance testNG){
testNG.configurableTestNG.run();
public void onTestFailedButWithinSuccessPercentage(ITestResult iTestResult) {
basket.handle(ResultEvent.failure(iTestResult));
}
static TestNGInstance loggingTo(Logger[] loggers){ return new TestNGInstance(loggers); }

public void onStart(ITestContext iTestContext) {}

public void onFinish(ITestContext iTestContext) {}
}

public class TestNGInstance extends TestNG{
public TestNGInstance(Logger[] loggers,
ClassLoader testClassLoader,
String[] testOptions,
String suiteName,
EventHandler eventHandler) {
addClassLoader(testClassLoader);

class ConfigurableTestNG extends TestNG{ // the TestNG method we need is protected
public void configure(CommandLineArgs args) { super.configure(args); }
try{
this.setTestClasses(new Class[]{Class.forName(suiteName)});
}catch(ClassNotFoundException e){
throw new RuntimeException(e);
}
this.addListener(new TestNGListener(eventHandler));
CommandLineArgs args = new CommandLineArgs();
new JCommander(args, testOptions); // args is an output parameter of the constructor!
configure(args);
}
}


35 changes: 14 additions & 21 deletions testng/src/mill/testng/TestNGRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import sbt.testing.*;

import java.util.Arrays;
import java.util.Collections;

class TestNGTask implements Task {

TaskDef taskDef;
Expand All @@ -18,24 +21,14 @@ public String[] tags() {

@Override
public Task[] execute(EventHandler eventHandler, Logger[] loggers) {
if (TestRunState.permissionToExecute.tryAcquire()) {
TestNGInstance.start(
TestNGInstance.loggingTo(loggers)
.loadingClassesFrom(runner.testClassLoader)
.using(runner.args())
.storingEventsIn(runner.state.recorder)
);

runner.state.testCompletion.countDown();
}

try{
runner.state.testCompletion.await();
}catch(InterruptedException e){
throw new RuntimeException(e);
}

runner.state.recorder.replayTo(eventHandler, taskDef.fullyQualifiedName(), loggers);
System.out.println("Executing " + taskDef.fullyQualifiedName());
new TestNGInstance(
loggers,
runner.testClassLoader,
runner.args(),
taskDef.fullyQualifiedName(),
eventHandler
).run();
return new Task[0];
}

Expand All @@ -44,19 +37,19 @@ public TaskDef taskDef() {
return taskDef;
}
}

public class TestNGRunner implements Runner {
ClassLoader testClassLoader;
TestRunState state;
String[] args;
String[] remoteArgs;
public TestNGRunner(String[] args, String[] remoteArgs, ClassLoader testClassLoader, TestRunState state) {
public TestNGRunner(String[] args, String[] remoteArgs, ClassLoader testClassLoader) {
this.testClassLoader = testClassLoader;
this.state = state;
this.args = args;
this.remoteArgs = remoteArgs;
}

public Task[] tasks(TaskDef[] taskDefs) {
System.out.println("TestNGRunner#tasks " + Arrays.toString(taskDefs));
Task[] out = new Task[taskDefs.length];
for (int i = 0; i < taskDefs.length; i += 1) {
out[i] = new TestNGTask(taskDefs[i], this);
Expand Down
10 changes: 0 additions & 10 deletions testng/src/mill/testng/TestRunState.java

This file was deleted.

0 comments on commit 11122c4

Please sign in to comment.