Open majk-p opened 2 years ago
This is related to #2615, which notes that nextInterval
raises an exception in some cases. At the very least, fixing that should help narrow down what's going on here.
Thank you! This indeed seems related. On my fork I've modified nextInterval
slightly:
def nextInterval(): FiniteDuration = {
val s = state
if (s.tasks.nonEmpty) {
val task = s.tasks.min
require(
(task.runsAt - s.clock)> Duration.Zero,
s"Calculated negative next interval step. Min task: ${task} runs at ${task.runsAt}, clock: ${s.clock}, diff: ${(task.runsAt - s.clock)}"
)
task.runsAt - s.clock
} else Duration.Zero
}
Now I end up with this kind of error:
[error] ! monoid.intercalateRepeat2
[error] java.lang.IllegalArgumentException: Exception raised on property evaluation.> ARG_0: <function1>
[error] > ARG_1: <function1>> Exception: java.lang.IllegalArgumentException: requirement failed: Calculated negative next interval step. Min task: Task(197,cats.effect.IOFiber$$Lambda$9792/0x00000008428a9840@6a551b6a,260016048000 microseconds) runs at 260016048000 microseconds, clock: 260016048047968 nanoseconds, diff: -47968 nanoseconds
[error] The seed is 8wotMV45FnXThYD8IEOgfuwFiSh_MxkTujPrb4xpPDL= (TestContext.scala:101)
[error] cats.effect.kernel.testkit.TestContext.nextInterval(TestContext.scala:101)
[error] cats.effect.kernel.testkit.TestContext.tickAll(TestContext.scala:184)
[error] cats.effect.testkit.TestInstances.unsafeRun(TestInstances.scala:193)
[error] cats.effect.testkit.TestInstances.unsafeRun$(TestInstances.scala:183)
[error] net.michalp.IOConsumerLawsSpec.unsafeRun(ConsumerLawsSpec.scala:23)
Looks like the runtime would sometimes face tasks that should be finished in the past already. Obviously advance
allows only positive duration (perhaps it could accept zero?). Should we in this case just return zero duration? Or perhaps it's a bigger issue?
I've been recently playing around with migration to CE3. Some of my libraries provide algebras that are law tested. Some of them are meant to be used against
IO
, thus the laws were also tested against it. In CE2 I would usecats.effect.laws.discipline.arbitrary._
and as discussed on Discord the right replacement would be to have my test suite extendTestInstances
and instantiate implicitTicker()
.With this approach my migrated tests wouldn't work out well, but I've learned that
Parallel
is a tricky one to law test, so I've eliminated that one from my tests.Despite that effort, I still face issues with law testing quite simple algebras' properties. I've prepared a repository reproducing my issues: https://github.com/majk-p/io-laws-playground/
For the demo I've created two simple algebras, here are the simplified descriptions
and
Say I want to test that the laws of
Monoid
hold for those two. I've prepared a test suite in: https://github.com/majk-p/io-laws-playground/blob/master/src/test/scala/net/michalp/StorageLaws.scalaWhile the tests in
DummyStorageLaws
(that useIO.pure
asArbitraryIO
implementation) andSyncIOStorageLaws
(that useTestInstances
providedArbitrary[SyncIO[A]]
) or even justOptionLawSpec
work perfectly well, implementation based onArbitrary[IO[A]]
fromTestInstances
fails. The error is more or less like the one below for most testsPlease advise if I'm doing something wrong when using library provided
arbitraryIO
, or is it really a bug?