-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
get call count in thread safe way #965
base: master
Are you sure you want to change the base?
Conversation
m.mutex.Lock() | ||
defer m.mutex.Unlock() | ||
var actualCalls int | ||
for _, call := range m.calls() { |
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.
Please move the mutex locking right before the start of the critical section (i.e. before this line)
// NumberOfCalls returns the number of times a method was called | ||
func (m *Mock) NumberOfCalls(methodName string) int { | ||
m.mutex.Lock() | ||
defer m.mutex.Unlock() |
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.
Would it not make sense to move this unlock to right after the critical section (i.e. between lines 590,591)? My thought is that it being explicitly there will help the critical section unnecessarily ballooning by accident.
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'd ideally go with defer Unlock
since it's more "failsafe" in case the function body panics, however in this case, I don't think the critical section will panic at all. As such the result is identical the Unlock
can be moved to end. Though, as long as we're also aware of the fact that any newly introduced code prone to panic
will introduce a potential bug in future.
thoughts?
That’s a very good point. Fine to leave it as is then 🙂
… On 27 Jul 2020, at 22:32, Nisheeth Barthwal ***@***.***> wrote:
@nbaztec commented on this pull request.
In mock/mock.go:
> @@ -578,6 +578,19 @@ func (m *Mock) IsMethodCallable(t TestingT, methodName string, arguments ...inte
return false
}
+// NumberOfCalls returns the number of times a method was called
+func (m *Mock) NumberOfCalls(methodName string) int {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
I'd ideally go with defer Unlock since it's more "failsafe" in case the function body panics, however in this case, I don't think the critical section will panic at all. As such the result is identical the Unlock can be moved to end. Though, as long as we're also aware of the fact that any newly introduced code prone to panic will introduce a potential bug in future.
thoughts?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
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.
LGTM
@boyan-soubachov If it looks good to you too, feel free to merge |
@@ -1476,6 +1476,17 @@ func Test_MockReturnAndCalledConcurrent(t *testing.T) { | |||
wg.Wait() | |||
} | |||
|
|||
func Test_Mock_NumberOfCalls(t *testing.T) { |
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 add a test which covers the issue you fixed. I would imagine it would fail when run with go test -race
and without the fix you've added in this PR?
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, added the test to demonstrate data race.
Commenting out the mutex yields a data race with go test -v -race -run Test_Mock_NumberOfCallsIsThreadSafe ./...
The code looks good to me but I think we should have a test that demonstrates the issue (without the fix) and how it's fixed. |
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.
Thank you for your time and effort. @mvdkleijn , thoughts?
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.
lgtm
Is this safe to get merged? |
Can we merge this? It seems impl agreed and tests there, also |
@@ -578,6 +578,19 @@ func (m *Mock) IsMethodCallable(t TestingT, methodName string, arguments ...inte | |||
return false | |||
} | |||
|
|||
// NumberOfCalls returns the number of times a method was called | |||
func (m *Mock) NumberOfCalls(methodName string) int { |
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 not actually NumberOfCalls
, it's more like NumberOfCallsWithMethodName
. This PR is useful, but do we have to add another method here for people to count calls with certain arguments, or number of calls regardless of method name?
Perhaps something like I mentioned in #1128 is more useful?
Summary
Allows returning number of calls to a specific method in a thread safe way.
Changes
Adds a new method on the
Mock
object that returns the call count.Motivation
There was a need to get the call count information on a given mock. Accessing the
Calls
member leads to a race condition as the lock is neglected.Example usage (if applicable)
Related issues
Closes #964