-
-
Notifications
You must be signed in to change notification settings - Fork 784
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
Use ConTester to prove that the synchronized block is required #4672
Use ConTester to prove that the synchronized block is required #4672
Conversation
Codecov Report
@@ Coverage Diff @@
## main #4672 +/- ##
=========================================
Coverage 84.80% 84.80%
- Complexity 3452 3453 +1
=========================================
Files 492 492
Lines 11326 11328 +2
Branches 2086 2086
=========================================
+ Hits 9605 9607 +2
Misses 673 673
Partials 1048 1048
Continue to review full report at Codecov.
|
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's awesome 👍 It would help us catch a lot of concurrency problems we have. As a side note: we probably want to wait for a stable release of Contester before merging and releasing this.
@@ -26,6 +27,9 @@ class DetektPomModel(project: Project) : UserDataHolderBase(), PomModel { | |||
// Addresses https://github.com/detekt/detekt/issues/4609 | |||
synchronized(extensionArea) { | |||
if (!extensionArea.hasExtensionPoint(extension)) { | |||
ConTesterBreakpoint.defineBreakpoint("DetektPomModel.registerExtensionPoint") { | |||
extensionArea == getRootArea() |
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.
could you put a named parameter here?
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.
Could you provide an example of what you'd like it to look like?
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.
ConTesterBreakpoint.defineBreakpoint(
name = "DetektPomModel.registerExtensionPoint"
onlyWhen = { extensionArea == getRootArea() }
)
Something along those lines. onlyWhen
could be when
or condition
or whatever you prefer
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.
Ah. That's not possible unless there are Kotlin bindings for the library. condition
is preferable, to mimic debugger terminology.
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.
Sorry. I naively thought you wrote this in Kotlin, my bad :) You could add bindings for that btw.
condition is preferable, to mimic debugger terminology.
Yup that sounds great to me 👍
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, I would not want to impose a Kotlin runtime dependency for such a specific tool :)
ConTesterDriver.runToBreakpoint(thread1, "DetektPomModel.registerExtensionPoint") | ||
ConTesterDriver.runUntilBlockedOrTerminated(thread2) | ||
ConTesterDriver.join(thread1) |
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.
nit: That's mostly an API design decision, but they would read better if they're extension function instead.
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 get what you're saying, though I'm not too keen on extension functions, especially since they would be called join()
, start()
etc which already overload and would be confusing. How about some sort of ConTester
context, so the nature of the test is obvious?
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.
especially since they would be called join(), start() etc which already overload and would be confusing.
Agree. If you end up this way, I would not use those names and be a bit more specific with function naming.
How about some sort of ConTester context, so the nature of the test is obvious?
That also works eventually :)
Thanks :) It'd especially useful to regression test them. As for the side note: Yeah, I've possibly been too defensive about the naming, wanting to get a little bit of feedback on the tool before going |
It's odd to have test code in production code. But we already had regressions on this code so I imagine that it is worth it. I assume that the overhead in production is near to 0, right? |
The overhead is 0 for repeated calls, see https://github.com/davidburstrom/contester#benchmarks |
I get what you mean. Though, it's not much different than usage of
I've updated the benchmark, the first call is on micro-second duration. |
8b8fcbf
to
9572741
Compare
I've released a 0.1.0 GA, just waiting for it to appear on Maven Central. |
9572741
to
151d8eb
Compare
I vote to move this one to |
I'm fine with that :) |
151d8eb
to
4a0a216
Compare
@BraisGabin @cortinico I've released version 0.2.0 of ConTester which fixes a minor bug. Since Detekt 1.20.0 is released, could we consider merging this? I've rebased on top of latest |
Thanks for that! :) |
Thanks for doing this 🙏 |
Relates to PR #4631
The issue that was fixed was never proven, due to lack of test tooling. Therefore, I wrote the ConTester utility (https://github.com/davidburstrom/contester) which allows for defining breakpoints in the production code.
If the
synchronized
block is removed, the tests start to fail for the reason indicated in #4609