-
Notifications
You must be signed in to change notification settings - Fork 34
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
Cross-platform suite-local fixtures #104
Conversation
|
||
override def afterAll(): Unit = { | ||
assertEquals(acquired, 1) | ||
// assertEquals(released, 1) // Release is async, no way to check? |
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.
Yeah this is really my only question here. since there's no way to enforce backpressure between the release of the suite-local fixture and the acquisition of the next, you could run into some weird interactions between different suites. for example, if your fixture is a network server that binds to the same port. suite A might not release its port before the suite B attempts to acquire
I think this is still really useful for javascript to have, so this may just need to be a tradeoff that we warn users about
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 this is still really useful for javascript to have, so this may just need to be a tradeoff that we warn users about
I'm mindful of this issue too, but exactly as you said. For plenty of non-interacting resources should be fine.
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.
It's particularly evil, but this problem could be solved via some sort of global semaphore right?
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.
That sounds like it should work, but it would inhibit parallel suite execution (only the suites which use this feature) for users who opt in. which again may be fine and just something we warn users about
the fixtures do have names, so ideally you could split the global semaphore by name, but that relies on the assumption that interacting resources have the same name
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.
Right, but on JS we don't have parallel execution anyway. So maybe the trick is to use this implementation for JS (plus some sort of global semaphore), your blocking implementation for JVM, and just provide them under the same interface?
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 should call it UnsafeResourceSuiteLocalFixture
to emphasize these hazards.
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.
Im still a bit confused :)
We have a working ResourceSuiteLocalFixture
for the JVM only. As far as I understand, you want to add similar functionality but for JS?
I don't really know anything about ScalaJS and how to create libraries for it, but I don't get why we need to create something that works on both the JVM and JS?
Because, this shared logic on the JVM, doesn't really work as one would expect. And since we already have something that works the JVM, why add something shared?
So in my mind, that has no JS knowledge, can this logic simply be added to the JS part of this library? Or is there some value in having something shared?
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.
Good questions!
Or is there some value in having something shared
Yes, absolutely. If it is not shared, then if you want to test your code on both JVM and JS you'd have to write your tests twice, separately for each platform. For a concrete example of this consider the http4s test suite which now needs to support both JVM and JS platforms where in fact I've already been using this construct:
https://github.com/http4s/http4s/blob/main/testing/shared/src/test/scala/org/http4s/Http4sSuite.scala#L68
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.
Then I would indeed go for the UnsafeResourceSuiteLocalFixture
:)
Does the CatsEffectFunFixtures
not give you the functionality you desire?
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.
CatsEffectFunFixtures
does work on JVM and JS, but it allocates/tears down the resource once per test. The SuiteLocal
fixtures allocate/tear down once per suite.
@danicheg would you have a moment to review this please? I'd find this incredibly useful. |
@milanvdm @danicheg thank you both for your thoughtful reviews, I've pushed some changes which hopefully address both of your concerns.
Let me know what you think! |
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.
You did a huge job @armanbilge 👍🏻
Sorry, but I was out from your discussion with @milanvdm at some point.
But as I get the root problem is that ResourceSuiteLocalFixture
currently not working on JS correctly. And adding the ResourceSuiteLocalDeferredFixture
would mean that ResourceSuiteLocalFixture
will still not working on JS.
Maybe it's possible to change ResourceSuiteLocalFixture
to have a working version both on JVM and JS? For example, we could put implement details of munit.CatsEffectFixtures.ResourceSuiteLocalFixture#apply
for JVM and JS separately.
So we would have one suite to work with resource fixtures both on JVM and JS.
What do you folks think?
@danicheg Unfortunately, it is not possible to implement On JS, there is only one thread and therefore no Notice that this requires making a source-incompatible change to the signature. Which is obviously not an impossible thing to do, but it would be painful for any downstream currently using If we really want to fix all this craziness: would require a PR to |
@armanbilge thanks for the detailed answer. What about using |
Cool, thanks for giving it a try!! Have you tried running it against the test suite? 😉 My concern is that there is no guarantee when |
Also, you might find the implementation of |
@armanbilge yep, the tests were passed ._. But I'm not sure if this is legal though. |
Sounds like the test suite is not rigorous enough! 😬 We should fix that. For example, try using your fixture to allocate this resource: |
@armanbilge sorry, I've double-checked it and tests didn't run at all. To be honest, they are not running and for the current version of
|
That's probably because |
@armanbilge yep, it is. So, version with |
@danicheg thanks for looking into that. So, it definitely sounds like the current test suite is not sufficient then. I'll push a fix for that. |
@danicheg I added an |
This PR introduces a
ResourceSuiteLocalDeferredFixture[A]
. It has identical semantics to JVM-onlyResourceSuiteLocalFixture[A]
(i.e., allocate once per suite) but instead of providingA
provides anIO[A]
that is semantically blocked until the resource is allocated. This allows the fixture to be used on both JVM and JS.