From 658d9151d8e7c4e6fcbb762a6f39e0409039d38e Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Tue, 18 Sep 2018 22:02:37 +0200 Subject: [PATCH 1/3] Fix #5116: make it easy to sequentially run test With this change, it suffices to use `1` to make all tests sequential: val pool = threadLimit match { case Some(i) => JExecutors.newWorkStealingPool(1) case None => JExecutors.newWorkStealingPool(1) } Previously, `1` doesn't work because the progress bar monopolizes one thread in the thread pool. --- .../dotty/tools/vulpix/ParallelTesting.scala | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 651cbe8073f9..eeec9ae1c240 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -8,6 +8,7 @@ import java.util.HashMap import java.nio.file.StandardCopyOption.REPLACE_EXISTING import java.nio.file.{Files, NoSuchFileException, Path, Paths} import java.util.concurrent.{TimeUnit, TimeoutException, Executors => JExecutors} +import java.util.{Timer, TimerTask} import scala.io.Source import scala.util.control.NonFatal @@ -285,11 +286,11 @@ trait ParallelTesting extends RunnerOrchestration { self => realStderr.println(msg + paddingRight) } - /** A single `Runnable` that prints a progress bar for the curent `Test` */ - private def createProgressMonitor: Runnable = () => { + /** A `TimerTask` that prints a progress bar for the curent `Test` */ + private def updateProgressMonitor: Unit = { val start = System.currentTimeMillis var tCompiled = testSourcesCompleted - while (tCompiled < sourceCount) { + if (tCompiled < sourceCount) { val timestamp = (System.currentTimeMillis - start) / 1000 val progress = (tCompiled.toDouble / sourceCount * 40).toInt @@ -299,16 +300,14 @@ trait ParallelTesting extends RunnerOrchestration { self => (" " * (39 - progress)) + s"] completed ($tCompiled/$sourceCount, $failureCount failed, ${timestamp}s)\r" ) - - Thread.sleep(100) - tCompiled = testSourcesCompleted } - - val timestamp = (System.currentTimeMillis - start) / 1000 - // println, otherwise no newline and cursor at start of line - realStdout.println( - s"[=======================================] completed ($sourceCount/$sourceCount, $failureCount failed, ${timestamp}s)" - ) + else { + val timestamp = (System.currentTimeMillis - start) / 1000 + // println, otherwise no newline and cursor at start of line + realStdout.print( + s"[=======================================] completed ($sourceCount/$sourceCount, $failureCount failed, ${timestamp}s)\r" + ) + } } /** Wrapper function to make sure that the compiler itself did not crash - @@ -465,7 +464,13 @@ trait ParallelTesting extends RunnerOrchestration { self => case None => JExecutors.newWorkStealingPool() } - if (isInteractive && !suppressAllOutput) pool.submit(createProgressMonitor) + val timer = new Timer() + if (isInteractive && !suppressAllOutput) { + val task = new TimerTask { + def run() = updateProgressMonitor + } + timer.schedule(task, 100, 200) + } val eventualResults = filteredSources.map { target => pool.submit(encapsulatedCompilation(target)) @@ -479,6 +484,10 @@ trait ParallelTesting extends RunnerOrchestration { self => throw new TimeoutException("Compiling targets timed out") } + // wait for the timer task to execute once + Thread.sleep(300) + timer.cancel() + eventualResults.foreach(_.get) if (didFail) { From f71ab3ad05f311c905e300e470e32d93bcd967b6 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Wed, 19 Sep 2018 11:29:54 +0200 Subject: [PATCH 2/3] Address review --- .../test/dotty/tools/vulpix/ParallelTesting.scala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index eeec9ae1c240..c3bfbe6b10a1 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -286,8 +286,8 @@ trait ParallelTesting extends RunnerOrchestration { self => realStderr.println(msg + paddingRight) } - /** A `TimerTask` that prints a progress bar for the curent `Test` */ - private def updateProgressMonitor: Unit = { + /** Print a progress bar for the curent `Test` */ + private def updateProgressMonitor(): Unit = { val start = System.currentTimeMillis var tCompiled = testSourcesCompleted if (tCompiled < sourceCount) { @@ -467,7 +467,7 @@ trait ParallelTesting extends RunnerOrchestration { self => val timer = new Timer() if (isInteractive && !suppressAllOutput) { val task = new TimerTask { - def run() = updateProgressMonitor + def run() = updateProgressMonitor() } timer.schedule(task, 100, 200) } @@ -484,12 +484,12 @@ trait ParallelTesting extends RunnerOrchestration { self => throw new TimeoutException("Compiling targets timed out") } - // wait for the timer task to execute once - Thread.sleep(300) - timer.cancel() - eventualResults.foreach(_.get) + // update progress one last time + updateProgressMonitor() + timer.cancel() + if (didFail) { reportFailed() failedTestSources.toSet.foreach(addFailedTest) From 5eb3604ab2b91490d4654a82d3b1394e1ab733ae Mon Sep 17 00:00:00 2001 From: Fengyun Liu Date: Wed, 19 Sep 2018 14:01:56 +0200 Subject: [PATCH 3/3] Address review: only update progress in log mode --- .../test/dotty/tools/vulpix/ParallelTesting.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index c3bfbe6b10a1..c42e1073c237 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -465,7 +465,8 @@ trait ParallelTesting extends RunnerOrchestration { self => } val timer = new Timer() - if (isInteractive && !suppressAllOutput) { + val logProgress = isInteractive && !suppressAllOutput + if (logProgress) { val task = new TimerTask { def run() = updateProgressMonitor() } @@ -486,9 +487,11 @@ trait ParallelTesting extends RunnerOrchestration { self => eventualResults.foreach(_.get) - // update progress one last time - updateProgressMonitor() - timer.cancel() + if (logProgress) { + timer.cancel() + // update progress one last time + updateProgressMonitor() + } if (didFail) { reportFailed()