From 11122c48452d40eb32086fa247ce06d5d6f1a789 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Mon, 9 Apr 2018 01:29:14 -0700 Subject: Caffeine junit & testng suites seem to pass --- ci/test-mill-2.sh | 1 + integration/test/resources/caffeine/build.sc | 2 + .../test/src/mill/integration/CaffeineTests.scala | 20 ++++-- scalalib/src/mill/scalalib/Lib.scala | 4 +- testng/src/mill/testng/EventRecorder.java | 40 ----------- testng/src/mill/testng/TestNGFramework.java | 7 +- testng/src/mill/testng/TestNGInstance.java | 80 +++++++++++++++------- testng/src/mill/testng/TestNGRunner.java | 35 ++++------ testng/src/mill/testng/TestRunState.java | 10 --- 9 files changed, 92 insertions(+), 107 deletions(-) delete mode 100644 testng/src/mill/testng/EventRecorder.java delete mode 100644 testng/src/mill/testng/TestRunState.java diff --git a/ci/test-mill-2.sh b/ci/test-mill-2.sh index c61143e1..d5869b93 100755 --- a/ci/test-mill-2.sh +++ b/ci/test-mill-2.sh @@ -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}" diff --git a/integration/test/resources/caffeine/build.sc b/integration/test/resources/caffeine/build.sc index aa27eff9..3c023366 100644 --- a/integration/test/resources/caffeine/build.sc +++ b/integration/test/resources/caffeine/build.sc @@ -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, @@ -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, diff --git a/integration/test/src/mill/integration/CaffeineTests.scala b/integration/test/src/mill/integration/CaffeineTests.scala index 121a8701..a93dc91a 100644 --- a/integration/test/src/mill/integration/CaffeineTests.scala +++ b/integration/test/src/mill/integration/CaffeineTests.scala @@ -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")) } } diff --git a/scalalib/src/mill/scalalib/Lib.scala b/scalalib/src/mill/scalalib/Lib.scala index 3e06ea37..46164e4b 100644 --- a/scalalib/src/mill/scalalib/Lib.scala +++ b/scalalib/src/mill/scalalib/Lib.scala @@ -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)) diff --git a/testng/src/mill/testng/EventRecorder.java b/testng/src/mill/testng/EventRecorder.java deleted file mode 100644 index 59af5927..00000000 --- a/testng/src/mill/testng/EventRecorder.java +++ /dev/null @@ -1,40 +0,0 @@ -package mill.testng; - -import sbt.testing.Event; -import org.testng.ITestResult; -import org.testng.TestListenerAdapter; - -import sbt.testing.EventHandler; -import sbt.testing.Logger; - -import java.util.HashMap; - -public class EventRecorder extends TestListenerAdapter { - private final HashMap> basket = new HashMap<>(); - - String initKey(ITestResult result){ - String key = ResultEvent.classNameOf(result); - if (!basket.containsKey(key)) basket.put(key, new java.util.ArrayList()); - return key; - } - public void onTestFailure(ITestResult result){ - String key = initKey(result); - basket.get(key).add(ResultEvent.failure(result)); - } - public void onTestSkipped(ITestResult result){ - String key = initKey(result); - basket.get(key).add(ResultEvent.skipped(result)); - } - public void onTestSuccess(ITestResult result){ - String key = initKey(result); - basket.get(key).add(ResultEvent.success(result)); - } - - void replayTo(EventHandler sbt, String className, Logger[] loggers){ - synchronized (basket){ - for(Event e: basket.remove(className)){ - sbt.handle(e); - } - } - } -} diff --git a/testng/src/mill/testng/TestNGFramework.java b/testng/src/mill/testng/TestNGFramework.java index 50041440..924dc113 100644 --- a/testng/src/mill/testng/TestNGFramework.java +++ b/testng/src/mill/testng/TestNGFramework.java @@ -14,11 +14,8 @@ public class TestNGFramework implements Framework { @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{ @@ -29,4 +26,4 @@ class Annotated implements AnnotatedFingerprint{ } public String annotationName(){return annotationName;} public boolean isModule(){return false;} -} \ No newline at end of file +} diff --git a/testng/src/mill/testng/TestNGInstance.java b/testng/src/mill/testng/TestNGInstance.java index afb1e8f7..9ad990e0 100644 --- a/testng/src/mill/testng/TestNGInstance.java +++ b/testng/src/mill/testng/TestNGInstance.java @@ -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); + } } + + diff --git a/testng/src/mill/testng/TestNGRunner.java b/testng/src/mill/testng/TestNGRunner.java index 0ad6caa7..29ebb7dd 100644 --- a/testng/src/mill/testng/TestNGRunner.java +++ b/testng/src/mill/testng/TestNGRunner.java @@ -2,6 +2,9 @@ package mill.testng; import sbt.testing.*; +import java.util.Arrays; +import java.util.Collections; + class TestNGTask implements Task { TaskDef taskDef; @@ -18,24 +21,14 @@ class TestNGTask implements Task { @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]; } @@ -44,19 +37,19 @@ class TestNGTask implements Task { 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); diff --git a/testng/src/mill/testng/TestRunState.java b/testng/src/mill/testng/TestRunState.java deleted file mode 100644 index 3edb2a4d..00000000 --- a/testng/src/mill/testng/TestRunState.java +++ /dev/null @@ -1,10 +0,0 @@ -package mill.testng; - -import java.util.concurrent.Semaphore; -import java.util.concurrent.CountDownLatch; - -public class TestRunState { - public static Semaphore permissionToExecute = new Semaphore(1); - public static CountDownLatch testCompletion = new CountDownLatch(1); - public static EventRecorder recorder = new EventRecorder(); -} \ No newline at end of file -- cgit v1.2.3