-
-
Notifications
You must be signed in to change notification settings - Fork 360
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update thirdparty tests, make subprocess testrunner run user code in …
…root classloader (#2561) 1. Move `thirdparty` from `integration/` to `example/`, and simplify them down to `acyclic`, `fansi`, and `jimfs`. We can add more complex builds later if we want, but for now just having some realistic builds that are not bitrotted and old is already an improvement over what we have now. 2. Flip the sub-process `TestRunner` classloaders on its head: rather than runner `TestRunner.scala` in the boot classloader and user code in a sub-classloader, we run user code in the boot classloader and `TestRunner.scala` in a sub classloader. This is necessary to make JimFS work, and would probably fix #716 and related issues. 3. Broke up and cleaned up `TestRunner.scala`: 1. Separated `TestRunner` and `TestRunnerMain0`, the two entrypoints, from `TestRunnerUtils` 2. Replaced all the complicated logic for converting logic to/from CLI flags with JSON written to a file by `TestModule` and read from the file by `TestRunner` 3. Replaced `ClosableIterator` with `geny.Generator`, which also provides guaranteed closing after iteration 4. Marked most of `testrunner` as `@internal`. Most of these could be `private[mill]`, but I think we don't have a clear idea of how this stuff is meant to be used yet, and it's plausible that other people may want to interact with the testrunner in their own custom test suites. I think `@internal` is better suited for now until we either (a) know better what a stable API looks like or (b) decide that this stuff should not be used externally. We have much more control over `TestRunner.scala` than we do over user code, so we can make sure that `TestRunner.scala` works when running in a semi-isolated classloader, whereas for user code we can offer no such guarantees. We can't do anything for `.testLocal` that runs in-process, but at least for `.test` we can try to offer them a clean classloader environment. The classloader for user code is not 100% clean: we still have a single class `mill.testrunner.entrypoint.TestRunnerMain` added within it. That's probably OK, since no matter what we do w.r.t. shading and stuff we still need somewhere to put our own main method to bootstrap the `mill.testrunner` classloader. The testrunner changes are covered by existing unit and integration/example tests, and the new "user code runs in clean classloader" logic is covered by `example.thirdparty[jimfs].local`.
- Loading branch information
Showing
32 changed files
with
668 additions
and
1,745 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import mill._, scalalib._, publish._ | ||
|
||
object Deps { | ||
def acyclic = ivy"com.lihaoyi:::acyclic:0.3.6" | ||
def scalaCompiler(scalaVersion: String) = ivy"org.scala-lang:scala-compiler:$scalaVersion" | ||
val utest = ivy"com.lihaoyi::utest:0.8.1" | ||
} | ||
|
||
val crosses = | ||
Seq("2.11.12") ++ | ||
Range.inclusive(8, 17).map("2.12." + _) ++ | ||
Range.inclusive(0, 10).map("2.13." + _) | ||
|
||
object acyclic extends Cross[AcyclicModule](crosses) | ||
trait AcyclicModule extends CrossScalaModule with PublishModule { | ||
def crossFullScalaVersion = true | ||
def artifactName = "acyclic" | ||
def publishVersion = "1.3.3.7" | ||
|
||
def pomSettings = PomSettings( | ||
description = artifactName(), | ||
organization = "com.lihaoyi", | ||
url = "https://github.com/com-lihaoyi/acyclic", | ||
licenses = Seq(License.MIT), | ||
versionControl = VersionControl.github(owner = "com-lihaoyi", repo = "acyclic"), | ||
developers = Seq( | ||
Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi") | ||
) | ||
) | ||
|
||
def compileIvyDeps = Agg(Deps.scalaCompiler(crossScalaVersion)) | ||
|
||
object test extends ScalaModuleTests with TestModule.Utest { | ||
def sources = T.sources(millSourcePath / "src", millSourcePath / "resources") | ||
def ivyDeps = Agg(Deps.utest, Deps.scalaCompiler(crossScalaVersion)) | ||
} | ||
} | ||
|
||
// Acyclic is an example of a very small project that is a Scala compiler | ||
// plugin. It is cross-built against all point versions of Scala from 2.11.12 | ||
// to 2.13.10, and has a dependency on the `org.scala-lang:scala-compiler` | ||
|
||
/** Usage | ||
> ./mill resolve acyclic[_].compile | ||
acyclic[2.11.12].compile | ||
acyclic[2.12.10].compile | ||
acyclic[2.12.11].compile | ||
acyclic[2.12.12].compile | ||
acyclic[2.12.13].compile | ||
acyclic[2.12.14].compile | ||
acyclic[2.12.15].compile | ||
acyclic[2.12.16].compile | ||
acyclic[2.12.8].compile | ||
acyclic[2.12.9].compile | ||
acyclic[2.13.0].compile | ||
acyclic[2.13.1].compile | ||
acyclic[2.13.2].compile | ||
acyclic[2.13.3].compile | ||
acyclic[2.13.4].compile | ||
acyclic[2.13.5].compile | ||
acyclic[2.13.6].compile | ||
acyclic[2.13.7].compile | ||
acyclic[2.13.8].compile | ||
acyclic[2.13.9].compile | ||
> ./mill acyclic[2.12.17].compile | ||
compiling 6 Scala sources... | ||
... | ||
> ./mill acyclic[2.13.10].test.testLocal # acyclic tests need testLocal due to classloader assumptions | ||
-------------------------------- Running Tests -------------------------------- | ||
... | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import mill._, scalalib._, scalajslib._, scalanativelib._, publish._ | ||
|
||
val dottyCommunityBuildVersion = sys.props.get("dottyVersion").toList | ||
|
||
val scalaVersions = Seq("2.12.17", "2.13.8", "2.11.12", "3.1.3") ++ dottyCommunityBuildVersion | ||
|
||
trait FansiModule extends PublishModule with CrossScalaModule with PlatformScalaModule { | ||
def publishVersion = "1.3.3.7" | ||
|
||
def pomSettings = PomSettings( | ||
description = artifactName(), | ||
organization = "com.lihaoyi", | ||
url = "https://github.com/com-lihaoyi/Fansi", | ||
licenses = Seq(License.MIT), | ||
versionControl = VersionControl.github(owner = "com-lihaoyi", repo = "fansi"), | ||
developers = Seq( | ||
Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi") | ||
) | ||
) | ||
|
||
def ivyDeps = Agg(ivy"com.lihaoyi::sourcecode::0.3.0") | ||
|
||
trait FansiTestModule extends ScalaModuleTests with TestModule.Utest { | ||
def ivyDeps = Agg(ivy"com.lihaoyi::utest::0.8.1") | ||
} | ||
} | ||
|
||
object fansi extends Module { | ||
object jvm extends Cross[JvmFansiModule](scalaVersions) | ||
trait JvmFansiModule extends FansiModule with ScalaModule { | ||
object test extends FansiTestModule with ScalaModuleTests | ||
} | ||
|
||
object js extends Cross[JsFansiModule](scalaVersions) | ||
trait JsFansiModule extends FansiModule with ScalaJSModule { | ||
def scalaJSVersion = "1.10.1" | ||
object test extends FansiTestModule with ScalaJSModuleTests | ||
} | ||
|
||
object native extends Cross[NativeFansiModule](scalaVersions) | ||
trait NativeFansiModule extends FansiModule with ScalaNativeModule { | ||
def scalaNativeVersion = "0.4.5" | ||
object test extends FansiTestModule with ScalaNativeModuleTests | ||
} | ||
} | ||
|
||
// Fansi is an example of a small library that is cross built against every | ||
// minor version of Scala (including Scala 3.x) and every platform: JVM, JS, | ||
// and Native. Both the library and the test suite are duplicated across all | ||
// entries in the {version}x{platform} matrix, and you can select which one you | ||
// want to compile, test, or publish | ||
|
||
/** Usage | ||
> ./mill resolve __.compile | ||
fansi.js[2.11.12].test.compile | ||
fansi.js[2.12.17].compile | ||
fansi.js[2.12.17].test.compile | ||
fansi.js[2.13.8].compile | ||
fansi.js[2.13.8].test.compile | ||
fansi.js[3.1.3].compile | ||
fansi.js[3.1.3].test.compile | ||
fansi.jvm[2.11.12].compile | ||
fansi.jvm[2.11.12].test.compile | ||
fansi.jvm[2.12.17].compile | ||
fansi.jvm[2.12.17].test.compile | ||
fansi.jvm[2.13.8].compile | ||
fansi.jvm[2.13.8].test.compile | ||
fansi.jvm[3.1.3].compile | ||
fansi.jvm[3.1.3].test.compile | ||
fansi.native[2.11.12].compile | ||
fansi.native[2.11.12].test.compile | ||
fansi.native[2.12.17].compile | ||
fansi.native[2.12.17].test.compile | ||
fansi.native[2.13.8].compile | ||
fansi.native[2.13.8].test.compile | ||
fansi.native[3.1.3].compile | ||
fansi.native[3.1.3].test.compile | ||
> ./mill fansi.jvm[2.12.17].compile | ||
compiling 1 Scala source... | ||
... | ||
> ./mill fansi.js[2.13.8].test | ||
Starting process: node | ||
-------------------------------- Running Tests -------------------------------- | ||
... | ||
> ./mill fansi.native[3.1.3].publishLocal | ||
Publishing Artifact(com.lihaoyi,fansi_native0.4_3,1.3.3.7) to ivy repo... | ||
... | ||
*/ |
Oops, something went wrong.