-
Notifications
You must be signed in to change notification settings - Fork 28
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
Global matcher registration is not thread-safe #116
Comments
Hi @oceanful, thanks for opening this issue. It's true, Pegomock doesn't allow mock-setup in multiple goroutines (just for clarity, invoking the mocked methods from multiple goroutines is not a problem). Introducing a Mutex for this is actually not quite that trivial. As you noted, we'd have to lock the slice of matchers that a certain goroutine used for mock-setup. In this world, any call to a matcher like 2 suggestions that I'd like to go through first, before diving into the suggested Mutex:
|
Hi Peter, thank you for the thoughtful answer! I see now that because of the way the dsl is structured, the One idea would be an (optional) alternative grammar that allows the framework to grab a lock before the matchers and invocation are called ... something like: func WhenInvoking() func(invocation ...interface{}) *ongoingStubbing {
invocationLock.Lock()
return func(invocation ...interface{}) *ongoingStubbing {
defer invocationLock.Unlock()
return When(invocation...)
}
} Which would make testing code read like: WhenInvoking()(myMock.Method(AnyString(), AnyInt())).Then(...) Not quite as pretty as the current DSL but perhaps not too bad of an alternative when parallelism is desired. Also, thank you for offering alternatives!
|
Hey @oceanful, I think your approach could work. But agree that introducing |
Hi Peter, If we want to fix this in the current DSL, then I agree that your initial proposal is the way to go; grab the lock if not already held in func RegisterMatcher(...) {
lockIfNotLocked()
...
}
func When(...) {
lockIfNotLocked()
defer unlock()
...
}
func Verify(...) {
lockIfNotLocked()
defer unlock()
...
} As you've probably surmised, the |
When running tests in
t.Parallel()
, the Golang race detector often fails with a data race:Perhaps this can be addressed by locking on a Mutex when accessing
globalArgMatchers
, or encapsulating the slice of Matchers in a thread-safe object.Or let me know if there's a different approach I should be taking for using mocks in a parallel testing environment. Thank you!
The text was updated successfully, but these errors were encountered: