Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run scripted tests on sbt 1.4.x + refactoring #10655

Merged
merged 19 commits into from Mar 13, 2021

Conversation

mkurz
Copy link
Member

@mkurz mkurz commented Jan 22, 2021

As suggested once by Dale I now folded scripts/test-scripted-13x into scripts/test-scripted. I also can not see why we should have different scripts for different sbt versions... Also because this pull request now adds another sbt version,1.4.9, meaning the scripted tests will now be run against 1.2.x, 1.3.x and 1.4.x.

I also defined fixed sbt versions in .travis.yml. Before that the job(s) that "Run scripted tests (a/b/c) for sbt 1.x" would just use the sbt version set by interplay (See Line -> Line -> Line). IMHO setting the versions hardcoded in .travis.yml is more readable (took me a while to figure out the default comes from interplay), safer (what if interplay upgrades to 1.3.x or newer, but nobody updates the .travis.yml description, when looking at the tests someone may still thinks that the tests are running for 1.2.x) and also easier to maintain (we can quickly test new sbt versions by just updating .travis.yml instead of releasing and upgrading interplay).

@mkurz
Copy link
Member Author

mkurz commented Jan 27, 2021

Following scripted tests fail when running with sbt 1.4, however this was expected by me, because sbt 1.4 support is not done/merged yet (also #10711 not yet): (All fixed 🎉)

[error] 	play-sbt-plugin/dev-mode
[error] 	play-sbt-plugin/evolutions-auto-apply-false
[error] 	play-sbt-plugin/evolutions-auto-apply-true
[error] 	play-sbt-plugin/evolutions-multiple-databases
[error] 	play-sbt-plugin/generated-keystore
[error] 	play-sbt-plugin/http-backend-system-property
[error] 	play-sbt-plugin/maven-layout-twirl-reload
[error] 	play-sbt-plugin/multiproject
[error] 	play-sbt-plugin/play-position-mapper
[error] 	play-sbt-plugin/routes-compiler-source-mapping
[error] 	play-sbt-plugin/shutdown-downing
[error] 	play-sbt-plugin/shutdown-happy-path

.travis.yml Outdated Show resolved Hide resolved
.travis.yml Outdated Show resolved Hide resolved
.travis.yml Show resolved Hide resolved
@mkurz
Copy link
Member Author

mkurz commented Feb 25, 2021

Backport #10723

@mkurz
Copy link
Member Author

mkurz commented Mar 2, 2021

Now that #10711 got merged, I restarted the tests for this PR, let's see if all the tests pass when running against sbt 1.4

@mkurz
Copy link
Member Author

mkurz commented Mar 3, 2021

Following scripted tests fail when running against sbt 1.4.x, but pass with 1.3.x EDIT: Fixed!

[error] (scripted) Failed tests:
[error] 	play-sbt-plugin/multiproject
[error] 	play-sbt-plugin/play-position-mapper
[error] 	play-sbt-plugin/routes-compiler-source-mapping

Challenge accepted :trollface:

@mkurz
Copy link
Member Author

mkurz commented Mar 5, 2021

To make play-sbt-plugin/play-position-mapper work we need to wait for sbt 1.4.8, which should be got released this weekend. I had to patch sbt:
sbt/sbt#6352
1.4.x backport: sbt/sbt#6356
EDIT:
One more patch needed: sbt/sbt#6358
1.4.x backport: sbt/sbt#6359
EDIT 2: All fixed an released in sbt 1.4.8/1.4.9

@mkurz mkurz requested a review from ignasi35 March 9, 2021 23:33
@mkurz mkurz removed the request for review from ignasi35 March 11, 2021 15:04
// anymore before adding it to "allProblems", the field that eventually gets used by the Incomplete. (The transformation still takes place to show
// the mapped source file in the logs) Play however needs to know the mapped source file to display it in it's error pages for a nice dev experience.
// So the solution is that Play itself will try to transform the source file to the mapped file by running it "through" sourcePositionMappers:
Project
Copy link
Member Author

@mkurz mkurz Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the comment says it all... So since sbt/zinc#931 (which made it into sbt 1.4.1) the left Incomplete of following compileResult

val compileResult: Either[Incomplete, CompileSuccess] = for {
analysis <- reloadCompile().toEither.right
classpath <- classpath().toEither.right
} yield CompileSuccess(sourceMap(analysis), classpath.files)
compileResult.left.map(inc => CompileFailure(taskFailureHandler(inc, streams()))).merge
comes with Positions which are not transformed by the sourcePositionMappers config anymore. Here is the relevant code after that referenced pull request got applied for better context:
https://github.com/sbt/zinc/blob/v1.4.1/internal/zinc-compile-core/src/main/scala/sbt/internal/inc/LoggedReporter.scala#L131-L139
So since 1.4.1 sbt only transforms the position for log outputs... which is a problem for Play, so we have to make the Positions run through the sourcepositionmappers ourselves to show users the correct original soure of a problem in the error pages...

I also added two new tests for this new code here, which is relevant for sbt 1.4.1, see below.

Also I had to remove one scripted test which will always fail in sbt 1.4.1+, see routes-compiler-source-mapping/build.sbt below (I think you have to click "Load diff" in the GitHub UI to see the comment I left there). However the two new tests I added compensate the deleted one.

val (status, body) = ScriptedTools.callUrl(path)
println(s"Resource at $path returned HTTP $status")
IO.write(destination, body)
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to wrap this in a Future for these tests here... This was a mistake from beginning when I just copy/pasted the makeRequestAndRecordResponseBody task from the shutdown-happy-path scripted test where that Future is actually needed because it is a different test case.
As a result, in the test, we can also remove the 2 and 5 seconds sleeps after calling the command because now its blocking.

> makeRequestAndRecordResponseBody / appconf-fail.txt
# First request takes a bit longer, therefore 5 seconds
$ sleep 5000
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like mentioned makeRequestAndRecordResponseBody is blocking now, no need anymore for that sleep.

@@ -64,7 +64,28 @@ TaskKey[Unit]("checkPlayCompileEverything") := {
base / "playmodule" / "app" / "PlayModule.scala",
base / "transitive" / "app" / "Transitive.scala"
)
val allSources = analyses.flatMap(_.relations.allSources).map(_.toPath).sorted.map(_.toFile)
val allSources = analyses.flatMap(_.relations.allSources).map(_ match {
Copy link
Member Author

@mkurz mkurz Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allSources returns VirtualFiles in sbt 1.4 (which has no toPath method) but a Java File in sbt <= 1.3... Therefore I had to apply the same workaround in this test we used in PR 10648: https://github.com/playframework/playframework/pull/10648/files#diff-e1d77acde8f8aee39e58b112462d82fdcbc8c2920092be5af01ed5b3a92ca64b

EDIT:
Actually I had the error log still open in an editor so this is what failed when running with sbt 1.4:

[error] /tmp/sbt_3797ffa5/build.sbt:67: error: value toPath is not a member of xsbti.VirtualFileRef
[error]   val allSources = analyses.flatMap(_.relations.allSources).map(_.toPath).sorted.map(_.toFile)
[error]                                                                   ^

@@ -5,6 +5,7 @@ lazy val root = (project in file("."))
.enablePlugins(PlayJava)

libraryDependencies ++= Seq(guice, specs2 % Test)
libraryDependencies += "org.scala-lang.modules" %% "scala-collection-compat" % "2.3.2" // can be removed when dropping Scala 2.12
Copy link
Member Author

@mkurz mkurz Mar 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This an all changes below make the scripted tests behave on Scala 2.13 (until now they were just run with Scala 2.12...)

val source = base / args(0)
val line = Integer.parseInt(args(1))
val errors = Incomplete
.allExceptions(assertLeft(assertSome(Project.runTask(compile in Compile, state.value))._2.toEither))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed that test because it will never succeed anymore in sbt 1.4.1+ because Positions returned by the incomplete will not be transformed anymore by the sourcepositionmappers, see comment above.

@@ -376,7 +376,6 @@ object BuildSettings {
"-XX:MaxMetaspaceSize=300m",
"-XX:HeapDumpPath=/tmp/",
"-XX:+HeapDumpOnOutOfMemoryError",
s"-Dscala.version=$scala212",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets set by script/test-scripted now.

@@ -12,7 +12,7 @@ rm -rf $HOME/.ivy2/local
end clean "CLEANED IVY LOCAL REPO"

start publish-local "CROSS-PUBLISHING PLAY LOCALLY FOR SBT SCRIPTED TESTS"
runSbt +publishLocal
runSbt ";crossScalaVersions;crossSbtVersions;+publishLocal"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just adding some output for debugging...

@mkurz
Copy link
Member Author

mkurz commented Mar 11, 2021

@ignasi35 @octonato This pull request is finally ready to review!

As an example how a cron build will look like (except without sbt 1.2) you can have a look at
https://travis-ci.com/github/playframework/playframework/builds/219526837
which is the build of this commit:
image
(the commit before I added the cron conditions)

Copy link
Member

@ignasi35 ignasi35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great work! Thanks @mkurz

I only have a concern re the cost of running so many scripted tests in the CRON jobs. I'll merge as is but we should keep an eye on the weekend cron jobs to get a better idea of how much cost/benefit this brings.

Comment on lines +39 to +41
- test-sbt-1.3.x
- cron-test-sbt-1.3.x
- cron-test-sbt-1.4.x
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- test-sbt-1.3.x
- cron-test-sbt-1.3.x
- cron-test-sbt-1.4.x
- test-sbt-1.3.x-2.12
- cron-test-sbt-1.3.x-2.13
- cron-test-sbt-1.4.x

Indicating the difference (scala version) to make it clearer what's the version tested on every PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker. Let's solve this elsewhere.

Comment on lines +131 to +139
# Test against sbt 1.4.x, but only for cron builds
- stage: cron-test-sbt-1.4.x
name: "Run tests for 1.4.x and Scala 2.12.x"
script: scripts/test-scripted $SCRIPTED_SBT_1_4 $TEST_SCALA_2_12
if: type = cron
workspaces:
use: published-local
- name: "Run tests for 1.4.x and Scala 2.13.x"
script: scripts/test-scripted $SCRIPTED_SBT_1_4 $TEST_SCALA_2_13
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is rather expensive and I'm not 100% sure we should extend the support matrix in all possible axis (JDK8/11, sbt1.3/1.4, scala2.12/2.13).

I think running only 1.4.x for 2.13 could be enough. I think users of sbt 1.4 may be more likely to be early adopters in general and, therefore, users of 2.13 already.

Again, not sure whether we should keep both jobs or not...

@@ -30,96 +30,152 @@ $ delete build.sbt.1
################
$ copy-file conf/application.conf application.conf.good
$ copy-file application.conf.bad conf/application.conf
# Give CI/docker/Java thread enough time to detect file change
$ sleep 1200
> makeRequestAndRecordResponseBody / appconf-fail.txt
# First request takes a bit longer, therefore 5 seconds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is obsolete (the sleep is gone)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was referring to # First request takes a bit longer, therefore 5 seconds

Comment on lines +105 to +108
#############################################################################################################################################
# Invalid twirl template (parsing index.scala.html file is OK, but compiling target/scala-*/twirl/main/views/html/index.template.scala fails)
# Actually this tests if the sourcePositionMappers set up by sbt-twirl is called and works correctly
#############################################################################################################################################
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments are great. Help the maintenance of the tests as they explain the expectation and use case very clearly. 👏🏼

@mkurz
Copy link
Member Author

mkurz commented Mar 13, 2021

@ignasi35 thanks a lot for the review! I removed the obsolete comment.

I only have a concern re the cost of running so many scripted tests in the CRON jobs

Like you said, lets merge and observe, we can always change/remove jobs from the matrix.

@mergify mergify bot merged commit 8f7021d into playframework:master Mar 13, 2021
@mkurz mkurz deleted the sbt14_refactoring branch March 13, 2021 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants