All Downloads are FREE. Search and download functionalities are using the official Maven repository.

utest.runner.MasterRunner.scala Maven / Gradle / Ivy

There is a newer version: 0.7.11
Show newest version
package utest
package runner
//import acyclic.file
import java.util.concurrent.atomic.{AtomicInteger, AtomicReference}

import sbt.testing.TaskDef

import scala.annotation.tailrec

final class MasterRunner(args: Array[String],
                         remoteArgs: Array[String],
                         testClassLoader: ClassLoader,
                         setup: () => Unit,
                         teardown: () => Unit)
                         extends BaseRunner(args, remoteArgs, testClassLoader){
  setup()
  val results = new AtomicReference[List[String]](Nil)
  val total = new AtomicInteger(0)
  val success = new AtomicInteger(0)
  val failure = new AtomicInteger(0)
  val failures = new AtomicReference[List[String]](Nil)
  val traces = new AtomicReference[List[String]](Nil)

  @tailrec def addResult(r: String): Unit = {
    val old = results.get()
    if (!results.compareAndSet(old, r :: old)) addResult(r)
  }

  @tailrec final def addFailure(r: String): Unit = {
    val old = failures.get()
    if (!failures.compareAndSet(old, r :: old)) addFailure(r)
  }
  @tailrec final def addTrace(r: String): Unit = {
    val old = traces.get()
    if (!traces.compareAndSet(old, r :: old)) addTrace(r)
  }

  def addTotal(v: Int): Unit = total.addAndGet(v)
  def incSuccess(): Unit = success.incrementAndGet()
  def incFailure(): Unit = failure.incrementAndGet()

  def successCount: Int = success.get
  def failureCount: Int = failure.get
  def totalCount: Int = total.get

  def done(): String = {
    teardown()
    val header = "-----------------------------------Results-----------------------------------"

    val body = results.get.mkString("\n")

    val failureMsg = if (failures.get() == Nil) ""
    else Seq(
      Console.RED + "Failures:",
      failures.get()
              .zip(traces.get())
              // We pre-pending to a list, so need to reverse to make the order correct
              .reverse
              // ignore those with an empty trace, e.g. utest.SkippedOuterFailures,
              // since those are generally just spam (we already can see the outer failure)
              .collect{case (f, t) if t != "" => f + ("\n" + t).replace("\n", "\n"+Console.RED)}
              .mkString("\n")
    ).mkString("\n")
    Seq(
      header,
      body,
      failureMsg,
      s"Tests: $total",
      s"Passed: $success",
      s"Failed: $failure"
    ).mkString("\n")
  }

  def receiveMessage(msg: String): Option[String] = {
    def badMessage = sys.error("bad message: " + msg)
    msg(0) match {
      case 'h' => // hello message. nothing special to do
      case 'r' => addResult(msg.tail)
      case 'f' => addFailure(msg.tail)
      case 't' => addTotal(msg.tail.toInt)
      case 'c' => addTrace(msg.tail)
      case 'i' => msg(1) match {
        case 's' => incSuccess()
        case 'f' => incFailure()
        case _ => badMessage
      }
      case _ => badMessage
    }

    val countMsg = s"$successCount,$failureCount,$totalCount"
    Some(countMsg)
  }

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy