Repository: 7mind/izumi
Pull request #1150 (2020-07-19 18:02:17)

Update scalamock to 5.0.0
Updates [org.scalamock:scalamock](https://github.com/paulbutcher/ScalaMock) from 4.4.0 to 5.0.0.
[GitHub Release Notes](https://github.com/paulbutcher/ScalaMock/releases/tag/5.0.0)

I'll automatically update this PR to resolve conflicts as long as you don't change it yourself.

If you'd like to skip this version, you can just close this PR. If you have any feedback, just mention me in the comments below.

Configure Scala Steward for your repository with a [`.scala-steward.conf`](https://github.com/fthomas/scala-steward/blob/b7d2c9bed4486a3a55b140f6c6827b7e6897079a/docs/repo-specific-configuration.md) file.

Have a fantastic day writing Scala!

<details>
<summary>Ignore future updates</summary>

Add this to your `.scala-steward.conf` file to ignore future updates of this dependency:
```
updates.ignore = [ { groupId = "org.scalamock", artifactId = "scalamock" } ]
```
</details>

labels: test-library-update, semver-major


Patch:
diff --git a/.scalafmt.conf b/.scalafmt.conf
index 9544e19bd..07362e869 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,4 +1,4 @@
-version = "2.6.3"
+version = "2.6.4"
 edition = "2020-05"
 project.git = true
 
diff --git a/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala b/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala
index 7d80d8eca..f9515cfcd 100644
--- a/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala
+++ b/distage/distage-framework-api/src/main/scala/izumi/distage/framework/model/IntegrationCheck.scala
@@ -11,7 +11,7 @@ import izumi.fundamentals.platform.integration.ResourceCheck
   * Not wrapped in `F` because you shouldn't use async or any non-trivial effect inside IntegrationCheck,
   * it must be _trivial_ and return near-instantly. The execution will be suspended in F.
   */
-trait IntegrationCheck {
+trait IntegrationCheck[F[_]] {
   /** This method must never throw, on error return [[ResourceCheck.Failure]] instead * */
-  def resourcesAvailable(): ResourceCheck
+  def resourcesAvailable(): F[ResourceCheck]
 }
diff --git a/distage/distage-framework-docker/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala b/distage/distage-framework-docker/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala
index 5e1c1f2b8..58cc00540 100644
--- a/distage/distage-framework-docker/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala
+++ b/distage/distage-framework-docker/src/main/scala/izumi/distage/docker/DockerClientWrapper.scala
@@ -4,6 +4,7 @@ import java.util.UUID
 
 import com.github.dockerjava.api.DockerClient
 import com.github.dockerjava.api.command.DockerCmdExecFactory
+import com.github.dockerjava.api.model.Container
 import com.github.dockerjava.core.{DefaultDockerClientConfig, DockerClientBuilder, DockerClientConfig}
 import izumi.distage.docker.Docker.{ClientConfig, ContainerId}
 import izumi.distage.docker.DockerClientWrapper.ContainerDestroyMeta
@@ -16,9 +17,8 @@ import izumi.fundamentals.platform.integration.ResourceCheck
 import izumi.fundamentals.platform.language.Quirks._
 import izumi.logstage.api.IzLogger
 
-import scala.jdk.CollectionConverters._
-import com.github.dockerjava.api.model.Container
 import scala.annotation.nowarn
+import scala.jdk.CollectionConverters._
 
 class DockerClientWrapper[F[_]](
   val rawClient: DockerClient,
@@ -75,7 +75,7 @@ object DockerClientWrapper {
     logger: IzLogger,
     clientConfig: ClientConfig,
   ) extends DIResource[F, DockerClientWrapper[F]]
-    with IntegrationCheck {
+    with IntegrationCheck[F] {
 
     private[this] lazy val rawClientConfig = Value(DefaultDockerClientConfig.createDefaultConfigBuilder())
       .mut(clientConfig.remote.filter(_ => clientConfig.useRemote))(
@@ -92,7 +92,7 @@ object DockerClientWrapper {
       .withDockerCmdExecFactory(factory)
       .build
 
-    override def resourcesAvailable(): ResourceCheck = {
+    override def resourcesAvailable(): F[ResourceCheck] = DIEffect[F].maybeSuspend {
       try {
         client.infoCmd().exec()
         ResourceCheck.Success()
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala
index 8b971b523..c546d878c 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/IntegrationChecker.scala
@@ -46,7 +46,7 @@ object IntegrationChecker {
       val instances = integrationComponents
         .toList.map {
           ick =>
-            ick -> integrationLocator.lookupInstance[Any](ick).map(_.asInstanceOf[IntegrationCheck])
+            ick -> integrationLocator.lookupInstance[Any](ick).map(_.asInstanceOf[IntegrationCheck[F]])
         }.toSet
 
       val good = instances.collect { case (_, Some(ic)) => ic }
@@ -68,25 +68,25 @@ object IntegrationChecker {
       }
     }
 
-    private def runCheck(resource: IntegrationCheck)(implicit F: DIEffect[F]): F[Either[ResourceCheck.Failure, Unit]] = {
-      F.maybeSuspend {
-        logger.debug(s"Checking $resource")
-        try {
-          resource.resourcesAvailable() match {
-            case failure @ ResourceCheck.ResourceUnavailable(reason, Some(cause)) =>
-              logger.debug(s"Integration check failed, $resource unavailable: $reason, $cause")
-              Left(failure)
-            case failure @ ResourceCheck.ResourceUnavailable(reason, None) =>
-              logger.debug(s"Integration check failed, $resource unavailable: $reason")
-              Left(failure)
-            case ResourceCheck.Success() =>
-              Right(())
-          }
-        } catch {
-          case NonFatal(exception) =>
-            logger.error(s"Integration check for $resource threw $exception")
-            Left(ResourceCheck.ResourceUnavailable(exception.getMessage, Some(exception)))
+    private def runCheck(resource: IntegrationCheck[F])(implicit F: DIEffect[F]): F[Either[ResourceCheck.Failure, Unit]] = {
+      logger.debug(s"Checking $resource")
+      F.definitelyRecover {
+        resource.resourcesAvailable().map {
+          case failure @ ResourceCheck.ResourceUnavailable(reason, Some(cause)) =>
+            logger.debug(s"Integration check failed, $resource unavailable: $reason, $cause")
+            Left(failure): Either[ResourceCheck.Failure, Unit]
+          case failure @ ResourceCheck.ResourceUnavailable(reason, None) =>
+            logger.debug(s"Integration check failed, $resource unavailable: $reason")
+            Left(failure)
+          case ResourceCheck.Success() =>
+            Right(())
         }
+      } {
+        case NonFatal(exception) =>
+          logger.error(s"Integration check for $resource threw $exception")
+          F.pure(Left(ResourceCheck.ResourceUnavailable(exception.getMessage, Some(exception))))
+        case other =>
+          F.fail(other)
       }
     }
   }
diff --git a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala
index 05d28ac4b..078eb2ec3 100644
--- a/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala
+++ b/distage/distage-framework/src/main/scala/izumi/distage/framework/services/RoleAppPlanner.scala
@@ -56,7 +56,7 @@ object RoleAppPlanner {
       val runtimeKeys = bootstrappedApp.plan.keys
 
       val appPlan = bootstrappedApp.injector.trisectByKeys(bootloader.activation, bootstrappedApp.module.drop(runtimeKeys), appMainRoots) {
-        _.collectChildren[IntegrationCheck].map(_.target).toSet
+        _.collectChildren[IntegrationCheck[F]].map(_.target).toSet
       }
 
       val check = new PlanCircularDependencyCheck(options, logger)
diff --git a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/mono/Entropy.scala b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/mono/Entropy.scala
index ea76aba32..62e430211 100644
--- a/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/mono/Entropy.scala
+++ b/fundamentals/fundamentals-bio/src/main/scala/izumi/functional/mono/Entropy.scala
@@ -17,6 +17,7 @@ trait Entropy[+F[_]] {
   def nextFloat(): F[Float]
   def nextGaussian(): F[Double]
   def nextLong(): F[Long]
+  def nextLong(max: Long): F[Long]
   def nextInt(max: Int): F[Int]
   def nextInt(): F[Int]
   def nextTimeUUID(): F[UUID]
@@ -55,6 +56,7 @@ object Entropy {
       override def nextInt(): F[Int] = F.syncSafe(impureEntropy.nextInt())
       override def nextTimeUUID(): F[UUID] = F.syncSafe(impureEntropy.nextTimeUUID())
       override def nextUUID(): F[UUID] = F.syncSafe(impureEntropy.nextUUID())
+      override def nextLong(max: Long): F[Long] = F.syncSafe(impureEntropy.nextLong(max))
 
       @nowarn("msg=CanBuildFrom")
       override def shuffle[T, CC[X] <: IterableOnce[X]](xs: CC[T])(implicit bf: CanBuildFrom[CC[T], T, CC[T]]): F[CC[T]] =
@@ -78,6 +80,7 @@ object Entropy {
     override def nextGaussian(): Double = random.nextGaussian()
     override def nextLong(): Long = random.nextLong()
     override def nextInt(): Int = random.nextInt()
+    override def nextLong(max: Long): Identity[Long] = random.nextLong(max)
   }
 
 }
diff --git a/project/Versions.scala b/project/Versions.scala
index fc4478e63..2ded24b71 100644
--- a/project/Versions.scala
+++ b/project/Versions.scala
@@ -28,7 +28,7 @@ object V {
 
   // good to drop - scala
   val scala_java_time = "2.0.0-RC5"
-  val scalamock = "4.4.0"
+  val scalamock = "5.0.0"
 
   // java-only dependencies below
   val classgraph = "4.8.87"


Test patch:
diff --git a/distage/distage-framework-docker/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala b/distage/distage-framework-docker/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala
index d9db81fda..a4d0b0d00 100644
--- a/distage/distage-framework-docker/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala
+++ b/distage/distage-framework-docker/src/test/scala/izumi/distage/testkit/docker/fixtures/DockerPlugin.scala
@@ -21,8 +21,8 @@ class PgSvcExample(
   val cs: AvailablePort @Id("cs"),
   val mq: AvailablePort @Id("mq"),
   val cmd: ReusedOneshotContainer.Container,
-) extends IntegrationCheck {
-  override def resourcesAvailable(): ResourceCheck = {
+) extends IntegrationCheck[Task] {
+  override def resourcesAvailable(): Task[ResourceCheck] = Task.effect {
     new PortCheck(10.milliseconds).checkPort(pg.hostV4, pg.port)
   }
 }
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala
index 8dfc5cffc..0b8535dd7 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/RoleAppTest.scala
@@ -5,10 +5,11 @@ import java.nio.charset.StandardCharsets.UTF_8
 import java.nio.file.{Files, Paths}
 import java.util.UUID
 
+import cats.effect.IO
 import com.typesafe.config.ConfigFactory
 import distage.plugins.{PluginBase, PluginDef}
 import distage.{DIKey, Injector, Locator, LocatorRef}
-import izumi.distage.effect.modules.IdentityDIEffectModule
+import izumi.distage.effect.modules.CatsDIEffectModule
 import izumi.distage.framework.config.PlanningOptions
 import izumi.distage.framework.services.{IntegrationChecker, RoleAppPlanner}
 import izumi.distage.model.PlannerInput
@@ -18,7 +19,6 @@ import izumi.distage.roles.RoleAppMain
 import izumi.distage.roles.test.fixtures.Fixture._
 import izumi.distage.roles.test.fixtures._
 import izumi.distage.roles.test.fixtures.roles.TestRole00
-import izumi.fundamentals.platform.functional.Identity
 import izumi.fundamentals.platform.resources.ArtifactVersion
 import izumi.logstage.api.IzLogger
 import org.scalatest.wordspec.AnyWordSpec
@@ -37,16 +37,17 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
   object TestEntrypoint extends RoleAppMain.Silent(new TestLauncher)
 
   class XXX_TestWhiteboxProbe extends PluginDef {
-    val resources = new XXX_ResourceEffectsRecorder
+    val resources = new XXX_ResourceEffectsRecorder[IO]
     private var locator0: LocatorRef = null
     lazy val locator: Locator = locator0.get
 
-    make[XXX_ResourceEffectsRecorder].fromValue(resources)
+    make[XXX_ResourceEffectsRecorder[IO]].fromValue(resources)
     make[XXX_LocatorLeak].from {
       locatorRef: LocatorRef =>
         locator0 = locatorRef
         XXX_LocatorLeak(locator0)
     }
+    include(CatsDIEffectModule)
   }
 
   val logLevel = "warn"
@@ -70,7 +71,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
       )
 
       assert(probe.resources.getStartedCloseables() == probe.resources.getClosedCloseables().reverse)
-      assert(probe.resources.getCheckedResources().toSet == Set(probe.locator.get[IntegrationResource0], probe.locator.get[IntegrationResource1]))
+      assert(probe.resources.getCheckedResources().toSet == Set(probe.locator.get[IntegrationResource0[IO]], probe.locator.get[IntegrationResource1[IO]]))
     }
 
     "start roles regression test" in {
@@ -87,9 +88,10 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
                 new AdoptedAutocloseablesCasePlugin,
                 probe,
                 new PluginDef {
-                  make[TestResource].from[IntegrationResource0]
+                  make[TestResource].from[IntegrationResource0[IO]]
                   many[TestResource]
                     .ref[TestResource]
+                  include(CatsDIEffectModule)
                 },
               )
             )
@@ -106,7 +108,7 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
 
       assert(probe.resources.getStartedCloseables() == probe.resources.getClosedCloseables().reverse)
       assert(probe.resources.getCheckedResources().toSet.size == 2)
-      assert(probe.resources.getCheckedResources().toSet == Set(probe.locator.get[TestResource], probe.locator.get[IntegrationResource1]))
+      assert(probe.resources.getCheckedResources().toSet == Set(probe.locator.get[TestResource], probe.locator.get[IntegrationResource1[IO]]))
     }
 
     "be able to read activations from config" in {
@@ -158,29 +160,29 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
 
       val logger = IzLogger()
       val definition = new ResourcesPluginBase {
-          make[TestResource].from[IntegrationResource0]
+          make[TestResource].from[IntegrationResource0[IO]]
           many[TestResource]
             .ref[TestResource]
-        } ++ IdentityDIEffectModule ++ probe
+        } ++ CatsDIEffectModule ++ probe
       val roots = Set(DIKey.get[Set[TestResource]]: DIKey)
-      val roleAppPlanner = new RoleAppPlanner.Impl[Identity](
+      val roleAppPlanner = new RoleAppPlanner.Impl[IO](
         PlanningOptions(),
         BootstrapModule.empty,
         logger,
         Injector.bootloader(PlannerInput(definition, Activation.empty, roots)),
       )
-      val integrationChecker = new IntegrationChecker.Impl[Identity](logger)
+      val integrationChecker = new IntegrationChecker.Impl[IO](logger)
 
       val plans = roleAppPlanner.makePlan(roots)
       Injector().produce(plans.runtime).use {
         Injector.inherit(_).produce(plans.app.shared).use {
           Injector.inherit(_).produce(plans.app.side).use {
             locator =>
-              integrationChecker.checkOrFail(plans.app.side.declaredRoots, locator)
+              integrationChecker.checkOrFail(plans.app.side.declaredRoots, locator).unsafeRunSync()
 
               assert(probe.resources.getStartedCloseables().size == 3)
               assert(probe.resources.getCheckedResources().size == 2)
-              assert(probe.resources.getCheckedResources().toSet == Set(locator.get[TestResource], locator.get[IntegrationResource1]))
+              assert(probe.resources.getCheckedResources().toSet == Set(locator.get[TestResource], locator.get[IntegrationResource1[IO]]))
           }
         }
       }
@@ -192,31 +194,31 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
       val logger = IzLogger()
       val definition = new ResourcesPluginBase {
           make[TestResource].fromResource {
-            r: IntegrationResource1 =>
+            r: IntegrationResource1[IO] =>
               DIResource.fromAutoCloseable(new IntegrationResource0(r, probe.resources))
           }
           many[TestResource]
             .ref[TestResource]
-        } ++ IdentityDIEffectModule ++ probe
+        } ++ probe
       val roots = Set(DIKey.get[Set[TestResource]]: DIKey)
-      val roleAppPlanner = new RoleAppPlanner.Impl[Identity](
+      val roleAppPlanner = new RoleAppPlanner.Impl[IO](
         PlanningOptions(),
         BootstrapModule.empty,
         logger,
         Injector.bootloader(PlannerInput(definition, Activation.empty, roots)),
       )
-      val integrationChecker = new IntegrationChecker.Impl[Identity](logger)
+      val integrationChecker = new IntegrationChecker.Impl[IO](logger)
 
       val plans = roleAppPlanner.makePlan(roots)
       Injector().produce(plans.runtime).use {
         Injector.inherit(_).produce(plans.app.shared).use {
           Injector.inherit(_).produce(plans.app.side).use {
             locator =>
-              integrationChecker.checkOrFail(plans.app.side.declaredRoots, locator)
+              integrationChecker.checkOrFail(plans.app.side.declaredRoots, locator).unsafeRunSync()
 
               assert(probe.resources.getStartedCloseables().size == 3)
               assert(probe.resources.getCheckedResources().size == 2)
-              assert(probe.resources.getCheckedResources().toSet == Set(locator.get[TestResource], locator.get[IntegrationResource1]))
+              assert(probe.resources.getCheckedResources().toSet == Set(locator.get[TestResource], locator.get[IntegrationResource1[IO]]))
           }
         }
       }
@@ -224,35 +226,35 @@ class RoleAppTest extends AnyWordSpec with WithProperties {
 
     "integration checks are discovered and ran, ignoring duplicating reference bindings" in {
       val logger = IzLogger()
-      val initCounter = new XXX_ResourceEffectsRecorder
+      val initCounter = new XXX_ResourceEffectsRecorder[IO]
       val definition = new ResourcesPluginBase {
-          make[IntegrationResource0]
-          make[TestResource].using[IntegrationResource0]
-          make[TestResource with AutoCloseable].using[IntegrationResource0]
+          make[IntegrationResource0[IO]]
+          make[TestResource].using[IntegrationResource0[IO]]
+          make[TestResource with AutoCloseable].using[IntegrationResource0[IO]]
           many[TestResource]
             .ref[TestResource]
             .ref[TestResource with AutoCloseable]
-          make[XXX_ResourceEffectsRecorder].fromValue(initCounter)
-        } ++ IdentityDIEffectModule
+          make[XXX_ResourceEffectsRecorder[IO]].fromValue(initCounter)
+        } ++ CatsDIEffectModule
       val roots = Set(DIKey.get[Set[TestResource]]: DIKey)
-      val roleAppPlanner = new RoleAppPlanner.Impl[Identity](
+      val roleAppPlanner = new RoleAppPlanner.Impl[IO](
         PlanningOptions(),
         BootstrapModule.empty,
         logger,
         Injector.bootloader(PlannerInput(definition, Activation.empty, roots)),
       )
-      val integrationChecker = new IntegrationChecker.Impl[Identity](logger)
+      val integrationChecker = new IntegrationChecker.Impl[IO](logger)
 
       val plans = roleAppPlanner.makePlan(roots)
       Injector().produce(plans.runtime).use {
         Injector.inherit(_).produce(plans.app.shared).use {
           Injector.inherit(_).produce(plans.app.side).use {
             locator =>
-              integrationChecker.checkOrFail(plans.app.side.declaredRoots, locator)
+              integrationChecker.checkOrFail(plans.app.side.declaredRoots, locator).unsafeRunSync()
 
               assert(initCounter.getStartedCloseables().size == 3)
               assert(initCounter.getCheckedResources().size == 2)
-              assert(initCounter.getCheckedResources().toSet == Set(locator.get[IntegrationResource0], locator.get[IntegrationResource1]))
+              assert(initCounter.getCheckedResources().toSet == Set(locator.get[IntegrationResource0[IO]], locator.get[IntegrationResource1[IO]]))
           }
         }
       }
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/Fixture.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/Fixture.scala
index 48eaf7324..784903725 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/Fixture.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/Fixture.scala
@@ -3,6 +3,7 @@ package izumi.distage.roles.test.fixtures
 import distage.LocatorRef
 import izumi.distage.framework.model.IntegrationCheck
 import izumi.distage.model.definition.Axis
+import izumi.distage.model.effect.DIEffect
 import izumi.fundamentals.platform.integration.ResourceCheck
 import izumi.fundamentals.platform.language.Quirks._
 
@@ -23,47 +24,47 @@ object Fixture {
     systemPropList: List[Int],
   )
 
-  class XXX_ResourceEffectsRecorder {
+  class XXX_ResourceEffectsRecorder[F[_]] {
     private val startedCloseables: mutable.ArrayBuffer[AutoCloseable] = mutable.ArrayBuffer()
     private val closedCloseables: mutable.ArrayBuffer[AutoCloseable] = mutable.ArrayBuffer()
-    private val checkedResources: mutable.ArrayBuffer[IntegrationCheck] = mutable.ArrayBuffer()
+    private val checkedResources: mutable.ArrayBuffer[IntegrationCheck[F]] = mutable.ArrayBuffer()
 
     def onStart(c: AutoCloseable): Unit = this.synchronized(startedCloseables += c).discard()
     def onClose(c: AutoCloseable): Unit = this.synchronized(closedCloseables += c).discard()
-    def onCheck(c: IntegrationCheck): Unit = this.synchronized(checkedResources += c).discard()
+    def onCheck(c: IntegrationCheck[F]): Unit = this.synchronized(checkedResources += c).discard()
 
     def getStartedCloseables(): Seq[AutoCloseable] = this.synchronized(startedCloseables.toList)
     def getClosedCloseables(): Seq[AutoCloseable] = this.synchronized(closedCloseables.toList)
-    def getCheckedResources(): Seq[IntegrationCheck] = this.synchronized(checkedResources.toList)
+    def getCheckedResources(): Seq[IntegrationCheck[F]] = this.synchronized(checkedResources.toList)
   }
 
   case class XXX_LocatorLeak(locatorRef: LocatorRef)
 
   trait TestResource
 
-  trait ProbeResource extends TestResource with AutoCloseable {
-    def counter: XXX_ResourceEffectsRecorder
+  trait ProbeResource[F[_]] extends TestResource with AutoCloseable {
+    def counter: XXX_ResourceEffectsRecorder[F]
     counter.onStart(this)
 
     override def close(): Unit = counter.onClose(this)
 
   }
 
-  trait ProbeCheck extends ProbeResource with IntegrationCheck {
-    override def resourcesAvailable(): ResourceCheck = {
+  abstract class ProbeCheck[F[_]: DIEffect] extends ProbeResource[F] with IntegrationCheck[F] {
+    override def resourcesAvailable(): F[ResourceCheck] = DIEffect[F].maybeSuspend {
       counter.onCheck(this)
       ResourceCheck.Success()
     }
   }
 
-  class IntegrationResource0(val closeable: IntegrationResource1, val counter: XXX_ResourceEffectsRecorder) extends ProbeCheck
-  class IntegrationResource1(val roleComponent: JustResource1, val counter: XXX_ResourceEffectsRecorder) extends ProbeCheck
+  class IntegrationResource0[F[_]: DIEffect](val closeable: IntegrationResource1[F], val counter: XXX_ResourceEffectsRecorder[F]) extends ProbeCheck[F]
+  class IntegrationResource1[F[_]: DIEffect](val roleComponent: JustResource1[F], val counter: XXX_ResourceEffectsRecorder[F]) extends ProbeCheck[F]
 
-  case class ProbeResource0(roleComponent: JustResource3, counter: XXX_ResourceEffectsRecorder) extends ProbeResource
+  case class ProbeResource0[F[_]: DIEffect](roleComponent: JustResource3[F], counter: XXX_ResourceEffectsRecorder[F]) extends ProbeResource[F]
 
-  case class JustResource1(roleComponent: JustResource2, counter: XXX_ResourceEffectsRecorder) extends TestResource
-  case class JustResource2(closeable: ProbeResource0, counter: XXX_ResourceEffectsRecorder) extends TestResource
-  case class JustResource3(counter: XXX_ResourceEffectsRecorder) extends TestResource
+  case class JustResource1[F[_]: DIEffect](roleComponent: JustResource2[F], counter: XXX_ResourceEffectsRecorder[F]) extends TestResource
+  case class JustResource2[F[_]: DIEffect](closeable: ProbeResource0[F], counter: XXX_ResourceEffectsRecorder[F]) extends TestResource
+  case class JustResource3[F[_]: DIEffect](counter: XXX_ResourceEffectsRecorder[F]) extends TestResource
 
   trait AxisComponent
   object AxisComponentIncorrect extends AxisComponent
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/ResourcesPlugin.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/ResourcesPlugin.scala
index 2a59d4497..10de9a263 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/ResourcesPlugin.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/ResourcesPlugin.scala
@@ -2,6 +2,7 @@ package izumi.distage.roles.test.fixtures
 
 import java.util.concurrent.{ExecutorService, Executors}
 
+import cats.effect.IO
 import izumi.distage.model.definition.ModuleDef
 import izumi.distage.model.definition.StandardAxis._
 import izumi.distage.plugins.PluginDef
@@ -19,26 +20,26 @@ class ConflictPlugin extends PluginDef {
 
 class ResourcesPluginBase extends ModuleDef {
   make[ExecutorService].from(Executors.newCachedThreadPool())
-  make[IntegrationResource1]
-  make[JustResource1]
-  make[JustResource2]
-  make[ProbeResource0]
-  make[JustResource3]
+  make[IntegrationResource1[IO]]
+  make[JustResource1[IO]]
+  make[JustResource2[IO]]
+  make[ProbeResource0[IO]]
+  make[JustResource3[IO]]
 
   many[TestResource]
-    .ref[IntegrationResource1]
-    .ref[JustResource1]
-    .ref[JustResource2]
-    .ref[ProbeResource0]
-    .ref[JustResource3]
+    .ref[IntegrationResource1[IO]]
+    .ref[JustResource1[IO]]
+    .ref[JustResource2[IO]]
+    .ref[ProbeResource0[IO]]
+    .ref[JustResource3[IO]]
 }
 
 class ResourcesPlugin extends ResourcesPluginBase with PluginDef {
-  make[XXX_ResourceEffectsRecorder]
+  make[XXX_ResourceEffectsRecorder[IO]]
 
-  make[IntegrationResource0]
+  make[IntegrationResource0[IO]]
   many[TestResource]
-    .ref[IntegrationResource0]
+    .ref[IntegrationResource0[IO]]
 }
 
 object ResourcesPlugin {
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala
index 7474c4eae..a8f523cd2 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestPlugin.scala
@@ -35,7 +35,7 @@ class TestPluginBase[F[_]: TagK] extends CatsDIEffectModule with PluginDef with
   make[TestRole04[F]]
 
   make[TestRole00Resource[F]]
-  make[TestRole00ResourceIntegrationCheck]
+  make[TestRole00ResourceIntegrationCheck[F]]
 
   make[NotCloseable].from[InheritedCloseable]
   make[ConfigWriter[F]]
diff --git a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestRole00.scala b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestRole00.scala
index 835840df2..1c04f0735 100644
--- a/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestRole00.scala
+++ b/distage/distage-framework/src/test/scala/izumi/distage/roles/test/fixtures/TestRole00.scala
@@ -39,7 +39,7 @@ object roles {
     val resources: Set[TestResource],
     val conflict: Conflict,
     val es: ExecutorService,
-    val counter: XXX_ResourceEffectsRecorder,
+    val counter: XXX_ResourceEffectsRecorder[F],
     val ref: XXX_LocatorLeak,
   ) extends RoleService[F] {
     notCloseable.discard()
@@ -62,12 +62,12 @@ object roles {
     final case class IntegrationOnlyCfg(flag: Boolean)
     final case class IntegrationOnlyCfg2(value: String)
 
-    final class TestRole00Resource[F[_]](private val it: TestRole00ResourceIntegrationCheck)
-    final class TestRole00ResourceIntegrationCheck(
+    final class TestRole00Resource[F[_]](private val it: TestRole00ResourceIntegrationCheck[F])
+    final class TestRole00ResourceIntegrationCheck[F[_]:DIEffect](
       private val cfg: IntegrationOnlyCfg,
       private val cfg2: IntegrationOnlyCfg2,
-    ) extends IntegrationCheck {
-      override def resourcesAvailable(): ResourceCheck = {
+    ) extends IntegrationCheck[F] {
+      override def resourcesAvailable(): F[ResourceCheck] = DIEffect[F].pure{
         assert(cfg2.value == "configvalue:updated")
         ResourceCheck.Success()
       }
diff --git a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/services/dstest/DistageTestRunner.scala b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/services/dstest/DistageTestRunner.scala
index def012287..aaf5a63b5 100644
--- a/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/services/dstest/DistageTestRunner.scala
+++ b/distage/distage-testkit-core/src/main/scala/izumi/distage/testkit/services/dstest/DistageTestRunner.scala
@@ -139,7 +139,7 @@ class DistageTestRunner[F[_]: TagK](
 
               // compute [[TriSplittedPlan]] of our test, to extract shared plan, and perform it only once
               val shared = injector.trisectByKeys(env.activation, strengthenedAppModule, sharedKeys) {
-                _.collectChildren[IntegrationCheck].map(_.target).toSet
+                _.collectChildren[IntegrationCheck[F]].map(_.target).toSet
               }
 
               val envMergeCriteria = EnvMergeCriteria(bsPlanMinusActivations, bsModuleMinusActivations, shared, runtimePlan, envExec)
@@ -367,7 +367,7 @@ class DistageTestRunner[F[_]: TagK](
 
     val allSharedKeys = mainSharedLocator.allInstances.map(_.key).toSet
 
-    val testIntegrationCheckKeys = testPlan.collectChildren[IntegrationCheck].map(_.target).toSet -- allSharedKeys
+    val testIntegrationCheckKeys = testPlan.collectChildren[IntegrationCheck[F]].map(_.target).toSet -- allSharedKeys
 
     val newAppModule = test.environment.appModule.drop(allSharedKeys)
     val moduleKeys = newAppModule.keys
diff --git a/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/fixtures/Fixtures.scala b/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/fixtures/Fixtures.scala
index 537339334..c4e043f1d 100644
--- a/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/fixtures/Fixtures.scala
+++ b/distage/distage-testkit-scalatest/src/test/scala/izumi/distage/testkit/distagesuite/fixtures/Fixtures.scala
@@ -38,8 +38,8 @@ trait ActiveComponent
 case object TestActiveComponent extends ActiveComponent
 case object ProdActiveComponent extends ActiveComponent
 
-class MockPostgresCheck[F[_]]() extends IntegrationCheck {
-  override def resourcesAvailable(): ResourceCheck = ResourceCheck.Success()
+class MockPostgresCheck[F[_]: DIEffect]() extends IntegrationCheck[F] {
+  override def resourcesAvailable(): F[ResourceCheck] = DIEffect[F].pure(ResourceCheck.Success())
 }
 
 class MockPostgresDriver[F[_]](val check: MockPostgresCheck[F])
@@ -48,22 +48,22 @@ class MockRedis[F[_]]()
 
 class MockUserRepository[F[_]](val pg: MockPostgresDriver[F])
 
-class MockCache[F[_]](val redis: MockRedis[F]) extends IntegrationCheck {
+class MockCache[F[_]: DIEffect](val redis: MockRedis[F]) extends IntegrationCheck[F] {
   locally {
     val integer = MockCache.instanceCounter.getOrElseUpdate(redis, new AtomicInteger(0))
     if (integer.incrementAndGet() > 2) { // one instance per each monad
       throw new RuntimeException(s"Something is wrong with memoization: $integer instances were created")
     }
   }
-  override def resourcesAvailable(): ResourceCheck = ResourceCheck.Success()
+  override def resourcesAvailable(): F[ResourceCheck] = DIEffect[F].pure(ResourceCheck.Success())
 }
 
 object MockCache {
   val instanceCounter = mutable.Map[AnyRef, AtomicInteger]()
 }
 
-class ApplePaymentProvider[F[_]] extends IntegrationCheck {
-  override def resourcesAvailable(): ResourceCheck = ResourceCheck.ResourceUnavailable("Test", None)
+class ApplePaymentProvider[F[_]: DIEffect] extends IntegrationCheck[F] {
+  override def resourcesAvailable(): F[ResourceCheck] = DIEffect[F].pure(ResourceCheck.ResourceUnavailable("Test", None))
 }
 
 class MockCachedUserService[F[_]](val users: MockUserRepository[F], val cache: MockCache[F])