add await.Require and await.RequireTrue#9490
Conversation
7d3afac to
4e042ac
Compare
7624541 to
1814d82
Compare
| s.NoError(descErr) | ||
| s.NotNil(desc) | ||
| s.NotNil(desc.GetPendingWorkflowTask()) | ||
| }, 5*time.Second, 250*time.Millisecond, "speculative WFT should be scheduled after sending update") |
3343e44 to
96a2172
Compare
| - pattern: '(^|\.)(Eventually|Eventuallyf|EventuallyWithT|EventuallyWithTf)(\(|$)' | ||
| msg: "Use await.Require / s.Await for assertion conditions, or await.RequireTrue / s.AwaitTrue for bool predicates, instead of testify Eventually helpers" |
There was a problem hiding this comment.
Require new code to use new Await
| s.AwaitTrue(func() bool { | ||
| // wait for workflow task to fail 3 times | ||
| return atomic.LoadInt32(&failures) >= 3 | ||
| }, 10*time.Second, 50*time.Millisecond) |
There was a problem hiding this comment.
^ AwaitTrue example
| ```go | ||
| s.Await(func(s *MySuite) { | ||
| resp, err := client.GetStatus(s.Context()) |
There was a problem hiding this comment.
This is the sleekest way I can imagine doing this.
| Execution: wfExecution, | ||
| }) | ||
| return descErr == nil && desc.GetPendingWorkflowTask() != nil | ||
| s.NoError(descErr) |
There was a problem hiding this comment.
I think this will completely eliminate a lot of "using the wrong t" issues.
| s.Eventually(func() bool { | ||
| desc, descErr := env.FrontendClient().DescribeWorkflowExecution(testcore.NewContext(), | ||
| s.Awaitf(func(s *PrematureEosTestSuite) { | ||
| desc, descErr := env.FrontendClient().DescribeWorkflowExecution(s.Context(), |
There was a problem hiding this comment.
What I like about this is that s.Context() is the same in and outside the block; but it will resolve to the right context.
| Errorf(string, ...any) | ||
| Fatal(...any) | ||
| Fatalf(string, ...any) | ||
| } |
There was a problem hiding this comment.
^ using interface so it doesn't require concrete testing.T
There was a problem hiding this comment.
type TB interface {
testing.TB
}
To simplify
| Errorf(string, ...any) | ||
| Fatal(...any) | ||
| Fatalf(string, ...any) | ||
| } |
There was a problem hiding this comment.
type TB interface {
testing.TB
}
To simplify
| @@ -0,0 +1,39 @@ | |||
| // Package await provides polling-based test assertions as a replacement | |||
There was a problem hiding this comment.
This should be in a doc.go file
There was a problem hiding this comment.
I've seen both approaches (doc.go and same name as package), but happy to move it to doc.go
| initSuite(t *testing.T, assertT require.TestingT, ctx contextOverride) | ||
| } | ||
|
|
||
| type contextOverride struct { |
There was a problem hiding this comment.
Is this necessary? I only see it used in initSuite to set the passed in ctx.
| tb.Helper() | ||
| run(testcontext.New(tb), tb, func(t *T) { | ||
| if !condition() { | ||
| t.failed = true |
There was a problem hiding this comment.
There is a t.Failed() func, could use that or remove that func.
| if !condition() { | ||
| t.failed = true | ||
| } | ||
| }, timeout, pollInterval, "", "await.RequireTrue", requireTrueMisuseHint, false) |
There was a problem hiding this comment.
The name "await.RequireTrue" is not piped in by the functions that call RequireTrue so it will always show up as await.RequireTrue
| if s.ctx != nil { | ||
| return s.ctx | ||
| } | ||
| return testcontext.New(s.T()) |
There was a problem hiding this comment.
This should set s.ctx so we can avoid the mutex lock/unlock on every call to s.Context()
There was a problem hiding this comment.
There could be a race between the test and a await/regular goroutine, though, both calling s.Context() which would likely create a data race warning and fail the test. But I can add a sync.Once to only call testcontext.New at most once.
What changed?
Introduces
common/testing/await, a polling-based test helper that replaces testify'sEventually/EventuallyWithT.Why?
From the package doc:
The upstream fix (testify#1657) aims to address several of these but has been open since Oct 2024 without merging.
How did you test it?
Potential risks
The biggest downside is that it adds more code that we own. But apart from any unknown bugs, this package should rarely/never change.