From 4e8eb320a882124630fb50d53d3d8c3721d9bd4e Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 22 Mar 2017 12:47:27 +0100 Subject: Consolidate test reporters in `TestReporter` always dumping log file --- .../test/dotty/tools/dotc/CompilationTests.scala | 3 +- .../test/dotty/tools/dotc/ParallelTesting.scala | 52 +++------- .../dotty/tools/dotc/reporting/TestReporter.scala | 107 +++++++++++++++++---- .../dotc/transform/PatmatExhaustivityTest.scala | 4 +- 4 files changed, 107 insertions(+), 59 deletions(-) (limited to 'compiler/test') diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 8df415a37..7f0f84049 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -249,7 +249,8 @@ object CompilationTests { } val noCheckOptions = Array( - "-pagewidth", "120" + "-pagewidth", "120", + "-color:never" ) val checkOptions = Array( diff --git a/compiler/test/dotty/tools/dotc/ParallelTesting.scala b/compiler/test/dotty/tools/dotc/ParallelTesting.scala index 1652dd9c4..5c9718ce2 100644 --- a/compiler/test/dotty/tools/dotc/ParallelTesting.scala +++ b/compiler/test/dotty/tools/dotc/ParallelTesting.scala @@ -3,20 +3,22 @@ package tools package dotc import java.io.{ File => JFile } -import scala.io.Source - -import core.Contexts._ -import reporting.{ Reporter, UniqueMessagePositions, HideNonSensicalMessages, MessageRendering } -import reporting.diagnostic.MessageContainer -import interfaces.Diagnostic.ERROR +import java.text.SimpleDateFormat +import java.util.HashMap import java.lang.reflect.InvocationTargetException import java.nio.file.StandardCopyOption.REPLACE_EXISTING import java.nio.file.{ Files, Path, Paths, NoSuchFileException } import java.util.concurrent.{ Executors => JExecutors, TimeUnit, TimeoutException } + +import scala.io.Source import scala.util.control.NonFatal import scala.util.Try import scala.collection.mutable -import java.util.HashMap + +import core.Contexts._ +import reporting.{ Reporter, TestReporter } +import reporting.diagnostic.MessageContainer +import interfaces.Diagnostic.ERROR trait ParallelTesting { @@ -281,7 +283,7 @@ trait ParallelTesting { (errorMap, expectedErrors) } - def getMissingAnnotations(errorMap: HashMap[String, Integer], reporterErrors: List[MessageContainer]) = !reporterErrors.forall { error => + def getMissingAnnotations(errorMap: HashMap[String, Integer], reporterErrors: Iterator[MessageContainer]) = !reporterErrors.forall { error => val getter = if (error.pos.exists) { val fileName = error.pos.source.file.toString s"$fileName:${error.pos.line}" @@ -318,7 +320,7 @@ trait ParallelTesting { val (errorMap, expectedErrors) = errorMapAndExpected(compilationUnits.toArray.flatten) val reporters = compilationUnits.map(files => compile(files.filter(isCompilable), flags, true, times, outDir)) val actualErrors = reporters.foldLeft(0)(_ + _.errorCount) - val errors = reporters.flatMap(_.errors) + val errors = reporters.iterator.flatMap(_.errors) (expectedErrors, actualErrors, () => getMissingAnnotations(errorMap, errors), errorMap) } } @@ -347,33 +349,7 @@ trait ParallelTesting { } } - private class DaftReporter(suppress: Boolean) - extends Reporter with UniqueMessagePositions with HideNonSensicalMessages - with MessageRendering { - private var _errors: List[MessageContainer] = Nil - def errors = _errors - - private var _summary = new StringBuilder - def echoSummary(msg: String): this.type = { - _summary.append(msg) - this - } - - def printSummary(): this.type = { - val msg = _summary.toString - if (msg.nonEmpty) println(msg) - this - } - - override def doReport(m: MessageContainer)(implicit ctx: Context) = { - if (m.level == ERROR) { - _errors = m :: _errors - if (!suppress) System.err.println(messageAndPos(m.contained, m.pos, diagnosticLevel(m))) - } - } - } - - private def compile(files0: Array[JFile], flags0: Array[String], suppressErrors: Boolean, times: Int, targetDir: JFile): DaftReporter = { + private def compile(files0: Array[JFile], flags0: Array[String], suppressErrors: Boolean, times: Int, targetDir: JFile): TestReporter = { val flags = flags0 ++ Array("-d", targetDir.getAbsolutePath) @@ -418,7 +394,7 @@ trait ParallelTesting { val javaCompiledBefore = compileWithJavac(javaFiles) // Then we compile the scala files: - val reporter = new DaftReporter(suppress = suppressErrors) + val reporter = TestReporter.parallelReporter(logLevel = if (suppressErrors) ERROR + 1 else ERROR) val driver = if (times == 1) new Driver { def newCompiler(implicit ctx: Context) = new Compiler } else new Driver { @@ -428,7 +404,7 @@ trait ParallelTesting { (emptyReporter /: (1 to n)) ((_, i) => op(i)) private def echoSummary(rep: Reporter, msg: String)(implicit ctx: Context) = - rep.asInstanceOf[DaftReporter].echoSummary(msg) + rep.asInstanceOf[TestReporter].echoSummary(msg) override def doCompile(comp: Compiler, files: List[String])(implicit ctx: Context) = ntimes(times) { run => diff --git a/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala b/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala index 169908c4f..4fc7e5dfe 100644 --- a/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala +++ b/compiler/test/dotty/tools/dotc/reporting/TestReporter.scala @@ -2,35 +2,61 @@ package dotty.tools package dotc package reporting +import java.io.{ PrintWriter, File => JFile, FileOutputStream } +import java.text.SimpleDateFormat +import java.util.Date + import scala.collection.mutable + import util.SourcePosition import core.Contexts._ import Reporter._ -import java.io.PrintWriter import diagnostic.{ Message, MessageContainer, NoExplanation } import diagnostic.messages._ +import interfaces.Diagnostic.{ ERROR, WARNING, INFO } -class TestReporter(writer: PrintWriter) extends Reporter -with UniqueMessagePositions with HideNonSensicalMessages { - +class TestReporter protected (outWriter: PrintWriter, protected val filePrintln: String => Unit, logLevel: Int) extends Reporter +with UniqueMessagePositions with HideNonSensicalMessages with MessageRendering { import MessageContainer._ - /** maximal number of error messages to be printed */ - protected def ErrorLimit = 100 + protected final val _errorBuf = mutable.ArrayBuffer.empty[MessageContainer] + final def errors: Iterator[MessageContainer] = _errorBuf.iterator - def printPos(pos: SourcePosition): Unit = + final def inlineInfo(pos: SourcePosition): String = if (pos.exists) { - if (pos.outer.exists) { - writer.println(s"\ninlined at ${pos.outer}:\n") - printPos(pos.outer) - } + if (pos.outer.exists) + s"\ninlined at ${pos.outer}:\n" + inlineInfo(pos.outer) + else "" + } + else "" + + final def printSummary(): this.type = { + val msg = _summary.toString + if (msg.nonEmpty) { + outWriter.println(msg) + filePrintln(msg) } + this + } + + private var _summary = new StringBuilder + final def echoSummary(msg: String): this.type = { + _summary.append(msg) + this + } /** Prints the message with the given position indication. */ - def printMessageAndPos(msg: String, pos: SourcePosition)(implicit ctx: Context): Unit = { - val posStr = s"${pos.line + 1}: " - writer.println(posStr + msg) - printPos(pos) + def printMessageAndPos(m: MessageContainer, extra: String)(implicit ctx: Context): Unit = { + val msg = messageAndPos(m.contained, m.pos, diagnosticLevel(m)) + val extraInfo = inlineInfo(m.pos) + + if (m.level >= logLevel) { + outWriter.println(msg) + if (extraInfo.nonEmpty) outWriter.println(extraInfo) + } + + filePrintln(msg) + if (extraInfo.nonEmpty) filePrintln(extraInfo) } override def doReport(m: MessageContainer)(implicit ctx: Context): Unit = { @@ -41,11 +67,56 @@ with UniqueMessagePositions with HideNonSensicalMessages { } m match { - case m: Error => - printMessageAndPos(m.contained.kind + extra, m.pos) + case m: Error => { + _errorBuf.append(m) + printMessageAndPos(m, extra) + } case w: Warning => - printMessageAndPos(w.contained.kind + extra, w.pos) + printMessageAndPos(w, extra) case _ => } } } + +object TestReporter { + private[this] val logWriter = { + val df = new SimpleDateFormat("yyyy-MM-dd-HH:mm") + val timestamp = df.format(new Date) + new PrintWriter(new FileOutputStream(new JFile(s"../tests-$timestamp.log"), true)) + } + + def parallelReporter(logLevel: Int): TestReporter = new TestReporter( + new PrintWriter(Console.err, true), + str => logWriter.synchronized { + logWriter.println(str) + logWriter.flush() + }, + logLevel + ) + + def reporter(logLevel: Int): TestReporter = new TestReporter( + new PrintWriter(Console.err, true), + logWriter.println, + logLevel + ) + + def simplifiedReporter(writer: PrintWriter): TestReporter = new TestReporter( + writer, + logWriter.println, + WARNING + ) { + /** Prints the message with the given position indication in a simplified manner */ + override def printMessageAndPos(m: MessageContainer, extra: String)(implicit ctx: Context): Unit = { + val msg = s"${m.pos.line + 1}: " + m.contained.kind + extra + val extraInfo = inlineInfo(m.pos) + + writer.println(msg) + filePrintln(msg) + + if (extraInfo.nonEmpty) { + writer.println(extraInfo) + filePrintln(extraInfo) + } + } + } +} diff --git a/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala b/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala index 96ab241fd..eff86e6e7 100644 --- a/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala +++ b/compiler/test/dotty/tools/dotc/transform/PatmatExhaustivityTest.scala @@ -17,7 +17,7 @@ class PatmatExhaustivityTest { private def compileFile(file: File) = { val stringBuffer = new StringWriter() - val reporter = new TestReporter(new PrintWriter(stringBuffer)) + val reporter = TestReporter.simplifiedReporter(new PrintWriter(stringBuffer)) try { Main.process((file.getPath::options).toArray, reporter, null) @@ -40,7 +40,7 @@ class PatmatExhaustivityTest { /** A single test with multiple files grouped in a folder */ private def compileDir(file: File) = { val stringBuffer = new StringWriter() - val reporter = new TestReporter(new PrintWriter(stringBuffer)) + val reporter = TestReporter.simplifiedReporter(new PrintWriter(stringBuffer)) val files = Directory(file.getPath).list.toList .filter(f => f.extension == "scala" || f.extension == "java" ) -- cgit v1.2.3