Build server test refactoring

This commit is contained in:
Adrien Piquerez 2023-10-25 15:01:08 +02:00
parent b189d49968
commit a4097440bf
1 changed files with 145 additions and 203 deletions

View File

@ -33,11 +33,11 @@ object BuildServerTest extends AbstractServerTest {
test("build/initialize") { _ => test("build/initialize") { _ =>
val id = initializeRequest() val id = initializeRequest()
assert(svr.waitForString(10.seconds) { s => assertMessage(
(s contains s""""id":"${id}"""") && s""""id":"${id}"""",
(s contains """"resourcesProvider":true""") && """"resourcesProvider":true""",
(s contains """"outputPathsProvider":true""") """"outputPathsProvider":true"""
}) )()
} }
test("workspace/buildTargets") { _ => test("workspace/buildTargets") { _ =>
@ -102,30 +102,17 @@ object BuildServerTest extends AbstractServerTest {
compile(buildTarget) compile(buildTarget)
// This doesn't always come back in 10s on CI. // This doesn't always come back in 10s on CI.
assert(svr.waitForString(60.seconds) { s => assertMessage("build/taskStart", """"message":"Compiling runAndTest"""")(duration = 60.seconds)
s.contains("build/taskStart") && assertMessage(
s.contains(""""message":"Compiling runAndTest"""") "build/taskProgress",
}) """"message":"Compiling runAndTest (15%)""""
)(duration = 60.seconds)
assert(svr.waitForString(60.seconds) { s => assertMessage(
s.contains("build/taskProgress") && "build/taskProgress",
s.contains(""""message":"Compiling runAndTest (15%)"""") """"message":"Compiling runAndTest (100%)""""
}) )(duration = 60.seconds)
assertMessage("build/publishDiagnostics", """"diagnostics":[]""")(duration = 60.seconds)
assert(svr.waitForString(60.seconds) { s => assertMessage("build/taskFinish", """"message":"Compiled runAndTest"""")(duration = 60.seconds)
s.contains("build/taskProgress") &&
s.contains(""""message":"Compiling runAndTest (100%)"""")
})
assert(svr.waitForString(60.seconds) { s =>
s.contains("build/publishDiagnostics") &&
s.contains(""""diagnostics":[]""")
})
assert(svr.waitForString(60.seconds) { s =>
s.contains("build/taskFinish") &&
s.contains(""""message":"Compiled runAndTest"""")
})
} }
test( test(
@ -136,10 +123,7 @@ object BuildServerTest extends AbstractServerTest {
compile(buildTarget) compile(buildTarget)
assert(svr.waitForString(30.seconds) { s => assertMessage("build/taskFinish", """"message":"Compiled diagnostics"""")(30.seconds)
s.contains("build/taskFinish") &&
s.contains(""""message":"Compiled diagnostics"""")
})
// introduce compile error // introduce compile error
IO.write( IO.write(
@ -152,13 +136,13 @@ object BuildServerTest extends AbstractServerTest {
reloadWorkspace() reloadWorkspace()
compile(buildTarget) compile(buildTarget)
assert( assertMessage(
svr.waitForString(30.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "Diagnostics.scala",
s.contains("Diagnostics.scala") && "\"message\":\"type mismatch"
s.contains("\"message\":\"type mismatch") )(
}, duration = 30.seconds,
"should send publishDiagnostics with type error for Main.scala" message = "should send publishDiagnostics with type error for Main.scala"
) )
// fix compilation error // fix compilation error
@ -172,13 +156,13 @@ object BuildServerTest extends AbstractServerTest {
reloadWorkspace() reloadWorkspace()
compile(buildTarget) compile(buildTarget)
assert( assertMessage(
svr.waitForString(30.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "Diagnostics.scala",
s.contains("Diagnostics.scala") && "\"diagnostics\":[]"
s.contains("\"diagnostics\":[]") )(
}, duration = 30.seconds,
"should send publishDiagnostics with empty diagnostics" message = "should send publishDiagnostics with empty diagnostics"
) )
// trigger no-op compilation // trigger no-op compilation
@ -199,13 +183,13 @@ object BuildServerTest extends AbstractServerTest {
compile(buildTarget) compile(buildTarget)
assert( assertMessage(
svr.waitForString(30.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "PatternMatch.scala",
s.contains("PatternMatch.scala") && """"message":"match may not be exhaustive"""
s.contains(""""message":"match may not be exhaustive""") )(
}, duration = 30.seconds,
"should send publishDiagnostics with type error for PatternMatch.scala" message = "should send publishDiagnostics with type error for PatternMatch.scala"
) )
IO.write( IO.write(
@ -223,15 +207,10 @@ object BuildServerTest extends AbstractServerTest {
reloadWorkspace() reloadWorkspace()
compile(buildTarget) compile(buildTarget)
assert( assertMessage("build/publishDiagnostics", "PatternMatch.scala", "\"diagnostics\":[]")(
svr.waitForString(30.seconds) { s => duration = 30.seconds,
s.contains("build/publishDiagnostics") && message = "should send publishDiagnostics with empty diagnostics"
s.contains("PatternMatch.scala") &&
s.contains("\"diagnostics\":[]")
},
"should send publishDiagnostics with empty diagnostics"
) )
} }
test("buildTarget/compile: Java diagnostics") { _ => test("buildTarget/compile: Java diagnostics") { _ =>
@ -239,42 +218,32 @@ object BuildServerTest extends AbstractServerTest {
compile(buildTarget) compile(buildTarget)
assert( assertMessage(
svr.waitForString(10.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "Hello.java",
s.contains("Hello.java") && """"severity":2""",
s.contains(""""severity":2""") && """missing type arguments for generic class java.util.List"""
s.contains("""missing type arguments for generic class java.util.List""") )(message = "should send publishDiagnostics with severity 2 for Hello.java")
},
"should send publishDiagnostics with severity 2 for Hello.java"
)
assert( assertMessage(
svr.waitForString(1.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "Hello.java",
s.contains("Hello.java") && """"severity":1""",
s.contains(""""severity":1""") && """incompatible types: int cannot be converted to java.lang.String"""
s.contains("""incompatible types: int cannot be converted to java.lang.String""") )(
}, message = "should send publishDiagnostics with severity 1 for Hello.java"
"should send publishDiagnostics with severity 1 for Hello.java"
) )
} }
test("buildTarget/scalacOptions, buildTarget/javacOptions") { _ => test("buildTarget/scalacOptions, buildTarget/javacOptions") { _ =>
val buildTarget = buildTargetUri("util", "Compile") val buildTarget = buildTargetUri("util", "Compile")
val badBuildTarget = buildTargetUri("badBuildTarget", "Compile") val badBuildTarget = buildTargetUri("badBuildTarget", "Compile")
val id1 = scalacOptions(Seq(buildTarget, badBuildTarget))
assert(svr.waitForString(10.seconds) { s => val id1 = scalacOptions(Seq(buildTarget, badBuildTarget))
(s contains s""""id":"$id1"""") && assertMessage(s""""id":"$id1"""", "scala-library-2.13.11.jar")()
(s contains "scala-library-2.13.11.jar")
})
val id2 = javacOptions(Seq(buildTarget, badBuildTarget)) val id2 = javacOptions(Seq(buildTarget, badBuildTarget))
assert(svr.waitForString(10.seconds) { s => assertMessage(s""""id":"$id2"""", "scala-library-2.13.11.jar")()
(s contains s""""id":"$id2"""") &&
(s contains "scala-library-2.13.11.jar")
})
} }
test("buildTarget/cleanCache") { _ => test("buildTarget/cleanCache") { _ =>
@ -328,10 +297,7 @@ object BuildServerTest extends AbstractServerTest {
s"""{ "jsonrpc": "2.0", "id": "$id", "method": "workspace/reload"}""" s"""{ "jsonrpc": "2.0", "id": "$id", "method": "workspace/reload"}"""
) )
assertProcessing("workspace/reload") assertProcessing("workspace/reload")
assert(svr.waitForString(10.seconds) { s => assertMessage(s""""id":"$id"""", """"result":null""")()
(s contains s""""id":"$id"""") &&
(s contains """"result":null""")
})
} }
test("workspace/reload: send diagnostic and respond with error") { _ => test("workspace/reload: send diagnostic and respond with error") { _ =>
@ -347,22 +313,19 @@ object BuildServerTest extends AbstractServerTest {
) )
val id = reloadWorkspace() val id = reloadWorkspace()
// reload // reload
assert( assertMessage(
svr.waitForString(10.seconds) { s => s""""buildTarget":{"uri":"$metaBuildTarget"}""",
s.contains(s""""buildTarget":{"uri":"$metaBuildTarget"}""") && s""""textDocument":{"uri":"${otherBuildFile.toPath.toUri}"}""",
s.contains(s""""textDocument":{"uri":"${otherBuildFile.toPath.toUri}"}""") && """"severity":1""",
s.contains(""""severity":1""") && """"reset":true"""
s.contains(""""reset":true""") )()
}
) assertMessage(
assert( s""""id":"$id"""",
svr.waitForString(10.seconds) { s => """"error"""",
s.contains(s""""id":"$id"""") && s""""code":${ErrorCodes.InternalError}""",
s.contains(""""error"""") && "Type error in expression"
s.contains(s""""code":${ErrorCodes.InternalError}""") && )()
s.contains("Type error in expression")
}
)
// fix the other-build.sbt file and reload again // fix the other-build.sbt file and reload again
IO.write( IO.write(
otherBuildFile, otherBuildFile,
@ -374,14 +337,12 @@ object BuildServerTest extends AbstractServerTest {
) )
reloadWorkspace() reloadWorkspace()
// assert received an empty diagnostic // assert received an empty diagnostic
assert( assertMessage(
svr.waitForString(10.seconds) { s => s""""buildTarget":{"uri":"$metaBuildTarget"}""",
s.contains(s""""buildTarget":{"uri":"$metaBuildTarget"}""") && s""""textDocument":{"uri":"${otherBuildFile.toPath.toUri}"}""",
s.contains(s""""textDocument":{"uri":"${otherBuildFile.toPath.toUri}"}""") && """"diagnostics":[]""",
s.contains(""""diagnostics":[]""") && """"reset":true"""
s.contains(""""reset":true""") )()
}
)
IO.delete(otherBuildFile) IO.delete(otherBuildFile)
} }
@ -395,10 +356,7 @@ object BuildServerTest extends AbstractServerTest {
|} }""".stripMargin |} }""".stripMargin
) )
assertProcessing("buildTarget/scalaMainClasses") assertProcessing("buildTarget/scalaMainClasses")
assert(svr.waitForString(30.seconds) { s => assertMessage(s""""id":"$id"""", """"class":"main.Main"""")(duration = 30.seconds)
(s contains s""""id":"$id"""") &&
(s contains """"class":"main.Main"""")
})
} }
test("buildTarget/run") { _ => test("buildTarget/run") { _ =>
@ -412,14 +370,8 @@ object BuildServerTest extends AbstractServerTest {
|} }""".stripMargin |} }""".stripMargin
) )
assertProcessing("buildTarget/run") assertProcessing("buildTarget/run")
assert(svr.waitForString(10.seconds) { s => assertMessage("build/logMessage", """"message":"Hello World!"""")()
(s contains "build/logMessage") && assertMessage(s""""id":"$id"""", """"statusCode":1""")()
(s contains """"message":"Hello World!"""")
})
assert(svr.waitForString(10.seconds) { s =>
(s contains s""""id":"$id"""") &&
(s contains """"statusCode":1""")
})
} }
test("buildTarget/jvmRunEnvironment") { _ => test("buildTarget/jvmRunEnvironment") { _ =>
@ -433,15 +385,13 @@ object BuildServerTest extends AbstractServerTest {
|}""".stripMargin |}""".stripMargin
) )
assertProcessing("buildTarget/jvmRunEnvironment") assertProcessing("buildTarget/jvmRunEnvironment")
assert { assertMessage(
svr.waitForString(10.seconds) { s => s""""id":"$id"""",
(s contains s""""id":"$id"""") && "jsoniter-scala-core_2.13-2.13.11.jar", // compile dependency
(s contains "jsoniter-scala-core_2.13-2.13.11.jar") && // compile dependency "\"jvmOptions\":[\"Xmx256M\"]",
(s contains "\"jvmOptions\":[\"Xmx256M\"]") && "\"environmentVariables\":{\"KEY\":\"VALUE\"}",
(s contains "\"environmentVariables\":{\"KEY\":\"VALUE\"}") && "/buildserver/run-and-test/" // working directory
(s contains "/buildserver/run-and-test/") // working directory )()
}
}
} }
test("buildTarget/jvmTestEnvironment") { _ => test("buildTarget/jvmTestEnvironment") { _ =>
@ -455,16 +405,13 @@ object BuildServerTest extends AbstractServerTest {
|}""".stripMargin |}""".stripMargin
) )
assertProcessing("buildTarget/jvmTestEnvironment") assertProcessing("buildTarget/jvmTestEnvironment")
assert { assertMessage(
svr.waitForString(10.seconds) { s => s""""id":"$id"""",
(s contains s""""id":"$id"""") && "jsoniter-scala-core_2.13-2.13.11.jar", // compile dependency
// test depends on compile so it has dependencies from both "scalatest_2.13-3.0.8.jar", // test dependency
(s contains "jsoniter-scala-core_2.13-2.13.11.jar") && // compile dependency "\"jvmOptions\":[\"Xmx512M\"]",
(s contains "scalatest_2.13-3.0.8.jar") && // test dependency "\"environmentVariables\":{\"KEY_TEST\":\"VALUE_TEST\"}"
(s contains "\"jvmOptions\":[\"Xmx512M\"]") && )()
(s contains "\"environmentVariables\":{\"KEY_TEST\":\"VALUE_TEST\"}")
}
}
} }
test("buildTarget/scalaTestClasses") { _ => test("buildTarget/scalaTestClasses") { _ =>
@ -477,12 +424,12 @@ object BuildServerTest extends AbstractServerTest {
|} }""".stripMargin |} }""".stripMargin
) )
assertProcessing("buildTarget/scalaTestClasses") assertProcessing("buildTarget/scalaTestClasses")
assert(svr.waitForString(10.seconds) { s => assertMessage(
(s contains s""""id":"$id"""") && s""""id":"$id"""",
(s contains """"tests.FailingTest"""") && """"tests.FailingTest"""",
(s contains """"tests.PassingTest"""") && """"tests.PassingTest"""",
(s contains """"framework":"ScalaTest"""") """"framework":"ScalaTest""""
}) )()
} }
test("buildTarget/test: run all tests") { _ => test("buildTarget/test: run all tests") { _ =>
@ -494,10 +441,7 @@ object BuildServerTest extends AbstractServerTest {
|} }""".stripMargin |} }""".stripMargin
) )
assertProcessing("buildTarget/test") assertProcessing("buildTarget/test")
assert(svr.waitForString(10.seconds) { s => assertMessage(s""""id":"$id"""", """"statusCode":2""")()
(s contains s""""id":"$id"""") &&
(s contains """"statusCode":2""")
})
} }
test("buildTarget/test: run one test class") { _ => test("buildTarget/test: run one test class") { _ =>
@ -518,41 +462,38 @@ object BuildServerTest extends AbstractServerTest {
|} }""".stripMargin |} }""".stripMargin
) )
assertProcessing("buildTarget/test") assertProcessing("buildTarget/test")
assert(svr.waitForString(10.seconds) { s => assertMessage(s""""id":"$id"""", """"statusCode":1""")()
(s contains s""""id":"$id"""") &&
(s contains """"statusCode":1""")
})
} }
test("buildTarget/compile: report error") { _ => test("buildTarget/compile: report error") { _ =>
val buildTarget = buildTargetUri("reportError", "Compile") val buildTarget = buildTargetUri("reportError", "Compile")
compile(buildTarget) compile(buildTarget)
assert(svr.waitForString(10.seconds) { s => assertMessage(
(s contains s""""buildTarget":{"uri":"$buildTarget"}""") && s""""buildTarget":{"uri":"$buildTarget"}""",
(s contains """"severity":1""") && """"severity":1""",
(s contains """"reset":true""") """"reset":true"""
}) )()
} }
test("buildTarget/compile: report warning") { _ => test("buildTarget/compile: report warning") { _ =>
val buildTarget = buildTargetUri("reportWarning", "Compile") val buildTarget = buildTargetUri("reportWarning", "Compile")
compile(buildTarget) compile(buildTarget)
assert(svr.waitForString(10.seconds) { s => assertMessage(
(s contains s""""buildTarget":{"uri":"$buildTarget"}""") && s""""buildTarget":{"uri":"$buildTarget"}""",
(s contains """"severity":2""") && """"severity":2""",
(s contains """"reset":true""") """"reset":true"""
}) )()
} }
test("buildTarget/compile: respond error") { _ => test("buildTarget/compile: respond error") { _ =>
val buildTarget = buildTargetUri("respondError", "Compile") val buildTarget = buildTargetUri("respondError", "Compile")
val id = compile(buildTarget) val id = compile(buildTarget)
assert(svr.waitForString(10.seconds) { s => assertMessage(
s.contains(s""""id":"$id"""") && s""""id":"$id"""",
s.contains(""""error"""") && """"error"""",
s.contains(s""""code":${ErrorCodes.InternalError}""") && s""""code":${ErrorCodes.InternalError}""",
s.contains("custom message") "custom message"
}) )()
} }
test("buildTarget/resources") { _ => test("buildTarget/resources") { _ =>
@ -565,9 +506,7 @@ object BuildServerTest extends AbstractServerTest {
|} }""".stripMargin |} }""".stripMargin
) )
assertProcessing("buildTarget/resources") assertProcessing("buildTarget/resources")
assert(svr.waitForString(10.seconds) { s => assertMessage(s""""id":"$id"""", "util/src/main/resources/")()
(s contains s""""id":"$id"""") && (s contains "util/src/main/resources/")
})
} }
test("buildTarget/outputPaths") { _ => test("buildTarget/outputPaths") { _ =>
@ -601,16 +540,12 @@ object BuildServerTest extends AbstractServerTest {
val testFile = new File(svr.baseDirectory, s"twirlProj/src/main/twirl/main.scala.html") val testFile = new File(svr.baseDirectory, s"twirlProj/src/main/twirl/main.scala.html")
compile(buildTarget) compile(buildTarget)
assert( assertMessage(
svr.waitForString(10.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "main.scala.html",
s.contains("main.scala.html") && """"severity":1""",
s.contains(""""severity":1""") && "not found: value tilte"
s.contains("not found: value tilte") )(message = "should report diagnostic in Twirl file")
},
"should report diagnostic in Twirl file"
)
IO.write( IO.write(
testFile, testFile,
"""|@(title: String, paragraphs: Seq[String]) """|@(title: String, paragraphs: Seq[String])
@ -630,14 +565,14 @@ object BuildServerTest extends AbstractServerTest {
|""".stripMargin |""".stripMargin
) )
compile(buildTarget) compile(buildTarget)
assert.apply( assertMessage(
svr.waitForString(30.seconds) { s => "build/publishDiagnostics",
s.contains("build/publishDiagnostics") && "main.scala.html",
s.contains("main.scala.html") && """"diagnostics":[]""",
s.contains(""""diagnostics":[]""") && """"reset":true"""
s.contains(""""reset":true""") )(
}, duration = 30.seconds,
"should reset diagnostic in Twirl file" message = "should reset diagnostic in Twirl file"
) )
} }
@ -653,11 +588,18 @@ object BuildServerTest extends AbstractServerTest {
sendRequest("build/initialize", params) sendRequest("build/initialize", params)
} }
private def assertProcessing(method: String, debug: Boolean = false): Unit = { private def assertProcessing(method: String, debug: Boolean = false): Unit =
assert(svr.waitForString(10.seconds) { msg => assertMessage("build/logMessage", s""""message":"Processing $method"""")(debug = debug)
def assertMessage(
parts: String*
)(duration: FiniteDuration = 10.seconds, debug: Boolean = false, message: String = ""): Unit = {
def assertion =
svr.waitForString(duration) { msg =>
if (debug) println(msg) if (debug) println(msg)
msg.contains("build/logMessage") && msg.contains(s""""message":"Processing $method"""") parts.forall(msg.contains)
}) }
if (message.nonEmpty) assert.apply(assertion, message) else assert(assertion)
} }
private def reloadWorkspace(): Int = private def reloadWorkspace(): Int =