From cc4fa583690292d690804144fe92427f0c9f5fdf Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Wed, 8 Apr 2020 12:53:31 -0400 Subject: Add containsCause exception search testing util Adds a new method, chiselTests.Util.containsCause, that will search for a polymorphic exception anywhere in a stack trace. This is useful if exceptions may move around (e.g., if they are suddenly wrapped in a StageError). Signed-off-by: Schuyler Eldridge --- src/test/scala/chiselTests/ChiselSpec.scala | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/test/scala/chiselTests/ChiselSpec.scala') diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index 801dbac2..fa05ab86 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -13,6 +13,7 @@ import firrtl.util.BackendCompilationUtilities import java.io.ByteArrayOutputStream import java.security.Permission import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks +import scala.reflect.ClassTag /** Common utility functions for Chisel unit tests. */ trait ChiselRunners extends Assertions with BackendCompilationUtilities { @@ -284,4 +285,33 @@ trait Utils { } } + /** Run some code extracting an exception cause that matches a type parameter + * @param thunk some code to run + * @tparam A the type of the exception to expect + * @return nothing + * @throws the exception of type parameter A if it was found + */ + def extractCause[A <: Throwable : ClassTag](thunk: => Any): Unit = { + def unrollCauses(a: Throwable): Seq[Throwable] = a match { + case null => Seq.empty + case _ => a +: unrollCauses(a.getCause) + } + + val exceptions: Seq[_ <: Throwable] = try { + thunk + Seq.empty + } catch { + case a: Throwable => unrollCauses(a) + } + + exceptions.collectFirst{ case a: A => a } match { + case Some(a) => throw a + case None => exceptions match { + case Nil => Unit + case h :: t => throw h + } + } + + } + } -- cgit v1.2.3 From c45d8a8419a82e4c4bb438d31bc0e7138c960b9b Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 15 Jun 2020 16:15:56 -0400 Subject: Remove Driver usage in ChiselSpec Signed-off-by: Schuyler Eldridge --- src/test/scala/chiselTests/ChiselSpec.scala | 33 ++++++++--------------------- 1 file changed, 9 insertions(+), 24 deletions(-) (limited to 'src/test/scala/chiselTests/ChiselSpec.scala') diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index fa05ab86..04c35f32 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -7,8 +7,10 @@ import org.scalatest.prop._ import org.scalatest.flatspec.AnyFlatSpec import org.scalacheck._ import chisel3._ +import chisel3.stage.{ChiselGeneratorAnnotation, ChiselStage} import chisel3.testers._ -import firrtl.{AnnotationSeq, CommonOptions, ExecutionOptionsManager, FirrtlExecutionFailure, FirrtlExecutionSuccess, HasFirrtlOptions} +import firrtl.{AnnotationSeq, CommonOptions, EmittedVerilogCircuitAnnotation, ExecutionOptionsManager, FirrtlExecutionFailure, FirrtlExecutionSuccess, HasFirrtlOptions} +import firrtl.annotations.DeletedAnnotation import firrtl.util.BackendCompilationUtilities import java.io.ByteArrayOutputStream import java.security.Permission @@ -35,7 +37,6 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { ): Unit = { assert(!runTester(t, additionalVResources, annotations)) } - def elaborate(t: => RawModule): Unit = Driver.elaborate(() => t) def assertKnownWidth(expected: Int)(gen: => Data): Unit = { assertTesterPasses(new BasicTester { @@ -64,34 +65,18 @@ trait ChiselRunners extends Assertions with BackendCompilationUtilities { }) } - /** Given a generator, return the Firrtl that it generates. - * - * @param t Module generator - * @return Firrtl representation as a String - */ - def generateFirrtl(t: => RawModule): String = Driver.emit(() => t) - /** Compiles a Chisel Module to Verilog * NOTE: This uses the "test_run_dir" as the default directory for generated code. * @param t the generator for the module * @return the Verilog code as a string. */ def compile(t: => RawModule): String = { - val testDir = createTestDirectory(this.getClass.getSimpleName) - val manager = new ExecutionOptionsManager("compile") with HasFirrtlOptions - with HasChiselExecutionOptions { - commonOptions = CommonOptions(targetDirName = testDir.toString) - } - - Driver.execute(manager, () => t) match { - case ChiselExecutionSuccess(_, _, Some(firrtlExecRes)) => - firrtlExecRes match { - case FirrtlExecutionSuccess(_, verilog) => verilog - case FirrtlExecutionFailure(msg) => fail(msg) - } - case ChiselExecutionSuccess(_, _, None) => fail() // This shouldn't happen - case ChiselExecutionFailure(msg) => fail(msg) - } + (new ChiselStage) + .execute(Array("--target-dir", createTestDirectory(this.getClass.getSimpleName).toString), + Seq(ChiselGeneratorAnnotation(() => t))) + .collectFirst { + case DeletedAnnotation(_, EmittedVerilogCircuitAnnotation(a)) => a.value + }.getOrElse(fail("No Verilog circuit was emitted by the FIRRTL compiler!")) } } -- cgit v1.2.3 From b5e59895e13550006fd8e951b7e9483de00f82dd Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 22 Jun 2020 19:59:44 -0400 Subject: Clarify chiselTests.Utils.extractCause Scaladoc Signed-off-by: Schuyler Eldridge --- src/test/scala/chiselTests/ChiselSpec.scala | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src/test/scala/chiselTests/ChiselSpec.scala') diff --git a/src/test/scala/chiselTests/ChiselSpec.scala b/src/test/scala/chiselTests/ChiselSpec.scala index 04c35f32..2ee6fbcf 100644 --- a/src/test/scala/chiselTests/ChiselSpec.scala +++ b/src/test/scala/chiselTests/ChiselSpec.scala @@ -270,11 +270,19 @@ trait Utils { } } - /** Run some code extracting an exception cause that matches a type parameter + /** Run some code and rethrow an exception with a specific type if an exception of that type occurs anywhere in the + * stack trace. + * + * This is useful for "extracting" one exception that may be wrapped by other exceptions. + * + * Example usage: + * {{{ + * a [ChiselException] should be thrownBy extractCause[ChiselException] { /* ... */ } + * }}} + * * @param thunk some code to run - * @tparam A the type of the exception to expect + * @tparam A the type of the exception to extract * @return nothing - * @throws the exception of type parameter A if it was found */ def extractCause[A <: Throwable : ClassTag](thunk: => Any): Unit = { def unrollCauses(a: Throwable): Seq[Throwable] = a match { -- cgit v1.2.3