From a11b095f40944bd486f51ab793f3b3eeb6bb4280 Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Tue, 27 Jun 2023 09:21:44 +0200 Subject: [PATCH] Finish tests for event handlers --- .../TSReadinessForEventsChecker.scala | 2 +- .../syncrepometadata/EventHandler.scala | 2 +- .../syncrepometadata/EventHandlerSpec.scala | 81 ++++++++++++------- .../minprojectinfo/EventHandlerSpec.scala | 15 ++++ 4 files changed, 70 insertions(+), 30 deletions(-) diff --git a/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/TSReadinessForEventsChecker.scala b/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/TSReadinessForEventsChecker.scala index f47eeba1aa..0243c72158 100644 --- a/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/TSReadinessForEventsChecker.scala +++ b/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/TSReadinessForEventsChecker.scala @@ -28,7 +28,7 @@ import TSStateChecker.TSState.{MissingDatasets, ReProvisioning, Ready} import io.renku.triplesstore.SparqlQueryTimeRecorder import org.typelevel.log4cats.Logger -private trait TSReadinessForEventsChecker[F[_]] { +private[consumers] trait TSReadinessForEventsChecker[F[_]] { def verifyTSReady: F[Option[EventSchedulingResult]] } diff --git a/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandler.scala b/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandler.scala index b027d62a62..e84cce7f19 100644 --- a/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandler.scala +++ b/triples-generator/src/main/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandler.scala @@ -36,7 +36,7 @@ import io.renku.triplesstore.SparqlQueryTimeRecorder import org.typelevel.log4cats.Logger import processor.EventProcessor -private class EventHandler[F[_]: MonadCancelThrow: Logger]( +private[syncrepometadata] class EventHandler[F[_]: MonadCancelThrow: Logger]( override val categoryName: CategoryName, tsReadinessChecker: TSReadinessForEventsChecker[F], eventDecoder: EventDecoder, diff --git a/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandlerSpec.scala b/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandlerSpec.scala index 76ac3d5f21..08d8fea59d 100644 --- a/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandlerSpec.scala +++ b/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/syncrepometadata/EventHandlerSpec.scala @@ -18,7 +18,8 @@ package io.renku.triplesgenerator.events.consumers.syncrepometadata -import cats.effect.IO +import cats.data.Kleisli +import cats.effect._ import cats.effect.testing.scalatest.AsyncIOSpec import cats.syntax.all._ import io.renku.events.consumers.ConsumersModelGenerators.eventSchedulingResults @@ -27,6 +28,7 @@ import io.renku.generators.Generators.Implicits._ import io.renku.graph.model.projects import io.renku.interpreters.TestLogger import io.renku.lock.Lock +import io.renku.triplesgenerator.TgLockDB.TsWriteLock import io.renku.triplesgenerator.api.events.Generators.syncRepoMetadataEvents import io.renku.triplesgenerator.events.consumers.TSReadinessForEventsChecker import io.renku.triplesgenerator.events.consumers.syncrepometadata.processor.EventProcessor @@ -34,29 +36,48 @@ import org.scalamock.scalatest.AsyncMockFactory import org.scalatest.matchers.should import org.scalatest.wordspec.AsyncWordSpec -//TODO class EventHandlerSpec extends AsyncWordSpec with AsyncIOSpec with should.Matchers with AsyncMockFactory { "handlingDefinition.decode" should { "be EventDecoder.decode" in { + val tc = new TestCase - expectTSReadinessCheckerCall + tc.expectTSReadinessCheckerCall - handler.createHandlingDefinition().decode shouldBe EventDecoder.decode + tc.handler.createHandlingDefinition().decode shouldBe EventDecoder.decode } } "handlingDefinition.process" should { "be the EventProcessor.process" in { + val tc = new TestCase + tc.expectTSReadinessCheckerCall - expectTSReadinessCheckerCall + syncRepoMetadataEvents[IO].map(_.generateOne).flatMap { event => + (tc.eventProcessor.process _).expects(event).returns(().pure[IO]) + + tc.handler.createHandlingDefinition().process(event).assertNoException + } + } + + "lock while executing" in { + val test = Ref.unsafe[IO, Int](0) + val tc = new TestCase { + override val tsWriteLock: TsWriteLock[IO] = + Lock.from[IO, projects.Path](Kleisli(_ => test.update(_ + 1)))(Kleisli(_ => test.update(_ + 1))) + } + + tc.expectTSReadinessCheckerCall syncRepoMetadataEvents[IO].map(_.generateOne).flatMap { event => - (eventProcessor.process _).expects(event).returns(().pure[IO]) + (tc.eventProcessor.process _).expects(event).returns(().pure[IO]) - handler.createHandlingDefinition().process(event).asserting(_ shouldBe ()) + tc.handler.createHandlingDefinition().process(event).map { r => + r shouldBe () + test.get.unsafeRunSync() shouldBe 2 + } } } } @@ -64,40 +85,44 @@ class EventHandlerSpec extends AsyncWordSpec with AsyncIOSpec with should.Matche "handlingDefinition.precondition" should { "be the TSReadinessForEventsChecker.verifyTSReady" in { + val tc = new TestCase + tc.expectTSReadinessCheckerCall - expectTSReadinessCheckerCall - - handler.createHandlingDefinition().precondition.asserting(_ shouldBe readinessCheckerResult) + tc.handler.createHandlingDefinition().precondition.asserting(_ shouldBe tc.readinessCheckerResult) } } "handlingDefinition.onRelease" should { "not be defined" in { + val tc = new TestCase + tc.expectTSReadinessCheckerCall - expectTSReadinessCheckerCall - - handler.createHandlingDefinition().onRelease shouldBe None + tc.handler.createHandlingDefinition().onRelease shouldBe None } } - private implicit val logger: TestLogger[IO] = TestLogger[IO]() + class TestCase { + implicit val logger: TestLogger[IO] = TestLogger[IO]() - private lazy val tsReadinessChecker = mock[TSReadinessForEventsChecker[IO]] - private lazy val readinessCheckerResult = eventSchedulingResults.generateSome + lazy val tsReadinessChecker = mock[TSReadinessForEventsChecker[IO]] + lazy val readinessCheckerResult = eventSchedulingResults.generateSome - private def expectTSReadinessCheckerCall = - (() => tsReadinessChecker.verifyTSReady).expects().returns(readinessCheckerResult.pure[IO]) + def expectTSReadinessCheckerCall = + (() => tsReadinessChecker.verifyTSReady).expects().returns(readinessCheckerResult.pure[IO]) - private lazy val eventProcessor = mock[EventProcessor[IO]] + lazy val eventProcessor = mock[EventProcessor[IO]] - private lazy val handler = - new EventHandler[IO]( - categoryName, - tsReadinessChecker, - EventDecoder, - eventProcessor, - mock[ProcessExecutor[IO]], - Lock.none[IO, projects.Path] - ) + def tsWriteLock: TsWriteLock[IO] = Lock.none[IO, projects.Path] + + lazy val handler = + new EventHandler[IO]( + categoryName, + tsReadinessChecker, + EventDecoder, + eventProcessor, + mock[ProcessExecutor[IO]], + tsWriteLock + ) + } } diff --git a/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/tsprovisioning/minprojectinfo/EventHandlerSpec.scala b/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/tsprovisioning/minprojectinfo/EventHandlerSpec.scala index 1000b4454e..dcbc7b47d0 100644 --- a/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/tsprovisioning/minprojectinfo/EventHandlerSpec.scala +++ b/triples-generator/src/test/scala/io/renku/triplesgenerator/events/consumers/tsprovisioning/minprojectinfo/EventHandlerSpec.scala @@ -20,6 +20,7 @@ package io.renku.triplesgenerator.events.consumers package tsprovisioning.minprojectinfo import CategoryGenerators._ +import cats.data.Kleisli import cats.effect.{IO, Ref} import cats.syntax.all._ import io.circe.Encoder @@ -34,6 +35,7 @@ import io.renku.graph.model.projects import io.renku.interpreters.TestLogger import io.renku.lock.Lock import io.renku.testtools.IOSpec +import io.renku.triplesgenerator.TgLockDB.TsWriteLock import org.scalamock.scalatest.MockFactory import org.scalatest.matchers.should import org.scalatest.wordspec.AnyWordSpec @@ -64,6 +66,19 @@ class EventHandlerSpec extends AnyWordSpec with IOSpec with MockFactory with sho handler.createHandlingDefinition().process(event).unsafeRunSync() shouldBe () } + + "lock while executing" in new TestCase { + val test = Ref.unsafe[IO, Int](0) + override val tsWriteLock: TsWriteLock[IO] = + Lock.from[IO, projects.Path](Kleisli(_ => test.update(_ + 1)))(Kleisli(_ => test.update(_ + 1))) + + val event = minProjectInfoEvents.generateOne + + (eventProcessor.process _).expects(event).returns(().pure[IO]) + + handler.createHandlingDefinition().process(event).unsafeRunSync() shouldBe () + test.get.unsafeRunSync() shouldBe 2 + } } "handlingDefinition.precondition" should {