mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
fix: wait for prompt on rich param CLI test (#15406)
Fixes a race in TestUpdateValidateRichParameters where the parameter is sent prior to the prompt. Causes errors like: https://github.com/coder/coder/actions/runs/11681622439/job/32527173007 ``` ptytest.go:132: 2024-11-05 10:02:18.819: cmd: "bool_parameter" ptytest.go:167: 2024-11-05 10:02:18.819: cmd: matched "bool_parameter" = "bool_parameter" update_test.go:440: 2024-11-05 10:02:18.819: cmd: stdin: "cat\r\n" ptytest.go:132: 2024-11-05 10:02:18.819: cmd: "> Enter a value (default: \"\"): can't validate build parameter \"bool_parameter\": boolean value can be either \"true\" or \"false\"" ptytest.go:167: 2024-11-05 10:02:18.819: cmd: matched "boolean value can be either" = "\n> Enter a value (default: \"\"): can't validate build parameter \"bool_parameter\": boolean value can be either" update_test.go:440: 2024-11-05 10:02:18.819: cmd: stdin: "\r\n" ptytest.go:167: 2024-11-05 10:02:18.819: cmd: matched "Enter a value" = " \"true\" or \"false\"\n> Enter a value" update_test.go:440: 2024-11-05 10:02:18.819: cmd: stdin: "false\r\n" ptytest.go:132: 2024-11-05 10:02:18.821: cmd: "> Enter a value (default: \"\"): can't validate build parameter \"bool_parameter\": boolean value can be either \"true\" or \"false\"" ```
This commit is contained in:
@ -323,7 +323,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
err := inv.Run()
|
err := inv.Run()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt")
|
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt")
|
||||||
|
inv = inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -333,18 +335,16 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
matches := []string{
|
pty.ExpectMatch(stringParameterName)
|
||||||
stringParameterName, "$$",
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
"does not match", "",
|
pty.WriteLine("$$")
|
||||||
"Enter a value", "abc",
|
pty.ExpectMatch("does not match")
|
||||||
}
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
for i := 0; i < len(matches); i += 2 {
|
pty.WriteLine("")
|
||||||
match := matches[i]
|
pty.ExpectMatch("does not match")
|
||||||
value := matches[i+1]
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
pty.ExpectMatch(match)
|
pty.WriteLine("abc")
|
||||||
pty.WriteLine(value)
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
}
|
|
||||||
<-doneChan
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ValidateNumber", func(t *testing.T) {
|
t.Run("ValidateNumber", func(t *testing.T) {
|
||||||
@ -369,7 +369,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
err := inv.Run()
|
err := inv.Run()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt")
|
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -379,21 +381,16 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
matches := []string{
|
pty.ExpectMatch(numberParameterName)
|
||||||
numberParameterName, "12",
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
"is more than the maximum", "",
|
pty.WriteLine("12")
|
||||||
"Enter a value", "8",
|
pty.ExpectMatch("is more than the maximum")
|
||||||
}
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
for i := 0; i < len(matches); i += 2 {
|
pty.WriteLine("")
|
||||||
match := matches[i]
|
pty.ExpectMatch("is not a number")
|
||||||
value := matches[i+1]
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
pty.ExpectMatch(match)
|
pty.WriteLine("8")
|
||||||
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
if value != "" {
|
|
||||||
pty.WriteLine(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<-doneChan
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ValidateBool", func(t *testing.T) {
|
t.Run("ValidateBool", func(t *testing.T) {
|
||||||
@ -418,7 +415,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
err := inv.Run()
|
err := inv.Run()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt")
|
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt")
|
||||||
|
inv = inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -428,18 +427,16 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
matches := []string{
|
pty.ExpectMatch(boolParameterName)
|
||||||
boolParameterName, "cat",
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
"boolean value can be either", "",
|
pty.WriteLine("cat")
|
||||||
"Enter a value", "false",
|
pty.ExpectMatch("boolean value can be either \"true\" or \"false\"")
|
||||||
}
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
for i := 0; i < len(matches); i += 2 {
|
pty.WriteLine("")
|
||||||
match := matches[i]
|
pty.ExpectMatch("boolean value can be either \"true\" or \"false\"")
|
||||||
value := matches[i+1]
|
pty.ExpectMatch("> Enter a value (default: \"\"): ")
|
||||||
pty.ExpectMatch(match)
|
pty.WriteLine("false")
|
||||||
pty.WriteLine(value)
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
}
|
|
||||||
<-doneChan
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("RequiredParameterAdded", func(t *testing.T) {
|
t.Run("RequiredParameterAdded", func(t *testing.T) {
|
||||||
@ -485,7 +482,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace")
|
inv, root = clitest.New(t, "update", "my-workspace")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -508,7 +507,7 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
pty.WriteLine(value)
|
pty.WriteLine(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("OptionalParameterAdded", func(t *testing.T) {
|
t.Run("OptionalParameterAdded", func(t *testing.T) {
|
||||||
@ -555,7 +554,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace")
|
inv, root = clitest.New(t, "update", "my-workspace")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -566,7 +567,7 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
pty.ExpectMatch("Planning workspace...")
|
pty.ExpectMatch("Planning workspace...")
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ParameterOptionChanged", func(t *testing.T) {
|
t.Run("ParameterOptionChanged", func(t *testing.T) {
|
||||||
@ -612,7 +613,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace")
|
inv, root = clitest.New(t, "update", "my-workspace")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -636,7 +639,7 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ParameterOptionDisappeared", func(t *testing.T) {
|
t.Run("ParameterOptionDisappeared", func(t *testing.T) {
|
||||||
@ -683,7 +686,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace")
|
inv, root = clitest.New(t, "update", "my-workspace")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -707,7 +712,7 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ParameterOptionFailsMonotonicValidation", func(t *testing.T) {
|
t.Run("ParameterOptionFailsMonotonicValidation", func(t *testing.T) {
|
||||||
@ -739,7 +744,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt=true")
|
inv, root = clitest.New(t, "update", "my-workspace", "--always-prompt=true")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
|
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
@ -762,7 +769,7 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
pty.ExpectMatch(match)
|
pty.ExpectMatch(match)
|
||||||
}
|
}
|
||||||
|
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("ImmutableRequiredParameterExists_MutableRequiredParameterAdded", func(t *testing.T) {
|
t.Run("ImmutableRequiredParameterExists_MutableRequiredParameterAdded", func(t *testing.T) {
|
||||||
@ -804,7 +811,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace")
|
inv, root = clitest.New(t, "update", "my-workspace")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -828,7 +837,7 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("MutableRequiredParameterExists_ImmutableRequiredParameterAdded", func(t *testing.T) {
|
t.Run("MutableRequiredParameterExists_ImmutableRequiredParameterAdded", func(t *testing.T) {
|
||||||
@ -874,7 +883,9 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Update the workspace
|
// Update the workspace
|
||||||
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
inv, root = clitest.New(t, "update", "my-workspace")
|
inv, root = clitest.New(t, "update", "my-workspace")
|
||||||
|
inv.WithContext(ctx)
|
||||||
clitest.SetupConfig(t, member, root)
|
clitest.SetupConfig(t, member, root)
|
||||||
doneChan := make(chan struct{})
|
doneChan := make(chan struct{})
|
||||||
pty := ptytest.New(t).Attach(inv)
|
pty := ptytest.New(t).Attach(inv)
|
||||||
@ -898,6 +909,6 @@ func TestUpdateValidateRichParameters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<-doneChan
|
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func (e *outExpecter) expectMatcherFunc(ctx context.Context, str string, fn func
|
|||||||
e.fatalf("read error", "%v (wanted %q; got %q)", err, str, buffer.String())
|
e.fatalf("read error", "%v (wanted %q; got %q)", err, str, buffer.String())
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
e.logf("matched %q = %q", str, stripansi.Strip(buffer.String()))
|
e.logf("matched %q = %q", str, buffer.String())
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user