diff options
-rwxr-xr-x | build.sc | 5 | ||||
-rwxr-xr-x | ci/test-mill-2.sh | 2 | ||||
-rwxr-xr-x | ci/test-mill-release.sh | 2 | ||||
-rw-r--r-- | integration/test/resources/caffeine/build.sc | 5 | ||||
-rw-r--r-- | integration/test/src/mill/integration/CaffeineTests.scala | 5 | ||||
-rw-r--r-- | main/test/src/mill/util/ScriptTestSuite.scala | 4 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/Lib.scala | 45 | ||||
-rw-r--r-- | scalaworker/src/mill/scalaworker/ScalaWorker.scala | 4 | ||||
-rw-r--r-- | testng/src/mill/testng/ResultEvent.java | 2 | ||||
-rw-r--r-- | testng/src/mill/testng/TestNGFramework.java | 12 | ||||
-rw-r--r-- | testng/src/mill/testng/TestNGInstance.java | 11 | ||||
-rw-r--r-- | testng/src/mill/testng/TestNGRunner.java | 29 |
12 files changed, 76 insertions, 50 deletions
@@ -210,7 +210,10 @@ object integration extends MillModule{ def testArgs = T{ scalajslib.testArgs() ++ scalaworker.testArgs() ++ - Seq("-DMILL_TESTNG=" + testng.runClasspath().map(_.path).mkString(",")) ++ + Seq( + "-DMILL_TESTNG=" + testng.runClasspath().map(_.path).mkString(","), + "-DMILL_VERSION=" + build.publishVersion()._2 + ) ++ (for((k, v) <- testRepos()) yield s"-D$k=$v") } def forkArgs = testArgs() diff --git a/ci/test-mill-2.sh b/ci/test-mill-2.sh index d5869b93..00480a31 100755 --- a/ci/test-mill-2.sh +++ b/ci/test-mill-2.sh @@ -7,4 +7,4 @@ git clean -xdf mill testng.publishLocal # Needed for CaffeineTests # Run tests -mill integration.test "mill.integration.local.{AcyclicTests,AmmoniteTests,CaffeineTests}" +mill integration.test "mill.integration.local.{AcyclicTests,AmmoniteTests}" diff --git a/ci/test-mill-release.sh b/ci/test-mill-release.sh index e5ea2b67..6a6e46e0 100755 --- a/ci/test-mill-release.sh +++ b/ci/test-mill-release.sh @@ -15,3 +15,5 @@ rm -rf ~/.mill # Run tests ~/mill-release -i integration.test "mill.integration.forked.{AcyclicTests,UpickleTests,PlayJsonTests}" + +~/mill-release -i integration.test "mill.integration.local.CaffeineTests"
\ No newline at end of file diff --git a/integration/test/resources/caffeine/build.sc b/integration/test/resources/caffeine/build.sc index 3c023366..32bf2d1b 100644 --- a/integration/test/resources/caffeine/build.sc +++ b/integration/test/resources/caffeine/build.sc @@ -21,7 +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", + ivy"com.lihaoyi:mill-testng:${sys.props("MILL_VERSION")}", libraries.guava, testLibraries.mockito, testLibraries.hamcrest, @@ -85,6 +85,8 @@ object caffeine extends CaffeineModule { testLibraries.guavaTestLib, ) ++ testLibraries.testng + + def allSourceFiles = super.allSourceFiles().filter(_.path.last != "OSGiTest.java") } } @@ -99,6 +101,7 @@ object guava extends CaffeineModule { testLibraries.easymock, testLibraries.guavaTestLib ) + def allSourceFiles = super.allSourceFiles().filter(_.path.last != "OSGiTest.java") def forkArgs = Seq( "-Dguava.osgi.version=" + versions.guava, "-Dcaffeine.osgi.jar=" + caffeine.jar().path, diff --git a/integration/test/src/mill/integration/CaffeineTests.scala b/integration/test/src/mill/integration/CaffeineTests.scala index a93dc91a..8fcbcaee 100644 --- a/integration/test/src/mill/integration/CaffeineTests.scala +++ b/integration/test/src/mill/integration/CaffeineTests.scala @@ -10,7 +10,7 @@ class CaffeineTests(fork: Boolean) extends IntegrationTestSuite("MILL_CAFFEINE_R // type inference issues during the compile if (mill.client.ClientServer.isJava9OrAbove){ assert(eval("caffeine.test.compile")) - assert(eval("guava.test")) + val suites = Seq( "com.github.benmanes.caffeine.SingleConsumerQueueTest", "com.github.benmanes.caffeine.cache.AsyncTest", @@ -22,8 +22,11 @@ class CaffeineTests(fork: Boolean) extends IntegrationTestSuite("MILL_CAFFEINE_R "-testclass", suites.mkString(",") )) assert(eval("guava.test.compile")) + assert(eval("guava.test")) + assert(eval("jcache.test.compile")) assert(eval("simulator.test.compile")) + } } diff --git a/main/test/src/mill/util/ScriptTestSuite.scala b/main/test/src/mill/util/ScriptTestSuite.scala index bbca5d68..53356930 100644 --- a/main/test/src/mill/util/ScriptTestSuite.scala +++ b/main/test/src/mill/util/ScriptTestSuite.scala @@ -10,8 +10,8 @@ abstract class ScriptTestSuite(fork: Boolean) extends TestSuite{ def scriptSourcePath: Path val workspacePath = pwd / 'target / 'workspace / workspaceSlug -// val stdOutErr = new PrintStream(new ByteArrayOutputStream()) - val stdOutErr = new PrintStream(System.out) + val stdOutErr = new PrintStream(new ByteArrayOutputStream()) +// val stdOutErr = new PrintStream(System.out) val stdIn = new ByteArrayInputStream(Array()) lazy val runner = new mill.main.MainRunner( ammonite.main.Cli.Config(wd = workspacePath), diff --git a/scalalib/src/mill/scalalib/Lib.scala b/scalalib/src/mill/scalalib/Lib.scala index 46164e4b..bda8e8f8 100644 --- a/scalalib/src/mill/scalalib/Lib.scala +++ b/scalalib/src/mill/scalalib/Lib.scala @@ -289,27 +289,38 @@ object Lib{ if (!exists(base)) Nil else listClassFiles(base).flatMap { path => val cls = cl.loadClass(path.stripSuffix(".class").replace('/', '.')) - fingerprints.find { - case f: SubclassFingerprint => - !cls.isInterface && - (f.isModule == cls.getName.endsWith("$")) && - cl.loadClass(f.superclassName()).isAssignableFrom(cls) && - (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("$")) && - (f.isModule || cls.getConstructors.count(c => c.getParameterCount == 0 && Modifier.isPublic(c.getModifiers)) == 1) - ( - cls.isAnnotationPresent(annotationCls) || - cls.getDeclaredMethods.exists(_.isAnnotationPresent(annotationCls)) - ) - - }.map { f => (cls, f) } + val publicConstructorCount = + cls.getConstructors.count(c => c.getParameterCount == 0 && Modifier.isPublic(c.getModifiers)) + + if (Modifier.isAbstract(cls.getModifiers) || cls.isInterface || publicConstructorCount > 1) { + None + } else { + (cls.getName.endsWith("$"), publicConstructorCount == 0) match{ + case (true, true) => matchFingerprints(cl, cls, fingerprints, isModule = true) + case (false, false) => matchFingerprints(cl, cls, fingerprints, isModule = false) + case _ => None + } + } } } testClasses } + def matchFingerprints(cl: ClassLoader, cls: Class[_], fingerprints: Array[Fingerprint], isModule: Boolean) = { + fingerprints.find { + case f: SubclassFingerprint => + f.isModule == isModule && + cl.loadClass(f.superclassName()).isAssignableFrom(cls) + + case f: AnnotatedFingerprint => + val annotationCls = cl.loadClass(f.annotationName()).asInstanceOf[Class[Annotation]] + f.isModule == isModule && + ( + cls.isAnnotationPresent(annotationCls) || + cls.getDeclaredMethods.exists(_.isAnnotationPresent(annotationCls)) + ) + + }.map { f => (cls, f) } + } } diff --git a/scalaworker/src/mill/scalaworker/ScalaWorker.scala b/scalaworker/src/mill/scalaworker/ScalaWorker.scala index 08a31fc6..8c11379f 100644 --- a/scalaworker/src/mill/scalaworker/ScalaWorker.scala +++ b/scalaworker/src/mill/scalaworker/ScalaWorker.scala @@ -60,6 +60,10 @@ object ScalaWorker{ args = arguments )(ctx) + // Clear interrupted state in case some badly-behaved test suite + // dirtied the thread-interrupted flag and forgot to clean up. Otherwise + // that flag causes writing the results to disk to fail + Thread.interrupted() ammonite.ops.write(Path(outputPath), upickle.default.write(result)) }catch{case e: Throwable => println(e) diff --git a/testng/src/mill/testng/ResultEvent.java b/testng/src/mill/testng/ResultEvent.java index 215723cd..6e2a50d6 100644 --- a/testng/src/mill/testng/ResultEvent.java +++ b/testng/src/mill/testng/ResultEvent.java @@ -16,7 +16,7 @@ public class ResultEvent { } public Fingerprint fingerprint() { - return Annotated.instance; + return TestNGFingerprint.instance; } public Selector selector() { diff --git a/testng/src/mill/testng/TestNGFramework.java b/testng/src/mill/testng/TestNGFramework.java index 924dc113..6e993fcc 100644 --- a/testng/src/mill/testng/TestNGFramework.java +++ b/testng/src/mill/testng/TestNGFramework.java @@ -9,7 +9,7 @@ public class TestNGFramework implements Framework { public String name(){ return "TestNG"; } public Fingerprint[] fingerprints() { - return new Fingerprint[]{Annotated.instance}; + return new Fingerprint[]{TestNGFingerprint.instance}; } @Override @@ -18,12 +18,8 @@ public class TestNGFramework implements Framework { } } -class Annotated implements AnnotatedFingerprint{ - final public static Annotated instance = new Annotated("org.testng.annotations.Test"); - String annotationName; - public Annotated(String annotationName) { - this.annotationName = annotationName; - } - public String annotationName(){return annotationName;} +class TestNGFingerprint implements AnnotatedFingerprint{ + final public static TestNGFingerprint instance = new TestNGFingerprint(); + public String annotationName(){return "org.testng.annotations.Test";} public boolean isModule(){return false;} } diff --git a/testng/src/mill/testng/TestNGInstance.java b/testng/src/mill/testng/TestNGInstance.java index 9ad990e0..4cf274d3 100644 --- a/testng/src/mill/testng/TestNGInstance.java +++ b/testng/src/mill/testng/TestNGInstance.java @@ -54,19 +54,12 @@ class TestNGListener implements ITestListener{ public class TestNGInstance extends TestNG{ public TestNGInstance(Logger[] loggers, ClassLoader testClassLoader, - String[] testOptions, - String suiteName, + CommandLineArgs args, EventHandler eventHandler) { addClassLoader(testClassLoader); - 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 29ebb7dd..0ad05f76 100644 --- a/testng/src/mill/testng/TestNGRunner.java +++ b/testng/src/mill/testng/TestNGRunner.java @@ -1,17 +1,25 @@ package mill.testng; +import com.beust.jcommander.JCommander; +import org.testng.CommandLineArgs; import sbt.testing.*; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; class TestNGTask implements Task { TaskDef taskDef; TestNGRunner runner; - public TestNGTask(TaskDef taskDef, TestNGRunner runner){ + CommandLineArgs cliArgs; + public TestNGTask(TaskDef taskDef, + TestNGRunner runner, + CommandLineArgs cliArgs){ this.taskDef = taskDef; this.runner = runner; + this.cliArgs = cliArgs; } @Override @@ -21,12 +29,10 @@ class TestNGTask implements Task { @Override public Task[] execute(EventHandler eventHandler, Logger[] loggers) { - System.out.println("Executing " + taskDef.fullyQualifiedName()); new TestNGInstance( loggers, runner.testClassLoader, - runner.args(), - taskDef.fullyQualifiedName(), + cliArgs, eventHandler ).run(); return new Task[0]; @@ -49,12 +55,17 @@ public class TestNGRunner implements Runner { } 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); + CommandLineArgs cliArgs = new CommandLineArgs(); + new JCommander(cliArgs, args); // args is an output parameter of the constructor! + if(cliArgs.testClass == null){ + String[] names = new String[taskDefs.length]; + for(int i = 0; i < taskDefs.length; i += 1){ + names[i] = taskDefs[i].fullyQualifiedName(); + } + cliArgs.testClass = String.join(",", names); } - return out; + if (taskDefs.length == 0) return new Task[]{}; + else return new Task[]{new TestNGTask(taskDefs[0], this, cliArgs)}; } public String done() { return null; } |