-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ZIO Test Integration #282
ZIO Test Integration #282
Conversation
@fwbrasil please review when you get a chance. We can split this out into |
import zio.internal.stacktracer.SourceLocation | ||
import zio.test.* | ||
|
||
abstract class KyoSpecAbstract[S] extends ZIOSpecAbstract: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ZIOSpecAbstract
has a timeout warning after 60 seconds. This works correctly with Fiber.sleep
:
timestamp=2024-04-24T19:41:29.306520Z level=WARN thread=#zio-fiber-160508830 message="Test suite! - Fibers.sleep has taken more than 1 m to execute. If this is not expected, consider using TestAspect.timeout to timeout runaway tests for faster diagnostics."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to propagate ZIO's cancelation to Kyo's fibers otherwise the test could continue running in the background.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true, though may not be a problem for an initial implementation. ZIO uses .disconnect
to provide immediate interruption of ZIO effects when TestAspect.timeout(..)
is used. Given this is for testing, I don't think we should be too concerned about resource leaks... though that's likely a bad precedence to set.
We will need to find a suitable point of introp with ZIO which supports cancellation. ZIO has an CancelableFuture
, but I can't find any info on it.
|
||
abstract class KyoSpecDefault extends KyoSpecAbstract[KyoApp.Effects]: | ||
final override def run[In](v: => In < KyoApp.Effects)(using Flat[In < KyoApp.Effects]): ZIO[Environment, Throwable, In] = | ||
ZIO.fromFuture { implicit ec => IOs.run(KyoApp.runFiber(timeout)(IOs(v)).toFuture).map(_.get) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can add a private[kyo] def KyoApp.runToFuture
method.
Note, I am wrapping in IOs
here to ensure suspension - not sure that's necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe KyoApp.runFuture
? It could be public as well, it seems useful. There's no need for the IOs
suspension since the code handles IOs
and is also suspended in ZIO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure - I was just hesitant to suggest a public function as it seems like it could be misused.
final override def run[In](v: => In < KyoApp.Effects)(using Flat[In < KyoApp.Effects]): ZIO[Environment, Throwable, In] = | ||
ZIO.fromFuture { implicit ec => IOs.run(KyoApp.runFiber(timeout)(IOs(v)).toFuture).map(_.get) } | ||
|
||
def timeout: Duration = Duration.Inf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure we need this. Users can use the ZIO timeout aspects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A default timeout is important since people might not add the aspect. KyoTest
has a behavior to disable the timeout in case there's an active debugging session. It's quite useful when working on tests so we'd need to port it as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we can update Fibers.timeout
to ignore Duration.Inf
? This should lower the overhead for each test
I haven't used |
zio-test will likely be equivalent in performance to scalatest - though there are ways to speed it up. You can use the
In scalatest the following is a valid passing test:
One final benefit is that zio-test is likely popular with many kyo users. If we expect users to interop with zio at all, it would be best if kyo-test ran on the same test runner. |
LGTM. Is this ready to merge? |
@fwbrasil it can be merged in the current state, but the remaining work:
|
@fwbrasil I removed the I split the code to new files project, so it should be consumable from all kyo projects. We can resolve the remaining issues later. |
Working, albeit messy zio-test integration. I think this is generally preferable to Scalatest (for many reasons), but open to feedback.
Much of this is closely tied to the implementation of
ZIOSpecDefault
or more accuratelyZIOSpec
.I currently cannot get sbt to detect the tests to run, but that may be a fault in my configuration.
One of the perks of Kyo's model is that we can simply assume all assertions may have pending effects. As such, we can always invoke the
run
. In ZIO's case, there is logic to determine whichTestConstructor[_, _]
to use via implicit resolution. If a pureTestResult
is passed as an assertion, it's necessary to wrap it inZIO.succeed