diff --git a/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala b/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala index 82131c8a82..fcbbffe7e4 100644 --- a/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala +++ b/frontend/src/main/scala/bloop/dap/BloopDebuggee.scala @@ -57,10 +57,6 @@ private final class MainClassDebugAdapter( val javaRuntime: Option[JavaRuntime] = JavaRuntime(env.javaHome.underlying) def name: String = s"${getClass.getSimpleName}(${project.name}, ${mainClass.className})" def start(state: State, listener: DebuggeeListener): Task[ExitStatus] = { - // TODO: https://github.com/scalacenter/bloop/issues/1456 - // Metals used to add the `-J` prefix but it is not needed anymore - // So we cautiously strip it off - val jvmOptions = mainClass.jvmOptions.map(_.stripPrefix("-J")) val runState = Tasks.runJVM( state, project, @@ -68,7 +64,7 @@ private final class MainClassDebugAdapter( project.workspaceDirectory.getOrElse(project.baseDirectory), mainClass.className, mainClass.arguments.toArray, - jvmOptions.toArray, + mainClass.jvmOptions.toArray, mainClass.environmentVariables.getOrElse(Nil), RunMode.Debug ) diff --git a/frontend/src/main/scala/bloop/exec/Forker.scala b/frontend/src/main/scala/bloop/exec/Forker.scala index adc2cd0e54..a43eb70098 100644 --- a/frontend/src/main/scala/bloop/exec/Forker.scala +++ b/frontend/src/main/scala/bloop/exec/Forker.scala @@ -200,6 +200,11 @@ object Forker { val envMap = builder.environment() envMap.putAll(env.asJava) builder.redirectErrorStream(false) + logger.info("Forking process:") + logger.info("- working directory: " + cwd.map(_.toString).getOrElse("null")) + logger.info("- command line: " + cmd.mkString(" ")) + val envFormatted = env.map { case (key, value) => s" $key=$value" }.mkString("\n") + logger.info("- environment variables:\n" + envFormatted) builder.start() }.flatMap { ps => val writeIn = writeToStdIn(ps.getOutputStream) diff --git a/frontend/src/test/scala/bloop/TestSpec.scala b/frontend/src/test/scala/bloop/TestSpec.scala index eb3d711f0d..882b25aeeb 100644 --- a/frontend/src/test/scala/bloop/TestSpec.scala +++ b/frontend/src/test/scala/bloop/TestSpec.scala @@ -29,7 +29,7 @@ abstract class BaseTestSpec(val projectName: String, buildName: String) build.state.test(project) try assert(logger.errors.size == 0) catch { case _: AssertionError => logger.dump() } - assertNoDiff( + assertEndsWith( logger.renderTimeInsensitiveTestInfos, expectedFullTestsOutput ) diff --git a/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala b/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala index d58cebb64a..e140f9b048 100644 --- a/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala +++ b/frontend/src/test/scala/bloop/dap/DebugProtocolSpec.scala @@ -40,7 +40,7 @@ object DebugProtocolSpec extends DebugBspBaseSuite { } yield output } - assertNoDiff(output, "Hello, World!\n") + assertNoDiff(output.linesIterator.toSeq.last, "Hello, World!") } } } @@ -76,8 +76,7 @@ object DebugProtocolSpec extends DebugBspBaseSuite { previousSessionOutput <- previousSession.takeCurrentOutput } yield previousSessionOutput } - - assertNoDiff(output, "") + assert(output.linesIterator.size == 5) } } } @@ -107,21 +106,18 @@ object DebugProtocolSpec extends DebugBspBaseSuite { val project = TestProject(workspace, "p", List(main)) loadBspState(workspace, List(project), logger) { state => - // start debug session and the immediately disconnect from it - val blockingSessionOutput = state.withDebugSession(project, mainClassParams("Main")) { - client => - for { - _ <- client.initialize() - _ <- client.launch(noDebug = true) - _ <- client.initialized - _ <- client.configurationDone() - output <- client.takeCurrentOutput.restartUntil(!_.isEmpty) - _ <- client.disconnect() - } yield output + // start debug session and then immediately disconnect from it + state.withDebugSession(project, mainClassParams("Main")) { client => + for { + _ <- client.initialize() + _ <- client.launch(noDebug = true) + _ <- client.initialized + _ <- client.configurationDone() + _ <- client.takeCurrentOutput.restartUntil(_.contains("Blocking Hello!")) + _ <- client.disconnect() + } yield () } - assertNoDiff(blockingSessionOutput, "Blocking Hello!") - // fix the main class val sources = state.toTestState.getProjectFor(project).sources val mainFile = sources.head.resolve("Main.scala") @@ -139,7 +135,7 @@ object DebugProtocolSpec extends DebugBspBaseSuite { } yield output } - assertNoDiff(output, "Non-blocking Hello!") + assertNoDiff(output.linesIterator.toSeq.last, "Non-blocking Hello!") } } } diff --git a/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala b/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala index ad941acd1a..b71c9dec2c 100644 --- a/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala +++ b/frontend/src/test/scala/bloop/dap/DebugServerSpec.scala @@ -141,10 +141,7 @@ object DebugServerSpec extends DebugBspBaseSuite { } yield { assert(client.socket.isClosed) assertNoDiff( - output.linesIterator - .filterNot(_.contains("ERROR: JDWP Unable to get JNI 1.2 environment")) - .filterNot(_.contains("JDWP exit error AGENT_ERROR_NO_JNI_ENV")) - .mkString(lineSeparator), + output.linesIterator.toSeq.last, "Hello, World!" ) } @@ -177,7 +174,7 @@ object DebugServerSpec extends DebugBspBaseSuite { project, state, arguments = List("hello"), - jvmOptions = List("-J-Dworld=world"), + jvmOptions = List("-Dworld=world"), environmentVariables = List("EXCL=!") ) @@ -194,10 +191,7 @@ object DebugServerSpec extends DebugBspBaseSuite { } yield { assert(client.socket.isClosed) assertNoDiff( - output.linesIterator - .filterNot(_.contains("ERROR: JDWP Unable to get JNI 1.2 environment")) - .filterNot(_.contains("JDWP exit error AGENT_ERROR_NO_JNI_ENV")) - .mkString(lineSeparator), + output.linesIterator.toSeq.takeRight(2).mkString(lineSeparator), "hello\nworld!" ) } @@ -370,7 +364,7 @@ object DebugServerSpec extends DebugBspBaseSuite { } yield { assert(client.socket.isClosed) assertNoDiff( - finalOutput, + finalOutput.linesIterator.toSeq.takeRight(7).mkString(lineSeparator), """|Breakpoint in main method |Breakpoint in hello class |Breakpoint in hello inner class @@ -624,6 +618,7 @@ object DebugServerSpec extends DebugBspBaseSuite { for { port <- startRemoteProcess(buildProject, testState) client <- server.startConnection + initOutput <- client.takeCurrentOutput _ <- client.initialize() _ <- client.attach("localhost", port) breakpoints <- client.setBreakpoints(breakpoints) @@ -639,12 +634,8 @@ object DebugServerSpec extends DebugBspBaseSuite { } yield { assert(client.socket.isClosed) - assertNoDiff(outputOnBreakpoint, "") - - assertNoDiff( - finalOutput, - "" - ) + assertNoDiff(outputOnBreakpoint, initOutput) + assertNoDiff(finalOutput, initOutput) } } } @@ -746,7 +737,7 @@ object DebugServerSpec extends DebugBspBaseSuite { _ <- Task.fromFuture(client.closedPromise.future) } yield { assert(client.socket.isClosed) - assertNoDiff(finalOutput, workspace.toString) + assertNoDiff(finalOutput.linesIterator.toSeq.last, workspace.toString) } } } diff --git a/frontend/src/test/scala/bloop/testing/BaseSuite.scala b/frontend/src/test/scala/bloop/testing/BaseSuite.scala index 3bb9aa6414..939b2b8084 100644 --- a/frontend/src/test/scala/bloop/testing/BaseSuite.scala +++ b/frontend/src/test/scala/bloop/testing/BaseSuite.scala @@ -437,12 +437,11 @@ abstract class BaseSuite extends TestSuite with BloopHelpers { expectedTitle: String )(implicit filename: sourcecode.File, line: sourcecode.Line): Unit = { colored { - DiffAssertions.assertNoDiffOrPrintExpected( + DiffAssertions.assertNoDiffOrPrintObtained( obtained, expected, obtainedTitle, - expectedTitle, - true + expectedTitle ) () } @@ -455,11 +454,20 @@ abstract class BaseSuite extends TestSuite with BloopHelpers { print: Boolean = true )(implicit filename: sourcecode.File, line: sourcecode.Line): Unit = { colored { - DiffAssertions.assertNoDiffOrPrintExpected(obtained, expected, title, title, print) + if (print) DiffAssertions.assertNoDiffOrPrintObtained(obtained, expected, title, title) + else DiffAssertions.assertNoDiff(obtained, expected, title, title) () } } + def assertEndsWith( + obtained: String, + expected: String, + title: String = "" + )(implicit filename: sourcecode.File, line: sourcecode.Line): Unit = { + colored { DiffAssertions.assertEndsWithOrPrintObtained(obtained, expected, title, title) } + } + def colored[T]( thunk: => T )(implicit filename: sourcecode.File, line: sourcecode.Line): T = { diff --git a/frontend/src/test/scala/bloop/testing/DiffAssertions.scala b/frontend/src/test/scala/bloop/testing/DiffAssertions.scala index 0f9f006c88..d4795c0b09 100644 --- a/frontend/src/test/scala/bloop/testing/DiffAssertions.scala +++ b/frontend/src/test/scala/bloop/testing/DiffAssertions.scala @@ -15,43 +15,19 @@ object DiffAssertions { obtainedTitle: String, expectedTitle: String )(implicit source: sourcecode.Line): Unit = { - orPrintObtained( - () => { assertNoDiff(obtained, expected, obtainedTitle, expectedTitle); () }, - obtained - ) + orPrintObtained(obtained) { () => + assertNoDiff(obtained, expected, obtainedTitle, expectedTitle); () + } } - def assertNoDiffOrPrintExpected( + def assertEndsWithOrPrintObtained( obtained: String, expected: String, obtainedTitle: String, - expectedTitle: String, - print: Boolean = true - )(implicit - source: sourcecode.Line - ): Boolean = { - try assertNoDiff(obtained, expected, obtainedTitle, expectedTitle) - catch { - case ex: Exception => - if (print) { - obtained.linesIterator.toList match { - case head +: tail => - val b = new StringBuilder() - b.++=(" \"\"\"|" + head).++=(System.lineSeparator()) - tail.foreach { line => - b.++=(" |") - .++=(line) - .++=(System.lineSeparator()) - } - b.++=(" |\"\"\".stripMargin").++=(System.lineSeparator()) - println(b.mkString) - case head +: Nil => - println(head) - case Nil => - println("obtained is empty") - } - } - throw ex + expectedTitle: String + )(implicit source: sourcecode.Line): Unit = { + orPrintObtained(obtained) { () => + assertEndsWith(obtained, expected, obtainedTitle, expectedTitle); () } } @@ -66,12 +42,22 @@ object DiffAssertions { if (result.isEmpty) true else { throw new TestFailedException( - error2message( - obtained, - expected, - obtainedTitle, - expectedTitle - ) + error2message(obtained, expected, obtainedTitle, expectedTitle) + ) + } + } + + def assertEndsWith( + obtained: String, + expected: String, + obtainedTitle: String, + expectedTitle: String + )(implicit source: sourcecode.Line): Boolean = colored { + if (obtained.isEmpty && !expected.isEmpty) fail("Obtained empty output!") + if (obtained.stripLineEnd.endsWith(expected.stripLineEnd)) true + else { + throw new TestFailedException( + error2message(obtained, expected, obtainedTitle, expectedTitle) ) } } @@ -126,7 +112,7 @@ object DiffAssertions { } } - def orPrintObtained(thunk: () => Unit, obtained: String): Unit = { + def orPrintObtained(obtained: String)(thunk: () => Unit): Unit = { try thunk() catch { case ex: Exception =>