PgSvcExample
may be a resource, in that case it would be created before all the tests and finalized after all the tests
We need more customized integration checks than what’s provided by the ResourceCheck
trait: https://github.com/7mind/distage-livecode/blob/livecode/src/main/scala/livecode/code.scala#L186
We have something as follows: https://github.com/BlueBrain/nexus/blob/master/cli/src/test/scala/ch/epfl/bluebrain/nexus/cli/postgres/AbstractPostgresSpec.scala#L45
DIResource
with acquire/release actions that are your before/afterAll actions. Then you can pin the resource to be global via memoizationRoots
AND pin the resource to be a dependency of all tests such that it doesn’t need to be summoned manually as a parameter for its acquire/release actions to execute.final class MyTransactor[F[_]] extends DIResourceBase[F, MyTransactor[F]] {
def acquire = waitForPostgres
def release = deleteAllTables
}
trait MyTest extends DistageAbstractScalatestSpec[IO] {
override def config = super.config.copy(
memoizationRoots = super.config.memoizationRoots ++ Set(
DIKey.get[MyTransactor[F]], // force MyTransactor to be acquired/released only once per test-run
),
forcedRoots = super.config.forcedRoots ++ Set(
DIKey.get[MyTransactor[F]], // force MyTransactor to be acquired/released always, no matter if the running tests declare it as a parameter
)
)
}
make[Transactor[IO]].fromEffect(...)
) and for the waiting logic I need the transactor itselfprivate def waitForPostgresReady(xa: Transactor[IO], maxDelay: FiniteDuration = 30.seconds): IO[Unit] = ???
reuse=true
allows reusing the same container between multiple test runs on top of that
./app :influx param1 —param2
@neko-kai If I had something like you posted:
trait AbstractTest extends DistageAbstractScalatestSpec[IO] {
override def config = super.config.copy(
memoizationRoots = super.config.memoizationRoots ++ Set(
DIKey.get[Transactor[F]], DIKey.get[InfluxClient[F]]
)
)
}
And then I have 2 tests: PostgresSpec extends AbstractTest
and InfluxSpec extends AbstractTest
and I run testOnly *InfluxSpec
I can see how the Postgres container is also started and the waitForPostgresReady
is also running, even though I’m just running the InfluxSpec.
sbt testOnly
doesn’t work correctly with distage-testkit – in reality all tests are run, not just the ones reported. Try running InfluxSpec
class test from IntelliJ IDEA - it will work correctly. You can also run select test cases with testOnly — -z “<test-name-patter>”
, but this will work for running specific test classes, not specific test suites
run
method is called, collect tests that are registered – this enables global sharing and all the features stemming from having a single entrypoint. Under sbt
this doesn’t work because scalatest’s sbt runner launches tests one-by-one and does not pass any parameters to figure out the enabled suites, the only way to figure out which suites were selected would be to wait until there was a big enough pause between run
calls, which would be pretty horrifying - so it instead it just launches everything
F[_]
but in fact a lot of times we end up using F[Either[_, _]]
on our signatures in order to catch errors not thrown on the F. And obviously is a pain to work with them directly. Probably using something like BIO would be better
@bogdanromanx
I see what you mean by decline
requiring executing the actions immediately inside the parser which makes it harder to decouple subcommands from wiring.
Well, one thing you could do to combat that is to not return F[ExitCode]
directly from the parser, but to parse into an ADT that describes the subcommand and the command-line arguments – that way you can do the wiring in one place where you pattern match on that ADT instead of in many places around the code.
Another option would be to not spread the command-line parsers across multiple classes, but put them all into Cli[F]
- this would again allow to centralize wiring and remove the LocatorRef parameter.
I’ve looked at your project and implemented one way to get rid of recursion on LocatorRef that isn’t one of the suggestions above, but I think is minimally disruptive to the way it’s organized right now - I’ve opened a PR at BlueBrain/nexus#1176
Hey guys, I new in BIO and I need assistance.
I have
def t[F[+_,+_]: BIOPrimitives: BIO : BIOApplicative, R[_] : Sync : MonadError[?[_], Throwable], B](t: R[B]): F[Throwable, Int] = ??? // How to get F[_,_] from R (which is cats effect IO instance)
to be able to do something like this
t(IO(1/0))
// zio.IO[Throwable, Int]