mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
fix(clitest): use separate channel when waiting for exit (#7231)
This commit is contained in:
@ -127,8 +127,8 @@ func extractTar(t *testing.T, data []byte, directory string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start runs the command in a goroutine and cleans it up when
|
// Start runs the command in a goroutine and cleans it up when the test
|
||||||
// the test completed.
|
// completed.
|
||||||
func Start(t *testing.T, inv *clibase.Invocation) {
|
func Start(t *testing.T, inv *clibase.Invocation) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ func (w *ErrorWaiter) Wait() error {
|
|||||||
var ok bool
|
var ok bool
|
||||||
w.cachedError, ok = <-w.c
|
w.cachedError, ok = <-w.c
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("unexpoected channel close")
|
panic("unexpected channel close")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return w.cachedError
|
return w.cachedError
|
||||||
@ -196,18 +196,18 @@ func (w *ErrorWaiter) RequireAs(want interface{}) {
|
|||||||
require.ErrorAs(w.t, w.Wait(), want)
|
require.ErrorAs(w.t, w.Wait(), want)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartWithWaiter runs the command in a goroutine but returns the error
|
// StartWithWaiter runs the command in a goroutine but returns the error instead
|
||||||
// instead of asserting it. This is useful for testing error cases.
|
// of asserting it. This is useful for testing error cases.
|
||||||
func StartWithWaiter(t *testing.T, inv *clibase.Invocation) *ErrorWaiter {
|
func StartWithWaiter(t *testing.T, inv *clibase.Invocation) *ErrorWaiter {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
errCh := make(chan error, 1)
|
|
||||||
|
|
||||||
var cleaningUp atomic.Bool
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ctx = inv.Context()
|
ctx = inv.Context()
|
||||||
cancel func()
|
cancel func()
|
||||||
|
|
||||||
|
cleaningUp atomic.Bool
|
||||||
|
errCh = make(chan error, 1)
|
||||||
|
doneCh = make(chan struct{})
|
||||||
)
|
)
|
||||||
if _, ok := ctx.Deadline(); !ok {
|
if _, ok := ctx.Deadline(); !ok {
|
||||||
ctx, cancel = context.WithDeadline(ctx, time.Now().Add(testutil.WaitMedium))
|
ctx, cancel = context.WithDeadline(ctx, time.Now().Add(testutil.WaitMedium))
|
||||||
@ -218,12 +218,13 @@ func StartWithWaiter(t *testing.T, inv *clibase.Invocation) *ErrorWaiter {
|
|||||||
inv = inv.WithContext(ctx)
|
inv = inv.WithContext(ctx)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
defer close(doneCh)
|
||||||
defer close(errCh)
|
defer close(errCh)
|
||||||
err := inv.Run()
|
err := inv.Run()
|
||||||
if cleaningUp.Load() && errors.Is(err, context.DeadlineExceeded) {
|
if cleaningUp.Load() && errors.Is(err, context.DeadlineExceeded) {
|
||||||
// If we're cleaning up, this error is likely related to the
|
// If we're cleaning up, this error is likely related to the CLI
|
||||||
// CLI teardown process. E.g., the server could be slow to shut
|
// teardown process. E.g., the server could be slow to shut down
|
||||||
// down Postgres.
|
// Postgres.
|
||||||
t.Logf("command %q timed out during test cleanup", inv.Command.FullName())
|
t.Logf("command %q timed out during test cleanup", inv.Command.FullName())
|
||||||
}
|
}
|
||||||
// Whether or not this fails the test is left to the caller.
|
// Whether or not this fails the test is left to the caller.
|
||||||
@ -235,7 +236,7 @@ func StartWithWaiter(t *testing.T, inv *clibase.Invocation) *ErrorWaiter {
|
|||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
cancel()
|
cancel()
|
||||||
cleaningUp.Store(true)
|
cleaningUp.Store(true)
|
||||||
<-errCh
|
<-doneCh
|
||||||
})
|
})
|
||||||
return &ErrorWaiter{c: errCh, t: t}
|
return &ErrorWaiter{c: errCh, t: t}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user