diff --git a/.circleci/config.yml b/.circleci/config.yml index 29faee5b748..864863f316a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -293,11 +293,15 @@ jobs: goarch: type: string default: "amd64" + enable_race_testing: + type: boolean + default: false environment: GOTEST_PKGS_EXCLUDE: "<< parameters.exclude_packages >>" GOTEST_PKGS: "<< parameters.test_packages >>" GOTEST_MOD: "<< parameters.test_module >>" GOTESTARCH: "<< parameters.goarch >>" + ENABLE_RACE: "<<# parameters.enable_race_testing >>TRUE<>" steps: - checkout - install-golang @@ -616,6 +620,7 @@ workflows: name: "test-api" test_module: "api" filters: *backend_test_branches_filter + enable_race_testing: true - test-container: name: "test-devices" test_packages: "./devices/..." diff --git a/CHANGELOG.md b/CHANGELOG.md index b819742925f..88a129dff02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ IMPROVEMENTS: BUG FIXES: * agent: Only allow querying Prometheus formatted metrics if Prometheus is enabled within the config [[GH-10140](https://github.com/hashicorp/nomad/pull/10140)] + * api: Fixed a panic that may occur on concurrent access to an SDK client [[GH-10302](https://github.com/hashicorp/nomad/issues/10302)] * api: Added missing devices block to AllocatedTaskResources [[GH-10064](https://github.com/hashicorp/nomad/pull/10064)] * cli: Fixed a bug where non-int proxy port would panic CLI [[GH-10072](https://github.com/hashicorp/nomad/issues/10072)] * cli: Fixed a bug where `nomad operator debug` incorrectly parsed https Consul API URLs. [[GH-10082](https://github.com/hashicorp/nomad/pull/10082)] diff --git a/api/api.go b/api/api.go index d2deff27478..7ce7d9a1368 100644 --- a/api/api.go +++ b/api/api.go @@ -685,8 +685,8 @@ func (c *Client) newRequest(method, path string) (*request, error) { } } - if c.config.Headers != nil { - r.header = c.config.Headers + for key, values := range c.config.Headers { + r.header[key] = values } return r, nil diff --git a/api/api_test.go b/api/api_test.go index 0048ecdfe67..dda4a571a13 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -13,9 +13,10 @@ import ( "testing" "time" - "github.com/hashicorp/nomad/api/internal/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/hashicorp/nomad/api/internal/testutil" ) type configCallback func(c *Config) @@ -538,3 +539,28 @@ func TestCloneHttpClient(t *testing.T) { }) } + +func TestClient_HeaderRaceCondition(t *testing.T) { + require := require.New(t) + + conf := DefaultConfig() + conf.Headers = map[string][]string{ + "test-header": {"a"}, + } + client, err := NewClient(conf) + require.NoError(err) + + c := make(chan int) + + go func() { + req, _ := client.newRequest("GET", "/any/path/will/do") + r, _ := req.toHTTP() + c <- len(r.Header) + }() + req, _ := client.newRequest("GET", "/any/path/will/do") + r, _ := req.toHTTP() + + require.Len(r.Header, 2, "local request should have two headers") + require.Equal(2, <-c, "goroutine request should have two headers") + require.Len(conf.Headers, 1, "config headers should not mutate") +} diff --git a/vendor/github.com/hashicorp/nomad/api/api.go b/vendor/github.com/hashicorp/nomad/api/api.go index d2deff27478..7ce7d9a1368 100644 --- a/vendor/github.com/hashicorp/nomad/api/api.go +++ b/vendor/github.com/hashicorp/nomad/api/api.go @@ -685,8 +685,8 @@ func (c *Client) newRequest(method, path string) (*request, error) { } } - if c.config.Headers != nil { - r.header = c.config.Headers + for key, values := range c.config.Headers { + r.header[key] = values } return r, nil