-
Notifications
You must be signed in to change notification settings - Fork 59
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
Introduce context aware helpers for context related testing #86
Conversation
I like the idea. However, my blocking concern is that they overload the clock interface with methods that don't have analogs in https://pkg.go.dev/time, rather they are functions from https://pkg.go.dev/context I'd support adding these to an unexported struct (maybe The fast/easy way to do this would be with You might consider trying to implement the unexported struct to intercept So.. I think we should offer our own cancel function, since we'll be negating the parent context's, i.e the function signature should be |
hmm. Could you elaborate?
Both look the same to me, so I can switch from methods to functions. |
I think I may have miscommunicated. Do you agree that something needs to implement My stance is:
My proposal is to make a struct like:
and we'll most certainly need a function to "construct" it, similar to your proposal #2. I'm against your proposal #1 and support your proposal #2 in concept, with 2 clarifications:
|
Ok. I'm still not 100% sure if I understood you correctly, but I've updated the PR with the #2 approach. The most considerable flow of this design changes the behavior from context.WithTimeout and context.WithDeadline from the code that does not use clockwork. |
@@ -51,3 +54,6 @@ func (f *fakeTimer) expire(now time.Time) *time.Duration { | |||
} | |||
return nil | |||
} | |||
|
|||
// Sleep momentarily so that other goroutines can process. |
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 delete this. We can't introduce arbitrary sleeps in test code.
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.
Unfortunately, without this code, AfterFunc does not guarantee a function call.
I can try to find a workaround, but I am unsure if I can succeed. Calling runtime.GoSched() is not enough.
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.
Hmm, that is a little bit of a code smell. Working with clocks and goroutines make it easy to introduce race conditions, and I want to avoid that. Let me take a look at the problem we are trying to solve again.
PS - Sorry this review took so long. :(
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 wanted to share my initial thoughts in #92. Obviously the With*
functions are not finalized and I just realized afterTime
isn't necessary. Regardless, I think my major takeaways are:
- We need to provide a way for the user that created the context to cancel the context they receive, even if we aren't respecting parent cancellation.
- I think we can do this with only a goroutine and 2 select statements(?)
I haven't started testing yet, so maybe I haven't hit the same issue as you that seems to require the sleep?
LMK if anything stands out to you. Going to continue working through it over the weekend.
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 take a look at #92. As far as I am aware, it has no race conditions and although we do have to sleep at 1 point in 2 different test cases, those cases are run in parallel and that sleep is not in the library's code path.
I'll let that PR hang for comments for ~2 weeks. LMK if that gives you everything you need or if you have any concerns.
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 added a comment on usage that is addressed by my PR but is not addressed in #92.
Let me know what you think.
Meanwhile, I'll try to work around the time.Sleep issue.
Hey folks.
I started using the library and found a missing piece that is very helpful for my case.
We use both time related functions and context.Timeout, but we want to be able to orchestrate all operations with a single time source.
I've introduced the logic that was already done by benbjohnson library https://github.com/benbjohnson/clock/blob/master/context.go
While testing context related things, I've also bumped into a problem with AfterFunc, which did not provide a guarantee of call on expiration. I've borrowed a "fix" with a time.Sleep from benbjohnson library. Without it, it is impossible to guarantee the call of the afterfunc.
I've ran tests for a few thousands times, but haven't see any issues.
Let me know if you have any concerns, or maybe you can help with a better way to fix this race.