From 2c3cf37fe63574eb19b6812e4d29387470cb6ae0 Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Fri, 24 Nov 2023 22:12:04 +0100 Subject: [PATCH] Implement first integration test for health routes --- app/src/main/scala/App.scala | 12 ++--- app/src/test/scala/IntegrationTest.scala | 57 ++++++++++++++++++++++++ build.sbt | 5 ++- project/Dependencies.scala | 6 +-- 4 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 app/src/test/scala/IntegrationTest.scala diff --git a/app/src/main/scala/App.scala b/app/src/main/scala/App.scala index 62cb060..8269deb 100644 --- a/app/src/main/scala/App.scala +++ b/app/src/main/scala/App.scala @@ -18,16 +18,16 @@ object App extends IOApp.Simple: for config <- Resource.eval(AppConfig.load) _ <- Resource.eval(KamonInitiator.apply.init(config.kamon)) - _ <- FishnetApp(config).run() + _ <- Resource.eval(Logger[IO].info(s"Starting lila-fishnet with config: $config")) + res <- AppResources.instance(config.redis) + _ <- FishnetApp(res, config).run() yield () -class FishnetApp(config: AppConfig)(using Logger[IO]): +class FishnetApp(res: AppResources, config: AppConfig)(using Logger[IO]): def run(): Resource[IO, Unit] = for - res <- AppResources.instance(config.redis) - _ <- Resource.eval(Logger[IO].info(s"Starting lila-fishnet with config: $config")) - lilaClient = LilaClient(res.redisPubsub) - monitor = Monitor.apply + lilaClient <- Resource.pure(LilaClient(res.redisPubsub)) + monitor = Monitor.apply executor <- Resource.eval(Executor.instance(lilaClient, monitor)) workListenerJob = RedisSubscriberJob(executor, res.redisPubsub) cleanJob = CleanJob(executor) diff --git a/app/src/test/scala/IntegrationTest.scala b/app/src/test/scala/IntegrationTest.scala new file mode 100644 index 0000000..a1237c5 --- /dev/null +++ b/app/src/test/scala/IntegrationTest.scala @@ -0,0 +1,57 @@ +package lila.fishnet + +import cats.effect.IO +import cats.effect.kernel.Resource +import cats.syntax.all.* +import com.comcast.ip4s.{ Host, Port } +import com.dimafeng.testcontainers.GenericContainer +import org.http4s.ember.client.EmberClientBuilder +import org.testcontainers.containers.wait.strategy.Wait +import org.typelevel.log4cats.Logger +import org.typelevel.log4cats.noop.NoOpLogger +import org.http4s.circe.CirceEntityDecoder.* +import weaver.* +import lila.fishnet.http.HealthCheck.AppStatus + +object IntegrationTest extends SimpleIOSuite: + + given Logger[IO] = NoOpLogger[IO] + private def resource: Resource[IO, Unit] = + for + redis <- RedisContainer.startRedis + defaultConfig <- Resource.eval(AppConfig.load) + config = defaultConfig.copy(redis = redis) + _ <- Resource.eval(IO.println(s"Starting lila-fishnet with config: $config")) + res <- AppResources.instance(config.redis) + _ <- FishnetApp(res, config).run() + yield () + + test("health check should return healthy"): + (resource >> client) + .use( + _.expect[AppStatus]("http://localhost:9665/health") + .map(expect.same(_, AppStatus(true))) + ) + + private def client = EmberClientBuilder.default[IO].build + +object RedisContainer: + + private val REDIS_PORT = 6379 + private val redisContainer = + val start = IO( + GenericContainer( + "redis:6-alpine", + exposedPorts = Seq(REDIS_PORT), + waitStrategy = Wait.forListeningPort() + ) + ) + .flatTap(cont => IO(cont.start())) + Resource.make(start)(cont => IO(cont.stop())) + + def parseConfig(redis: GenericContainer): RedisConfig = + println(s"redis: ${redis.host} ${redis.containerIpAddress} ${redis.envMap}") + RedisConfig(Host.fromString(redis.host).get, Port.fromInt(redis.mappedPort(REDIS_PORT)).get) + + def startRedis: Resource[IO, RedisConfig] = + redisContainer.map(parseConfig) diff --git a/build.sbt b/build.sbt index 052e89e..a6ae620 100644 --- a/build.sbt +++ b/build.sbt @@ -33,12 +33,15 @@ lazy val app = project log4Cats, logback, redis, + circeLiteral, chessTestKit, munit, munitScalacheck, weaver, weaverScalaCheck, - circeLiteral + testContainers, + log4CatsNoop, + http4sClient ) ) .enablePlugins(JavaAppPackaging) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 7289270..64b463d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -48,10 +48,10 @@ object Dependencies { val chessTestKit = "org.lichess" %% "scalachess-test-kit" % V.chess % Test val log4CatsNoop = "org.typelevel" %% "log4cats-noop" % "2.6.0" % Test - val testContainers = "com.dimafeng" %% "testcontainers-scala-redis" % "0.41.0" % Test - val weaver = "com.disneystreaming" %% "weaver-cats" % "0.8.3" % Test - val weaverScalaCheck = "com.disneystreaming" %% "weaver-scalacheck" % "0.8.3" % Test val munit = "org.scalameta" %% "munit" % V.munit % Test val munitScalacheck = "org.scalameta" %% "munit-scalacheck" % V.munit % Test + val testContainers = "com.dimafeng" %% "testcontainers-scala-core" % "0.41.0" % Test + val weaver = "com.disneystreaming" %% "weaver-cats" % "0.8.3" % Test + val weaverScalaCheck = "com.disneystreaming" %% "weaver-scalacheck" % "0.8.3" % Test }