diff --git a/modules/runtime/src/test/scala/gs/test/v0/runtime/engine/TestEngineTests.scala b/modules/runtime/src/test/scala/gs/test/v0/runtime/engine/TestEngineTests.scala index 5427faf..a90b1fb 100644 --- a/modules/runtime/src/test/scala/gs/test/v0/runtime/engine/TestEngineTests.scala +++ b/modules/runtime/src/test/scala/gs/test/v0/runtime/engine/TestEngineTests.scala @@ -18,15 +18,16 @@ class TestEngineTests extends IOSuite: iotest("should run an engine with no tests") { newEngine().use { obs => + val spanDb = obs.entryPoint.spanDb for suiteExecution <- obs.engine.runSuite( suite = Generators.testSuite(), tests = emptyStream[TestGroupDefinition[IO]] ) - rootSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.RootSpan) + rootSpan <- spanDb.get(EngineConstants.Tracing.RootSpan) results <- obs.reporter.terminateAndGetResults() yield - assertEquals(rootSpan.isDefined, true) + assertEquals(rootSpan.size, 1) assertEquals(results.isEmpty, true) assertEquals(suiteExecution.seen, 0L) assertEquals(suiteExecution.passed, 0L) @@ -36,41 +37,43 @@ class TestEngineTests extends IOSuite: iotest("should run an engine with a single passing test") { newEngine().use { obs => - val g1 = new G1 - val group = g1.compile() + val spanDb = obs.entryPoint.spanDb + val g1 = new G1 + val group = g1.compile() + for suiteExecution <- obs.engine.runSuite( suite = Generators.testSuite(), tests = fs2.Stream.apply(group) ) - rootSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.RootSpan) - groupSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.FullGroup) - beforeGroupSpan <- obs.entryPoint.getSpan( + rootSpan <- spanDb.get(EngineConstants.Tracing.RootSpan) + groupSpan <- spanDb.get(EngineConstants.Tracing.FullGroup) + beforeGroupSpan <- spanDb.get( EngineConstants.Tracing.BeforeGroup ) - afterGroupSpan <- obs.entryPoint.getSpan( + afterGroupSpan <- spanDb.get( EngineConstants.Tracing.AfterGroup ) - inGroupSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.InGroup) - fullTestSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.FullTest) - beforeTestSpan <- obs.entryPoint.getSpan( + inGroupSpan <- spanDb.get(EngineConstants.Tracing.InGroup) + fullTestSpan <- spanDb.get(EngineConstants.Tracing.FullTest) + beforeTestSpan <- spanDb.get( EngineConstants.Tracing.BeforeTest ) - afterTestSpan <- obs.entryPoint.getSpan( + afterTestSpan <- spanDb.get( EngineConstants.Tracing.AfterTest ) - testSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.TestSpan) + testSpan <- spanDb.get(EngineConstants.Tracing.TestSpan) results <- obs.reporter.terminateAndGetResults() yield - assertEquals(rootSpan.isDefined, true) - assertEquals(groupSpan.isDefined, true) - assertEquals(beforeGroupSpan.isDefined, true) - assertEquals(afterGroupSpan.isDefined, true) - assertEquals(inGroupSpan.isDefined, true) - assertEquals(fullTestSpan.isDefined, true) - assertEquals(beforeTestSpan.isDefined, true) - assertEquals(afterTestSpan.isDefined, true) - assertEquals(testSpan.isDefined, true) + assertEquals(rootSpan.size, 1) + assertEquals(groupSpan.size, 1) + assertEquals(beforeGroupSpan.size, 1) + assertEquals(afterGroupSpan.size, 1) + assertEquals(inGroupSpan.size, 1) + assertEquals(fullTestSpan.size, 1) + assertEquals(beforeTestSpan.size, 1) + assertEquals(afterTestSpan.size, 1) + assertEquals(testSpan.size, 1) assertEquals(results.size, 1) assertEquals(suiteExecution.seen, 1L) assertEquals(suiteExecution.passed, 1L) @@ -80,41 +83,43 @@ class TestEngineTests extends IOSuite: iotest("should run an engine with a single failing test") { newEngine().use { obs => - val g2 = new G2 - val group = g2.compile() + val spanDb = obs.entryPoint.spanDb + val g2 = new G2 + val group = g2.compile() for suiteExecution <- obs.engine.runSuite( suite = Generators.testSuite(), tests = fs2.Stream.apply(group) ) - rootSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.RootSpan) - groupSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.FullGroup) - beforeGroupSpan <- obs.entryPoint.getSpan( + rootSpan <- spanDb.get(EngineConstants.Tracing.RootSpan) + groupSpan <- spanDb.get(EngineConstants.Tracing.FullGroup) + beforeGroupSpan <- spanDb.get( EngineConstants.Tracing.BeforeGroup ) - afterGroupSpan <- obs.entryPoint.getSpan( + afterGroupSpan <- spanDb.get( EngineConstants.Tracing.AfterGroup ) - inGroupSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.InGroup) - fullTestSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.FullTest) - beforeTestSpan <- obs.entryPoint.getSpan( + inGroupSpan <- spanDb.get(EngineConstants.Tracing.InGroup) + fullTestSpan <- spanDb.get(EngineConstants.Tracing.FullTest) + beforeTestSpan <- spanDb.get( EngineConstants.Tracing.BeforeTest ) - afterTestSpan <- obs.entryPoint.getSpan( + afterTestSpan <- spanDb.get( EngineConstants.Tracing.AfterTest ) - testSpan <- obs.entryPoint.getSpan(EngineConstants.Tracing.TestSpan) + testSpan <- spanDb.get(EngineConstants.Tracing.TestSpan) results <- obs.reporter.terminateAndGetResults() yield - assertEquals(rootSpan.isDefined, true) - assertEquals(groupSpan.isDefined, true) - assertEquals(beforeGroupSpan.isDefined, true) - assertEquals(afterGroupSpan.isDefined, true) - assertEquals(inGroupSpan.isDefined, true) - assertEquals(fullTestSpan.isDefined, true) - assertEquals(beforeTestSpan.isDefined, true) - assertEquals(afterTestSpan.isDefined, true) - assertEquals(testSpan.isDefined, true) + // TODO rip out a validation function for a full set of stuff. + assertEquals(rootSpan.size, 1) + assertEquals(groupSpan.size, 1) + assertEquals(beforeGroupSpan.size, 1) + assertEquals(afterGroupSpan.size, 1) + assertEquals(inGroupSpan.size, 1) + assertEquals(fullTestSpan.size, 1) + assertEquals(beforeTestSpan.size, 1) + assertEquals(afterTestSpan.size, 1) + assertEquals(testSpan.size, 1) assertEquals(results.size, 1) assertEquals(suiteExecution.seen, 1L) assertEquals(suiteExecution.passed, 0L) diff --git a/modules/test-support/src/test/scala/support/SpanDb.scala b/modules/test-support/src/test/scala/support/SpanDb.scala new file mode 100644 index 0000000..b922f5f --- /dev/null +++ b/modules/test-support/src/test/scala/support/SpanDb.scala @@ -0,0 +1,27 @@ +package support + +import cats.effect.IO +import cats.effect.std.MapRef + +final class SpanDb( + db: MapRef[IO, String, Option[List[TestSpan]]] +): + + def get(spanName: String): IO[List[TestSpan]] = + db(spanName).get.map(_.getOrElse(Nil)) + + def putSpan( + spanName: String, + span: TestSpan + ): IO[Unit] = + db(spanName).update { + case None => Some(List(span)) + case Some(spans) => Some(span :: spans) + } + +object SpanDb: + + def initialize(): IO[SpanDb] = + MapRef[IO, String, List[TestSpan]].map(db => new SpanDb(db)) + +end SpanDb diff --git a/modules/test-support/src/test/scala/support/TestEntryPoint.scala b/modules/test-support/src/test/scala/support/TestEntryPoint.scala index 432a03e..12c0907 100644 --- a/modules/test-support/src/test/scala/support/TestEntryPoint.scala +++ b/modules/test-support/src/test/scala/support/TestEntryPoint.scala @@ -2,27 +2,22 @@ package support import cats.effect.IO import cats.effect.kernel.Resource -import cats.effect.std.MapRef import natchez.EntryPoint import natchez.Kernel import natchez.Span import natchez.Span.Options -// TODO: This doesn't account for multiple spans with the same name. final class TestEntryPoint private ( - spans: MapRef[IO, String, Option[TestSpan]] + val spanDb: SpanDb ) extends EntryPoint[IO]: - def getSpan(name: String): IO[Option[TestSpan]] = - spans(name).get - override def root( name: String, options: Options ): Resource[IO, Span[IO]] = TestSpan - .provisionRoot(name, spans) - .evalTap(span => spans.setKeyValue(name, span)) + .provisionRoot(name, spanDb) + .evalTap(span => spanDb.putSpan(name, span)) override def continue( name: String, @@ -41,7 +36,7 @@ final class TestEntryPoint private ( object TestEntryPoint: def initialize(): IO[TestEntryPoint] = - MapRef.apply[IO, String, TestSpan].map(spans => new TestEntryPoint(spans)) + SpanDb.initialize().map(db => new TestEntryPoint(db)) def provision(): Resource[IO, TestEntryPoint] = Resource.make(initialize())(_ => IO.unit) diff --git a/modules/test-support/src/test/scala/support/TestSpan.scala b/modules/test-support/src/test/scala/support/TestSpan.scala index 7f9aef0..a152233 100644 --- a/modules/test-support/src/test/scala/support/TestSpan.scala +++ b/modules/test-support/src/test/scala/support/TestSpan.scala @@ -15,7 +15,7 @@ final class TestSpan private ( val rawTraceId: String, val rawSpanId: String, baggage: MapRef[IO, String, Option[TraceValue]], - spans: MapRef[IO, String, Option[TestSpan]] + spanDb: SpanDb ) extends Span[IO]: override def put(fields: (String, TraceValue)*): IO[Unit] = @@ -37,8 +37,8 @@ final class TestSpan private ( options: Options ): Resource[IO, Span[IO]] = TestSpan - .provision(name, rawTraceId, TestSpan.makeSpanId(), spans) - .evalTap(span => spans.setKeyValue(name, span)) + .provision(name, rawTraceId, TestSpan.makeSpanId(), spanDb) + .evalTap(span => spanDb.putSpan(name, span)) override def traceId: IO[Option[String]] = IO(Some(rawTraceId)) @@ -50,15 +50,15 @@ object TestSpan: def initializeRoot( name: String, - spans: MapRef[IO, String, Option[TestSpan]] + spanDb: SpanDb ): IO[TestSpan] = - initialize(name, makeTraceId(), makeSpanId(), spans) + initialize(name, makeTraceId(), makeSpanId(), spanDb) def initialize( name: String, traceId: String, spanId: String, - spans: MapRef[IO, String, Option[TestSpan]] + spanDb: SpanDb ): IO[TestSpan] = MapRef.apply[IO, String, TraceValue].map { baggage => new TestSpan( @@ -66,23 +66,23 @@ object TestSpan: rawTraceId = traceId, rawSpanId = spanId, baggage = baggage, - spans = spans + spanDb = spanDb ) } def provisionRoot( name: String, - spans: MapRef[IO, String, Option[TestSpan]] + spanDb: SpanDb ): Resource[IO, TestSpan] = - provision(name, makeTraceId(), makeSpanId(), spans) + provision(name, makeTraceId(), makeSpanId(), spanDb) def provision( name: String, traceId: String, spanId: String, - spans: MapRef[IO, String, Option[TestSpan]] + spanDb: SpanDb ): Resource[IO, TestSpan] = - Resource.make(initialize(name, traceId, spanId, spans))(_ => IO.unit) + Resource.make(initialize(name, traceId, spanId, spanDb))(_ => IO.unit) private def makeTraceId(): String = UUID.randomUUID().toString().filterNot(_ == '-')