fix: avoid sharing echo.Responses across tests (#17211)

Closes https://github.com/coder/internal/issues/551

We've noticed lots of flakes in `go test -race` tests that use the echo provisioner. I believe the root cause of this to be https://github.com/coder/coder/pull/17012/, where we started mutating the `echo.Responses`. This only caused issues as we previously shared `echo.Responses` across multiple test cases.

This PR is therefore the same as https://github.com/coder/coder/pull/17128, but I believe this is all the cases where an `echo.Responses` is shared between tests - including tests that haven't flaked (yet).
This commit is contained in:
Ethan
2025-04-02 13:06:19 +11:00
committed by GitHub
parent d575e7f3ff
commit 6fdad0272d
3 changed files with 59 additions and 52 deletions

View File

@ -20,14 +20,16 @@ import (
func TestRestart(t *testing.T) { func TestRestart(t *testing.T) {
t.Parallel() t.Parallel()
echoResponses := prepareEchoResponses([]*proto.RichParameter{ echoResponses := func() *echo.Responses {
{ return prepareEchoResponses([]*proto.RichParameter{
Name: ephemeralParameterName, {
Description: ephemeralParameterDescription, Name: ephemeralParameterName,
Mutable: true, Description: ephemeralParameterDescription,
Ephemeral: true, Mutable: true,
}, Ephemeral: true,
}) },
})
}
t.Run("OK", func(t *testing.T) { t.Run("OK", func(t *testing.T) {
t.Parallel() t.Parallel()
@ -66,7 +68,7 @@ func TestRestart(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID)
@ -120,7 +122,7 @@ func TestRestart(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID)
@ -174,7 +176,7 @@ func TestRestart(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID)
@ -228,7 +230,7 @@ func TestRestart(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID)
@ -280,24 +282,26 @@ func TestRestart(t *testing.T) {
func TestRestartWithParameters(t *testing.T) { func TestRestartWithParameters(t *testing.T) {
t.Parallel() t.Parallel()
echoResponses := &echo.Responses{ echoResponses := func() *echo.Responses {
Parse: echo.ParseComplete, return &echo.Responses{
ProvisionPlan: []*proto.Response{ Parse: echo.ParseComplete,
{ ProvisionPlan: []*proto.Response{
Type: &proto.Response_Plan{ {
Plan: &proto.PlanComplete{ Type: &proto.Response_Plan{
Parameters: []*proto.RichParameter{ Plan: &proto.PlanComplete{
{ Parameters: []*proto.RichParameter{
Name: immutableParameterName, {
Description: immutableParameterDescription, Name: immutableParameterName,
Required: true, Description: immutableParameterDescription,
Required: true,
},
}, },
}, },
}, },
}, },
}, },
}, ProvisionApply: echo.ApplyComplete,
ProvisionApply: echo.ApplyComplete, }
} }
t.Run("DoNotAskForImmutables", func(t *testing.T) { t.Run("DoNotAskForImmutables", func(t *testing.T) {
@ -307,7 +311,7 @@ func TestRestartWithParameters(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) { workspace := coderdtest.CreateWorkspace(t, member, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {

View File

@ -79,25 +79,27 @@ var (
func TestStart(t *testing.T) { func TestStart(t *testing.T) {
t.Parallel() t.Parallel()
echoResponses := &echo.Responses{ echoResponses := func() *echo.Responses {
Parse: echo.ParseComplete, return &echo.Responses{
ProvisionPlan: []*proto.Response{ Parse: echo.ParseComplete,
{ ProvisionPlan: []*proto.Response{
Type: &proto.Response_Plan{ {
Plan: &proto.PlanComplete{ Type: &proto.Response_Plan{
Parameters: []*proto.RichParameter{ Plan: &proto.PlanComplete{
{ Parameters: []*proto.RichParameter{
Name: ephemeralParameterName, {
Description: ephemeralParameterDescription, Name: ephemeralParameterName,
Mutable: true, Description: ephemeralParameterDescription,
Ephemeral: true, Mutable: true,
Ephemeral: true,
},
}, },
}, },
}, },
}, },
}, },
}, ProvisionApply: echo.ApplyComplete,
ProvisionApply: echo.ApplyComplete, }
} }
t.Run("BuildOptions", func(t *testing.T) { t.Run("BuildOptions", func(t *testing.T) {
@ -106,7 +108,7 @@ func TestStart(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID)
@ -160,7 +162,7 @@ func TestStart(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID)

View File

@ -101,13 +101,14 @@ func TestUpdateWithRichParameters(t *testing.T) {
immutableParameterValue = "4" immutableParameterValue = "4"
) )
echoResponses := prepareEchoResponses([]*proto.RichParameter{ echoResponses := func() *echo.Responses {
{Name: firstParameterName, Description: firstParameterDescription, Mutable: true}, return prepareEchoResponses([]*proto.RichParameter{
{Name: immutableParameterName, Description: immutableParameterDescription, Mutable: false}, {Name: firstParameterName, Description: firstParameterDescription, Mutable: true},
{Name: secondParameterName, Description: secondParameterDescription, Mutable: true}, {Name: immutableParameterName, Description: immutableParameterDescription, Mutable: false},
{Name: ephemeralParameterName, Description: ephemeralParameterDescription, Mutable: true, Ephemeral: true}, {Name: secondParameterName, Description: secondParameterDescription, Mutable: true},
}, {Name: ephemeralParameterName, Description: ephemeralParameterDescription, Mutable: true, Ephemeral: true},
) })
}
t.Run("ImmutableCannotBeCustomized", func(t *testing.T) { t.Run("ImmutableCannotBeCustomized", func(t *testing.T) {
t.Parallel() t.Parallel()
@ -115,7 +116,7 @@ func TestUpdateWithRichParameters(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
@ -166,7 +167,7 @@ func TestUpdateWithRichParameters(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
@ -231,7 +232,7 @@ func TestUpdateWithRichParameters(t *testing.T) {
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client) owner := coderdtest.CreateFirstUser(t, client)
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID) member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, echoResponses())
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)