This is an automated email from the ASF dual-hosted git repository.

fanningpj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-pekko-http.git


The following commit(s) were added to refs/heads/main by this push:
     new 8b6ec62ca Revert "!sbt Use multiJvmPlugin from pekko." (#298)
8b6ec62ca is described below

commit 8b6ec62cab6e1b5f5af8d459174b147a92e78c11
Author: kerr <[email protected]>
AuthorDate: Wed Aug 9 16:23:08 2023 +0800

    Revert "!sbt Use multiJvmPlugin from pekko." (#298)
    
    This reverts commit 1f5b25de4fee337aa5995917fd1649f36cee5aa8.
---
 build.sbt                 |   2 +-
 project/Jvm.scala         | 125 ----------
 project/MultiNode.scala   |   6 +-
 project/SbtMultiJvm.scala | 623 ----------------------------------------------
 project/plugins.sbt       |   2 +-
 5 files changed, 5 insertions(+), 753 deletions(-)

diff --git a/build.sbt b/build.sbt
index 0e66f77d1..2245528d1 100644
--- a/build.sbt
+++ b/build.sbt
@@ -11,7 +11,7 @@ import ValidatePullRequest._
 import 
net.bzzt.reproduciblebuilds.ReproducibleBuildsPlugin.reproducibleBuildsCheckResolver
 import PekkoDependency._
 import Dependencies.{ h2specExe, h2specName }
-import MultiJvmPlugin.MultiJvmKeys.MultiJvm
+import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys.MultiJvm
 import java.nio.file.Files
 import java.nio.file.attribute.{ PosixFileAttributeView, PosixFilePermission }
 
diff --git a/project/Jvm.scala b/project/Jvm.scala
deleted file mode 100644
index 5afd85f59..000000000
--- a/project/Jvm.scala
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * license agreements; and to You under the Apache License, version 2.0:
- *
- *   https://www.apache.org/licenses/LICENSE-2.0
- *
- * This file is part of the Apache Pekko project, which was derived from Akka.
- */
-
-/*
- * Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
- */
-
-import java.io.File
-import java.lang.{ ProcessBuilder => JProcessBuilder }
-
-import sbt._
-import scala.sys.process.Process
-
-object Jvm {
-  def startJvm(
-      javaBin: File,
-      jvmOptions: Seq[String],
-      runOptions: Seq[String],
-      logger: Logger,
-      connectInput: Boolean) = {
-    forkJava(javaBin, jvmOptions ++ runOptions, logger, connectInput)
-  }
-
-  def forkJava(javaBin: File, options: Seq[String], logger: Logger, 
connectInput: Boolean) = {
-    val java = javaBin.toString
-    val command = (java :: options.toList).toArray
-    val builder = new JProcessBuilder(command: _*)
-    Process(builder).run(logger, connectInput)
-  }
-
-  /**
-   * check if the current operating system is some OS
-   */
-  def isOS(os: String) =
-    try {
-      System.getProperty("os.name").toUpperCase.startsWith(os.toUpperCase)
-    } catch {
-      case _: Throwable => false
-    }
-
-  /**
-   * convert to proper path for the operating system
-   */
-  def osPath(path: String) = if (isOS("WINDOWS")) Process(Seq("cygpath", 
path)).lineStream.mkString else path
-
-  def getPodName(hostAndUser: String, sbtLogger: Logger): String = {
-    val command: Array[String] =
-      Array("kubectl", "get", "pods", "-l", s"host=$hostAndUser", 
"--no-headers", "-o", "name")
-    val builder = new JProcessBuilder(command: _*)
-    sbtLogger.debug("Jvm.getPodName about to run " + command.mkString(" "))
-    val podName = Process(builder).!!
-    sbtLogger.debug("Jvm.getPodName podName is " + podName)
-    podName.stripPrefix("pod/").stripSuffix("\n")
-  }
-
-  def syncJar(jarName: String, hostAndUser: String, remoteDir: String, 
sbtLogger: Logger): Process = {
-    val podName = getPodName(hostAndUser, sbtLogger)
-    val command: Array[String] =
-      Array("kubectl", "exec", podName, "--", "/bin/bash", "-c", s"rm -rf 
$remoteDir && mkdir -p $remoteDir")
-    val builder = new JProcessBuilder(command: _*)
-    sbtLogger.debug("Jvm.syncJar about to run " + command.mkString(" "))
-    val process = Process(builder).run(sbtLogger, false)
-    if (process.exitValue() == 0) {
-      val command: Array[String] = Array("kubectl", "cp", osPath(jarName), 
podName + ":" + remoteDir + "/")
-      val builder = new JProcessBuilder(command: _*)
-      sbtLogger.debug("Jvm.syncJar about to run " + command.mkString(" "))
-      Process(builder).run(sbtLogger, false)
-    } else {
-      process
-    }
-  }
-
-  def forkRemoteJava(
-      java: String,
-      jvmOptions: Seq[String],
-      appOptions: Seq[String],
-      jarName: String,
-      hostAndUser: String,
-      remoteDir: String,
-      logger: Logger,
-      connectInput: Boolean,
-      sbtLogger: Logger): Process = {
-    val podName = getPodName(hostAndUser, sbtLogger)
-    sbtLogger.debug("About to use java " + java)
-    val shortJarName = new File(jarName).getName
-    val javaCommand = List(List(java), jvmOptions, List("-cp", shortJarName), 
appOptions).flatten
-    val command = Array(
-      "kubectl",
-      "exec",
-      podName,
-      "--",
-      "/bin/bash",
-      "-c",
-      ("cd " :: (remoteDir :: (" ; " :: javaCommand))).mkString(" "))
-    sbtLogger.debug("Jvm.forkRemoteJava about to run " + command.mkString(" "))
-    val builder = new JProcessBuilder(command: _*)
-    Process(builder).run(logger, connectInput)
-  }
-}
-
-class JvmBasicLogger(name: String) extends BasicLogger {
-  def jvm(message: String) = "[%s] %s".format(name, message)
-
-  def log(level: Level.Value, message: => String) = System.out.synchronized {
-    System.out.println(jvm(message))
-  }
-
-  def trace(t: => Throwable) = System.out.synchronized {
-    val traceLevel = getTrace
-    if (traceLevel >= 0) System.out.print(StackTrace.trimmed(t, traceLevel))
-  }
-
-  def success(message: => String) = log(Level.Info, message)
-  def control(event: ControlEvent.Value, message: => String) = log(Level.Info, 
message)
-
-  def logAll(events: Seq[LogEvent]) = System.out.synchronized { 
events.foreach(log) }
-}
-
-final class JvmLogger(name: String) extends JvmBasicLogger(name)
diff --git a/project/MultiNode.scala b/project/MultiNode.scala
index 5b2d0e5e1..f1350e0db 100644
--- a/project/MultiNode.scala
+++ b/project/MultiNode.scala
@@ -11,8 +11,8 @@
  * Copyright (C) 2009-2020 Lightbend Inc. <https://www.lightbend.com>
  */
 
-import MultiJvmPlugin.MultiJvmKeys.multiJvmCreateLogger
-import MultiJvmPlugin.MultiJvmKeys._
+import com.typesafe.sbt.SbtMultiJvm
+import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys._
 import sbt._
 import sbt.Keys._
 
@@ -57,7 +57,7 @@ object MultiNode extends AutoPlugin {
   }
 
   private val multiJvmSettings =
-    MultiJvmPlugin.multiJvmSettings ++
+    SbtMultiJvm.multiJvmSettings ++
     inConfig(MultiJvm)(org.scalafmt.sbt.ScalafmtPlugin.scalafmtConfigSettings) 
++
     inConfig(MultiJvm)(Seq(
       MultiJvm / jvmOptions := defaultMultiJvmOptions,
diff --git a/project/SbtMultiJvm.scala b/project/SbtMultiJvm.scala
deleted file mode 100644
index b05cf8470..000000000
--- a/project/SbtMultiJvm.scala
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * license agreements; and to You under the Apache License, version 2.0:
- *
- *   https://www.apache.org/licenses/LICENSE-2.0
- *
- * This file is part of the Apache Pekko project, which was derived from Akka.
- */
-
-/*
- * Copyright (C) 2009-2022 Lightbend Inc. <https://www.lightbend.com>
- */
-
-import scala.sys.process.Process
-import sjsonnew.BasicJsonProtocol._
-import sbt._
-import Keys._
-
-import java.io.File
-import java.lang.Boolean.getBoolean
-import sbtassembly.AssemblyPlugin.assemblySettings
-import sbtassembly.{ AssemblyKeys, MergeStrategy }
-import AssemblyKeys._
-
-import java.net.{ InetSocketAddress, Socket }
-import java.util.concurrent.TimeUnit
-
-object MultiJvmPlugin extends AutoPlugin {
-
-  case class Options(jvm: Seq[String], extra: String => Seq[String], run: 
String => Seq[String])
-
-  object MultiJvmKeys {
-    val MultiJvm = config("multi-jvm").extend(Test)
-
-    val multiJvmMarker = SettingKey[String]("multi-jvm-marker")
-
-    val multiJvmTests = TaskKey[Map[String, Seq[String]]]("multi-jvm-tests")
-    val multiJvmTestNames = TaskKey[Seq[String]]("multi-jvm-test-names")
-
-    val multiJvmApps = TaskKey[Map[String, Seq[String]]]("multi-jvm-apps")
-    val multiJvmAppNames = TaskKey[Seq[String]]("multi-jvm-app-names")
-
-    val multiJvmJavaCommand = TaskKey[File]("multi-jvm-java-command")
-
-    val jvmOptions = TaskKey[Seq[String]]("jvm-options") // TODO: shouldn't 
that be regular `javaOptions`?
-    val extraOptions = SettingKey[String => Seq[String]]("extra-options")
-    val multiJvmCreateLogger = TaskKey[String => 
Logger]("multi-jvm-create-logger")
-
-    val scalatestRunner = SettingKey[String]("scalatest-runner")
-    val scalatestOptions = SettingKey[Seq[String]]("scalatest-options")
-    val scalatestClasspath = TaskKey[Classpath]("scalatest-classpath")
-    val scalatestScalaOptions = TaskKey[String => 
Seq[String]]("scalatest-scala-options")
-    val scalatestMultiNodeScalaOptions = TaskKey[String => 
Seq[String]]("scalatest-multi-node-scala-options")
-    val multiTestOptions = TaskKey[Options]("multi-test-options")
-    val multiNodeTestOptions = TaskKey[Options]("multi-node-test-options")
-
-    val appScalaOptions = TaskKey[String => Seq[String]]("app-scala-options")
-    val multiRunOptions = TaskKey[Options]("multi-run-options")
-
-    val multiRunCopiedClassLocation = 
SettingKey[File]("multi-run-copied-class-location")
-
-    val multiJvmTestJar = TaskKey[String]("multi-jvm-test-jar")
-    val multiJvmTestJarName = TaskKey[String]("multi-jvm-test-jar-name")
-
-    val multiNodeTest = TaskKey[Unit]("multi-node-test")
-    val multiNodeExecuteTests = 
TaskKey[Tests.Output]("multi-node-execute-tests")
-    val multiNodeTestOnly = InputKey[Unit]("multi-node-test-only")
-
-    val multiNodeHosts = SettingKey[Seq[String]]("multi-node-hosts")
-    val multiNodeHostsFileName = 
SettingKey[String]("multi-node-hosts-file-name")
-    val multiNodeProcessedHosts = TaskKey[(IndexedSeq[String], 
IndexedSeq[String])]("multi-node-processed-hosts")
-    val multiNodeTargetDirName = 
SettingKey[String]("multi-node-target-dir-name")
-    val multiNodeJavaName = SettingKey[String]("multi-node-java-name")
-
-    // TODO fugly workaround for now
-    val multiNodeWorkAround =
-      TaskKey[(String, (IndexedSeq[String], IndexedSeq[String]), 
String)]("multi-node-workaround")
-  }
-
-  val autoImport = MultiJvmKeys
-
-  import MultiJvmKeys._
-
-  override def requires = plugins.JvmPlugin
-
-  override def projectConfigurations = Seq(MultiJvm)
-
-  override def projectSettings = multiJvmSettings
-
-  private[this] def noTestsMessage(scoped: ScopedKey[_])(implicit display: 
Show[ScopedKey[_]]): String =
-    "No tests to run for " + display.show(scoped)
-
-  lazy val multiJvmSettings: Seq[Def.Setting[_]] =
-    inConfig(MultiJvm)(Defaults.configSettings ++ internalMultiJvmSettings)
-
-  // 
https://github.com/sbt/sbt/blob/v0.13.15/main/actions/src/main/scala/sbt/Tests.scala#L296-L298
-  private[this] def showResults(log: Logger, results: Tests.Output, 
noTestsMessage: => String): Unit =
-    TestResultLogger.Default.copy(printNoTests = 
TestResultLogger.const(_.info(noTestsMessage))).run(log, results, "")
-
-  private def internalMultiJvmSettings =
-    assemblySettings ++ Seq(
-      multiJvmMarker := "MultiJvm",
-      loadedTestFrameworks := (Test / loadedTestFrameworks).value,
-      definedTests := Defaults.detectTests.value,
-      multiJvmTests := collectMultiJvmTests(
-        definedTests.value,
-        multiJvmMarker.value,
-        (MultiJvm / testOptions).value,
-        streams.value.log),
-      multiJvmTestNames := 
multiJvmTests.map(_.keys.toSeq).storeAs(multiJvmTestNames).triggeredBy(compile).value,
-      multiJvmApps := collectMultiJvm(discoveredMainClasses.value, 
multiJvmMarker.value),
-      multiJvmAppNames := 
multiJvmApps.map(_.keys.toSeq).storeAs(multiJvmAppNames).triggeredBy(compile).value,
-      multiJvmJavaCommand := javaCommand(javaHome.value, "java"),
-      jvmOptions := Seq.empty,
-      extraOptions := { (name: String) =>
-        Seq.empty
-      },
-      multiJvmCreateLogger := { (name: String) =>
-        new JvmLogger(name)
-      },
-      scalatestRunner := "org.scalatest.tools.Runner",
-      scalatestOptions := defaultScalatestOptions,
-      scalatestClasspath := 
managedClasspath.value.filter(_.data.name.contains("scalatest")),
-      multiRunCopiedClassLocation := new File(target.value, 
"multi-run-copied-libraries"),
-      scalatestScalaOptions := scalaOptionsForScalatest(
-        scalatestRunner.value,
-        scalatestOptions.value,
-        fullClasspath.value,
-        multiRunCopiedClassLocation.value),
-      scalatestMultiNodeScalaOptions := scalaMultiNodeOptionsForScalatest(
-        scalatestRunner.value,
-        scalatestOptions.value),
-      multiTestOptions := Options(jvmOptions.value, extraOptions.value, 
scalatestScalaOptions.value),
-      multiNodeTestOptions := Options(jvmOptions.value, extraOptions.value, 
scalatestMultiNodeScalaOptions.value),
-      appScalaOptions := scalaOptionsForApps(fullClasspath.value),
-      connectInput := true,
-      multiRunOptions := Options(jvmOptions.value, extraOptions.value, 
appScalaOptions.value),
-      executeTests := multiJvmExecuteTests.value,
-      testOnly := multiJvmTestOnly.evaluated,
-      test := showResults(streams.value.log, executeTests.value, "No tests to 
run for MultiJvm"),
-      run := multiJvmRun.evaluated,
-      runMain := multiJvmRun.evaluated,
-      // TODO try to make sure that this is only generated on a need to have 
basis
-      multiJvmTestJar := (assembly / 
assemblyOutputPath).map(_.getAbsolutePath).dependsOn(assembly).value,
-      multiJvmTestJarName := (assembly / 
assemblyOutputPath).value.getAbsolutePath,
-      multiNodeTest := {
-        implicit val display = Project.showContextKey(state.value)
-        showResults(streams.value.log, multiNodeExecuteTests.value, 
noTestsMessage(resolvedScoped.value))
-      },
-      multiNodeExecuteTests := multiNodeExecuteTestsTask.value,
-      multiNodeTestOnly := multiNodeTestOnlyTask.evaluated,
-      multiNodeHosts := Seq.empty,
-      multiNodeHostsFileName := "multi-node-test.hosts",
-      multiNodeProcessedHosts := processMultiNodeHosts(
-        multiNodeHosts.value,
-        multiNodeHostsFileName.value,
-        multiNodeJavaName.value,
-        streams.value),
-      multiNodeTargetDirName := "multi-node-test",
-      multiNodeJavaName := "java",
-      // TODO there must be a way get at keys in the tasks that I just don't 
get
-      multiNodeWorkAround := (multiJvmTestJar.value, 
multiNodeProcessedHosts.value, multiNodeTargetDirName.value),
-      // here follows the assembly parts of the config
-      // don't run the tests when creating the assembly
-      assembly / test := {},
-      // we want everything including the tests and test frameworks
-      assembly / fullClasspath := (MultiJvm / fullClasspath).value,
-      // the first class wins just like a classpath
-      // just concatenate conflicting text files
-      assembly / assemblyMergeStrategy := {
-        case n if n.endsWith(".class")  => MergeStrategy.first
-        case n if n.endsWith(".txt")    => MergeStrategy.concat
-        case n if n.endsWith("NOTICE")  => MergeStrategy.concat
-        case n if n.endsWith("LICENSE") => MergeStrategy.concat
-        case n                          => (assembly / 
assemblyMergeStrategy).value.apply(n)
-      },
-      assembly / assemblyJarName := {
-        name.value + "_" + scalaVersion.value + "-" + version.value + 
"-multi-jvm-assembly.jar"
-      })
-
-  def collectMultiJvmTests(
-      discovered: Seq[TestDefinition],
-      marker: String,
-      testOptions: Seq[TestOption],
-      log: Logger): Map[String, Seq[String]] = {
-    val testFilters = new collection.mutable.ListBuffer[String => Boolean]
-    val excludeTestsSet = new collection.mutable.HashSet[String]
-
-    for (option <- testOptions) {
-      option match {
-        case Tests.Exclude(excludedTests) => excludeTestsSet ++= excludedTests
-        case Tests.Filter(filterTestsIn)  => testFilters += filterTestsIn
-        case _                            => // do nothing since the intention 
is only to filter tests
-      }
-    }
-
-    if (excludeTestsSet.nonEmpty) {
-      log.debug(excludeTestsSet.mkString("Excluding tests: \n\t", "\n\t", ""))
-    }
-
-    def includeTest(test: TestDefinition): Boolean = {
-      !excludeTestsSet.contains(test.name) && testFilters.forall(filter => 
filter(test.name)) && test.name.contains(
-        marker)
-    }
-
-    val groupedTests: Map[String, List[TestDefinition]] =
-      discovered.filter(includeTest).toList.distinct.groupBy(test => 
multiName(test.name, marker))
-
-    groupedTests.map {
-      case (key, values) =>
-        val totalNodes = sys.props.get(marker + "." + key + 
".nrOfNodes").getOrElse(values.size.toString).toInt
-        val sortedClasses = values.map(_.name).sorted
-        val totalClasses = sortedClasses.padTo(totalNodes, sortedClasses.last)
-        (key, totalClasses)
-    }
-  }
-
-  def collectMultiJvm(discovered: Seq[String], marker: String): Map[String, 
Seq[String]] = {
-    val found = discovered.filter(_.contains(marker)).groupBy(multiName(_, 
marker))
-    found.map {
-      case (key, values) =>
-        val totalNodes = sys.props.get(marker + "." + key + 
".nrOfNodes").getOrElse(values.size.toString).toInt
-        val sortedClasses = values.sorted
-        val totalClasses = sortedClasses.padTo(totalNodes, sortedClasses.last)
-        (key, totalClasses)
-    }
-  }
-
-  def multiName(name: String, marker: String) = name.split(marker).head
-
-  def multiSimpleName(name: String) = name.split("\\.").last
-
-  def javaCommand(javaHome: Option[File], name: String): File = {
-    val home = javaHome.getOrElse(new File(System.getProperty("java.home")))
-    new File(new File(home, "bin"), name)
-  }
-
-  def defaultScalatestOptions: Seq[String] = {
-    if (getBoolean("sbt.log.noformat")) Seq("-oW") else Seq("-o")
-  }
-
-  def scalaOptionsForScalatest(
-      runner: String,
-      options: Seq[String],
-      fullClasspath: Classpath,
-      multiRunCopiedClassDir: File) = {
-    val directoryBasedClasspathEntries = 
fullClasspath.files.filter(_.isDirectory)
-    // Copy over just the jars to this folder.
-    fullClasspath.files
-      .filter(_.isFile)
-      .foreach(classpathFile =>
-        IO.copyFile(classpathFile, new File(multiRunCopiedClassDir, 
classpathFile.getName), true))
-    val cp =
-      directoryBasedClasspathEntries.absString + File.pathSeparator + 
multiRunCopiedClassDir.getAbsolutePath + File.separator + "*"
-    (testClass: String) => { Seq("-cp", cp, runner, "-s", testClass) ++ 
options }
-  }
-
-  def scalaMultiNodeOptionsForScalatest(runner: String, options: Seq[String]) 
= { (testClass: String) =>
-    { Seq(runner, "-s", testClass) ++ options }
-  }
-
-  def scalaOptionsForApps(classpath: Classpath) = {
-    val cp = classpath.files.absString
-    (mainClass: String) => Seq("-cp", cp, mainClass)
-  }
-
-  def multiJvmExecuteTests: Def.Initialize[sbt.Task[Tests.Output]] = Def.task {
-    runMultiJvmTests(
-      multiJvmTests.value,
-      multiJvmMarker.value,
-      multiJvmJavaCommand.value,
-      multiTestOptions.value,
-      sourceDirectory.value,
-      multiJvmCreateLogger.value,
-      streams.value.log)
-  }
-
-  def multiJvmTestOnly: Def.Initialize[sbt.InputTask[Unit]] =
-    InputTask.createDyn(loadForParser(multiJvmTestNames)((s, i) => 
Defaults.testOnlyParser(s, i.getOrElse(Nil)))) {
-      Def.task {
-        case (selection, _extraOptions) =>
-          val s = streams.value
-          val options = multiTestOptions.value
-          val opts = options.copy(extra = (s: String) => { options.extra(s) ++ 
_extraOptions })
-          val filters = selection.map(GlobFilter(_))
-          val tests = multiJvmTests.value.filterKeys(name => 
filters.exists(_.accept(name)))
-          Def.task {
-            val results = runMultiJvmTests(
-              tests,
-              multiJvmMarker.value,
-              multiJvmJavaCommand.value,
-              opts,
-              sourceDirectory.value,
-              multiJvmCreateLogger.value,
-              s.log)
-            showResults(s.log, results, "No tests to run for MultiJvm")
-          }
-      }
-    }
-
-  def runMultiJvmTests(
-      tests: Map[String, Seq[String]],
-      marker: String,
-      javaBin: File,
-      options: Options,
-      srcDir: File,
-      createLogger: String => Logger,
-      log: Logger): Tests.Output = {
-    val results =
-      if (tests.isEmpty)
-        List()
-      else
-        tests.map {
-          case (_name, classes) => multi(_name, classes, marker, javaBin, 
options, srcDir, false, createLogger, log)
-        }
-    Tests.Output(
-      Tests.overall(results.map(_._2)),
-      Map.empty,
-      results.map(result => Tests.Summary("multi-jvm", result._1)))
-  }
-
-  def multiJvmRun: Def.Initialize[sbt.InputTask[Unit]] =
-    InputTask.createDyn(loadForParser(multiJvmAppNames)((s, i) => runParser(s, 
i.getOrElse(Nil)))) {
-      Def.task {
-        val s = streams.value
-        val apps = multiJvmApps.value
-        val j = multiJvmJavaCommand.value
-        val c = connectInput.value
-        val dir = sourceDirectory.value
-        val options = multiRunOptions.value
-        val marker = multiJvmMarker.value
-        val createLogger = multiJvmCreateLogger.value
-
-        result => {
-          val classes = apps.getOrElse(result, Seq.empty)
-          Def.task {
-            if (classes.isEmpty) s.log.info("No apps to run.")
-            else multi(result, classes, marker, j, options, dir, c, 
createLogger, s.log)
-          }
-        }
-      }
-    }
-
-  def runParser: (State, Seq[String]) => complete.Parser[String] = {
-    import complete.DefaultParsers._
-    (state, appClasses) => Space ~> token(NotSpace.examples(appClasses.toSet))
-  }
-
-  def multi(
-      name: String,
-      classes: Seq[String],
-      marker: String,
-      javaBin: File,
-      options: Options,
-      srcDir: File,
-      input: Boolean,
-      createLogger: String => Logger,
-      log: Logger): (String, sbt.TestResult) = {
-    val logName = "* " + name
-    log.info(logName)
-    val classesHostsJavas = getClassesHostsJavas(classes, IndexedSeq.empty, 
IndexedSeq.empty, "")
-    val hosts = classesHostsJavas.map(_._2)
-    val processes = classes.zipWithIndex.map {
-      case (testClass, index) =>
-        val className = multiSimpleName(testClass)
-        val jvmName = "JVM-" + (index + 1) + "-" + className
-        val jvmLogger = createLogger(jvmName)
-        val optionsFile = (srcDir ** (className + ".opts")).get.headOption
-        val optionsFromFile =
-          optionsFile.map(IO.read(_)).map(_.trim.replace("\\n", " 
").split("\\s+").toList).getOrElse(Seq.empty[String])
-        val multiNodeOptions = getMultiNodeCommandLineOptions(hosts, index, 
classes.size)
-        val allJvmOptions = options.jvm ++ multiNodeOptions ++ optionsFromFile 
++ options.extra(className)
-        val runOptions = options.run(testClass)
-        val connectInput = input && index == 0
-        log.debug("Starting %s for %s".format(jvmName, testClass))
-        log.debug("  with JVM options: %s".format(allJvmOptions.mkString(" ")))
-        val testClass2Process = (testClass, Jvm.startJvm(javaBin, 
allJvmOptions, runOptions, jvmLogger, connectInput))
-        if (index == 0) {
-          log.debug("%s for %s 's started as `Controller`, waiting before can 
be connected for clients.".format(jvmName,
-            testClass))
-          val controllerHost = hosts.head
-          val serverPort: Int = Integer.getInteger("multinode.server-port", 
4711)
-          waitingBeforeConnectable(controllerHost, serverPort, 
TimeUnit.SECONDS.toMillis(20L))
-        }
-        testClass2Process
-    }
-    processExitCodes(name, processes, log)
-  }
-
-  private def waitingBeforeConnectable(host: String, port: Int, 
timeoutInMillis: Long): Unit = {
-    val inetSocketAddress = new InetSocketAddress(host, port)
-    def telnet(addr: InetSocketAddress, timeout: Int): Boolean = {
-      val socket: Socket = new Socket()
-      try {
-        socket.connect(inetSocketAddress, timeout)
-        socket.isConnected
-      } catch {
-        case _: Exception => false
-      } finally {
-        socket.close()
-      }
-    }
-
-    val startTime = System.currentTimeMillis()
-    var connectivity = false
-    while (!connectivity && (System.currentTimeMillis() - startTime < 
timeoutInMillis)) {
-      connectivity = telnet(inetSocketAddress, 1000)
-      TimeUnit.MILLISECONDS.sleep(100)
-    }
-  }
-
-  def processExitCodes(name: String, processes: Seq[(String, Process)], log: 
Logger): (String, sbt.TestResult) = {
-    val exitCodes = processes.map {
-      case (testClass, process) => (testClass, process.exitValue())
-    }
-    val failures = exitCodes.flatMap {
-      case (testClass, exit) if exit > 0 => Some("Failed: " + testClass)
-      case _                             => None
-    }
-    failures.foreach(log.error(_))
-    (name, if (failures.nonEmpty) TestResult.Failed else TestResult.Passed)
-  }
-
-  def multiNodeExecuteTestsTask: Def.Initialize[sbt.Task[Tests.Output]] = 
Def.task {
-    val (_jarName, (hostsAndUsers, javas), targetDir) = 
multiNodeWorkAround.value
-    runMultiNodeTests(
-      multiJvmTests.value,
-      multiJvmMarker.value,
-      multiNodeJavaName.value,
-      multiNodeTestOptions.value,
-      sourceDirectory.value,
-      _jarName,
-      hostsAndUsers,
-      javas,
-      targetDir,
-      multiJvmCreateLogger.value,
-      streams.value.log)
-  }
-
-  def multiNodeTestOnlyTask: Def.Initialize[InputTask[Unit]] =
-    InputTask.createDyn(loadForParser(multiJvmTestNames)((s, i) => 
Defaults.testOnlyParser(s, i.getOrElse(Nil)))) {
-      Def.task {
-        case (selected, _extraOptions) =>
-          val options = multiNodeTestOptions.value
-          val (_jarName, (hostsAndUsers, javas), targetDir) = 
multiNodeWorkAround.value
-          val s = streams.value
-          val opts = options.copy(extra = (s: String) => { options.extra(s) ++ 
_extraOptions })
-          val tests = selected.flatMap { name =>
-            multiJvmTests.value.get(name).map((name, _))
-          }
-          Def.task {
-            val results = runMultiNodeTests(
-              tests.toMap,
-              multiJvmMarker.value,
-              multiNodeJavaName.value,
-              opts,
-              sourceDirectory.value,
-              _jarName,
-              hostsAndUsers,
-              javas,
-              targetDir,
-              multiJvmCreateLogger.value,
-              s.log)
-            showResults(s.log, results, "No tests to run for MultiNode")
-          }
-      }
-    }
-
-  def runMultiNodeTests(
-      tests: Map[String, Seq[String]],
-      marker: String,
-      java: String,
-      options: Options,
-      srcDir: File,
-      jarName: String,
-      hostsAndUsers: IndexedSeq[String],
-      javas: IndexedSeq[String],
-      targetDir: String,
-      createLogger: String => Logger,
-      log: Logger): Tests.Output = {
-    val results =
-      if (tests.isEmpty)
-        List()
-      else
-        tests.map {
-          case (_name, classes) =>
-            multiNode(
-              _name,
-              classes,
-              marker,
-              java,
-              options,
-              srcDir,
-              false,
-              jarName,
-              hostsAndUsers,
-              javas,
-              targetDir,
-              createLogger,
-              log)
-        }
-    Tests.Output(
-      Tests.overall(results.map(_._2)),
-      Map.empty,
-      results.map(result => Tests.Summary("multi-jvm", result._1)))
-  }
-
-  def multiNode(
-      name: String,
-      classes: Seq[String],
-      marker: String,
-      defaultJava: String,
-      options: Options,
-      srcDir: File,
-      input: Boolean,
-      testJar: String,
-      hostsAndUsers: IndexedSeq[String],
-      javas: IndexedSeq[String],
-      targetDir: String,
-      createLogger: String => Logger,
-      log: Logger): (String, sbt.TestResult) = {
-    val logName = "* " + name
-    log.info(logName)
-    val classesHostsJavas = getClassesHostsJavas(classes, hostsAndUsers, 
javas, defaultJava)
-    val hosts = classesHostsJavas.map(_._2)
-    // TODO move this out, maybe to the hosts string as well?
-    val syncProcesses = classesHostsJavas.map {
-      case ((testClass, hostAndUser, java)) =>
-        (testClass + " sync", Jvm.syncJar(testJar, hostAndUser, targetDir, 
log))
-    }
-    val syncResult = processExitCodes(name, syncProcesses, log)
-    if (syncResult._2 == TestResult.Passed) {
-      val processes = classesHostsJavas.zipWithIndex.map {
-        case ((testClass, hostAndUser, java), index) => {
-          val jvmName = "JVM-" + (index + 1)
-          val jvmLogger = createLogger(jvmName)
-          val className = multiSimpleName(testClass)
-          val optionsFile = (srcDir ** (className + ".opts")).get.headOption
-          val optionsFromFile = optionsFile
-            .map(IO.read(_))
-            .map(_.trim.replace("\\n", " ").split("\\s+").toList)
-            .getOrElse(Seq.empty[String])
-          val multiNodeOptions = getMultiNodeCommandLineOptions(hosts, index, 
classes.size)
-          val allJvmOptions = options.jvm ++ optionsFromFile ++ 
options.extra(className) ++ multiNodeOptions
-          val runOptions = options.run(testClass)
-          val connectInput = input && index == 0
-          log.debug("Starting %s for %s".format(jvmName, testClass))
-          log.debug("  with JVM options: %s".format(allJvmOptions.mkString(" 
")))
-          (
-            testClass,
-            Jvm.forkRemoteJava(
-              java,
-              allJvmOptions,
-              runOptions,
-              testJar,
-              hostAndUser,
-              targetDir,
-              jvmLogger,
-              connectInput,
-              log))
-        }
-      }
-      processExitCodes(name, processes, log)
-    } else {
-      syncResult
-    }
-  }
-
-  private def padSeqOrDefaultTo(seq: IndexedSeq[String], default: String, max: 
Int): IndexedSeq[String] = {
-    val realSeq = if (seq.isEmpty) IndexedSeq(default) else seq
-    if (realSeq.size >= max)
-      realSeq
-    else
-      (0 until (max - realSeq.size)).foldLeft(realSeq)((mySeq, pos) => mySeq 
:+ realSeq(pos % realSeq.size))
-  }
-
-  private def getClassesHostsJavas(
-      classes: Seq[String],
-      hostsAndUsers: IndexedSeq[String],
-      javas: IndexedSeq[String],
-      defaultJava: String): IndexedSeq[(String, String, String)] = {
-    val max = classes.length
-    val tuple = (
-      classes.toIndexedSeq,
-      padSeqOrDefaultTo(hostsAndUsers, "localhost", max),
-      padSeqOrDefaultTo(javas, defaultJava, max))
-    tuple.zipped.map { case (className: String, hostAndUser: String, _java: 
String) => (className, hostAndUser, _java) }
-  }
-
-  private def getMultiNodeCommandLineOptions(hosts: Seq[String], index: Int, 
maxNodes: Int): Seq[String] = {
-    Seq(
-      "-Dmultinode.max-nodes=" + maxNodes,
-      "-Dmultinode.server-host=" + hosts.head.split("@").last,
-      "-Dmultinode.host=" + hosts(index).split("@").last,
-      "-Dmultinode.index=" + index)
-  }
-
-  private def processMultiNodeHosts(
-      hosts: Seq[String],
-      hostsFileName: String,
-      defaultJava: String,
-      s: Types.Id[Keys.TaskStreams]): (IndexedSeq[String], IndexedSeq[String]) 
= {
-    val hostsFile = new File(hostsFileName)
-    val theHosts: IndexedSeq[String] =
-      if (hosts.isEmpty) {
-        if (hostsFile.exists && hostsFile.canRead) {
-          s.log.info("Using hosts defined in file " + 
hostsFile.getAbsolutePath)
-          IO.readLines(hostsFile).map(_.trim).filter(_.nonEmpty).toIndexedSeq
-        } else
-          hosts.toIndexedSeq
-      } else {
-        if (hostsFile.exists && hostsFile.canRead)
-          s.log.info(
-            "Hosts from setting " + multiNodeHosts.key.label + " is overriding 
file " + hostsFile.getAbsolutePath)
-        hosts.toIndexedSeq
-      }
-
-    theHosts.map { x =>
-      val elems = x.split(":").toList.take(2).padTo(2, defaultJava)
-      (elems.head, elems(1))
-    }.unzip
-  }
-}
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 571b5e6c4..a44919bb8 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -15,7 +15,7 @@ resolvers ++= Resolver.sonatypeOssRepos("releases") // to 
more quickly obtain pa
 // which is used by plugin "org.kohsuke" % "github-api" % "1.68"
 resolvers += Resolver.jcenterRepo
 
-addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.1")
+addSbtPlugin("com.typesafe.sbt" % "sbt-multi-jvm" % "0.4.0")
 addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.0")
 addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")
 addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1")


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to