From 6fdad0272d1ef652dd43e2c377e8661bc74b8dd8 Mon Sep 17 00:00:00 2001 From: Ethan <39577870+ethanndickson@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:06:19 +1100 Subject: [PATCH] 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). --- cli/restart_test.go | 56 ++++++++++++++++++++++++--------------------- cli/start_test.go | 34 ++++++++++++++------------- cli/update_test.go | 21 +++++++++-------- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/cli/restart_test.go b/cli/restart_test.go index a17a9ba2a2..2179aea744 100644 --- a/cli/restart_test.go +++ b/cli/restart_test.go @@ -20,14 +20,16 @@ import ( func TestRestart(t *testing.T) { t.Parallel() - echoResponses := prepareEchoResponses([]*proto.RichParameter{ - { - Name: ephemeralParameterName, - Description: ephemeralParameterDescription, - Mutable: true, - Ephemeral: true, - }, - }) + echoResponses := func() *echo.Responses { + return prepareEchoResponses([]*proto.RichParameter{ + { + Name: ephemeralParameterName, + Description: ephemeralParameterDescription, + Mutable: true, + Ephemeral: true, + }, + }) + } t.Run("OK", func(t *testing.T) { t.Parallel() @@ -66,7 +68,7 @@ func TestRestart(t *testing.T) { client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.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}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.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}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.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}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID) @@ -280,24 +282,26 @@ func TestRestart(t *testing.T) { func TestRestartWithParameters(t *testing.T) { t.Parallel() - echoResponses := &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionPlan: []*proto.Response{ - { - Type: &proto.Response_Plan{ - Plan: &proto.PlanComplete{ - Parameters: []*proto.RichParameter{ - { - Name: immutableParameterName, - Description: immutableParameterDescription, - Required: true, + echoResponses := func() *echo.Responses { + return &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionPlan: []*proto.Response{ + { + Type: &proto.Response_Plan{ + Plan: &proto.PlanComplete{ + Parameters: []*proto.RichParameter{ + { + Name: immutableParameterName, + Description: immutableParameterDescription, + Required: true, + }, }, }, }, }, }, - }, - ProvisionApply: echo.ApplyComplete, + ProvisionApply: echo.ApplyComplete, + } } t.Run("DoNotAskForImmutables", func(t *testing.T) { @@ -307,7 +311,7 @@ func TestRestartWithParameters(t *testing.T) { client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) { diff --git a/cli/start_test.go b/cli/start_test.go index 48d4a1e74b..07577998fb 100644 --- a/cli/start_test.go +++ b/cli/start_test.go @@ -79,25 +79,27 @@ var ( func TestStart(t *testing.T) { t.Parallel() - echoResponses := &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionPlan: []*proto.Response{ - { - Type: &proto.Response_Plan{ - Plan: &proto.PlanComplete{ - Parameters: []*proto.RichParameter{ - { - Name: ephemeralParameterName, - Description: ephemeralParameterDescription, - Mutable: true, - Ephemeral: true, + echoResponses := func() *echo.Responses { + return &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionPlan: []*proto.Response{ + { + Type: &proto.Response_Plan{ + Plan: &proto.PlanComplete{ + Parameters: []*proto.RichParameter{ + { + Name: ephemeralParameterName, + Description: ephemeralParameterDescription, + Mutable: true, + Ephemeral: true, + }, }, }, }, }, }, - }, - ProvisionApply: echo.ApplyComplete, + ProvisionApply: echo.ApplyComplete, + } } t.Run("BuildOptions", func(t *testing.T) { @@ -106,7 +108,7 @@ func TestStart(t *testing.T) { client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.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}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) workspace := coderdtest.CreateWorkspace(t, member, template.ID) diff --git a/cli/update_test.go b/cli/update_test.go index 108923f281..6f061f29a7 100644 --- a/cli/update_test.go +++ b/cli/update_test.go @@ -101,13 +101,14 @@ func TestUpdateWithRichParameters(t *testing.T) { immutableParameterValue = "4" ) - echoResponses := prepareEchoResponses([]*proto.RichParameter{ - {Name: firstParameterName, Description: firstParameterDescription, Mutable: true}, - {Name: immutableParameterName, Description: immutableParameterDescription, Mutable: false}, - {Name: secondParameterName, Description: secondParameterDescription, Mutable: true}, - {Name: ephemeralParameterName, Description: ephemeralParameterDescription, Mutable: true, Ephemeral: true}, - }, - ) + echoResponses := func() *echo.Responses { + return prepareEchoResponses([]*proto.RichParameter{ + {Name: firstParameterName, Description: firstParameterDescription, Mutable: true}, + {Name: immutableParameterName, Description: immutableParameterDescription, Mutable: false}, + {Name: secondParameterName, Description: secondParameterDescription, Mutable: true}, + {Name: ephemeralParameterName, Description: ephemeralParameterDescription, Mutable: true, Ephemeral: true}, + }) + } t.Run("ImmutableCannotBeCustomized", func(t *testing.T) { t.Parallel() @@ -115,7 +116,7 @@ func TestUpdateWithRichParameters(t *testing.T) { client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) owner := coderdtest.CreateFirstUser(t, client) 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) 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}) owner := coderdtest.CreateFirstUser(t, client) 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) 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}) owner := coderdtest.CreateFirstUser(t, client) 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) template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)