Files
nomad/client/consul/consul_test.go
Daniel Bennett 04db81951f test: fix go 1.24 test complaints (#25346)
e.g. Error: nomad/leader_test.go:382:12: non-constant format string in call to (*testing.common).Fatalf
2025-03-11 11:01:39 -05:00

132 lines
3.0 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package consul
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"sync"
"testing"
"time"
consulapi "github.com/hashicorp/consul/api"
"github.com/hashicorp/nomad/helper/testlog"
"github.com/hashicorp/nomad/helper/uuid"
"github.com/hashicorp/nomad/nomad/mock"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/nomad/structs/config"
"github.com/shoenig/test/must"
)
type mockConsulServer struct {
httpSrv *httptest.Server
lock sync.RWMutex
errorCodeOnTokenSelf int
countTokenSelf int
}
func (m *mockConsulServer) resetTokenSelf(errNo int) {
m.lock.Lock()
defer m.lock.Unlock()
m.countTokenSelf = 0
m.errorCodeOnTokenSelf = errNo
}
func newMockConsulServer() *mockConsulServer {
srv := &mockConsulServer{}
mux := http.NewServeMux()
mux.HandleFunc("/v1/acl/token/self", func(w http.ResponseWriter, r *http.Request) {
srv.lock.RLock()
defer srv.lock.RUnlock()
srv.countTokenSelf++
if srv.errorCodeOnTokenSelf == 0 {
secretID := r.Header.Get("X-Consul-Token")
token := &consulapi.ACLToken{
SecretID: secretID,
}
buf, _ := json.Marshal(token)
fmt.Fprint(w, string(buf))
return
}
w.WriteHeader(srv.errorCodeOnTokenSelf)
fmt.Fprint(w, "{}")
})
srv.httpSrv = httptest.NewServer(mux)
return srv
}
type testClientCfg struct{ node *structs.Node }
func (c *testClientCfg) GetNode() *structs.Node {
return c.node
}
// TestConsul_TokenPreflightCheck verifies the retry logic for
func TestConsul_TokenPreflightCheck(t *testing.T) {
consulSrv := newMockConsulServer()
consulSrv.resetTokenSelf(404)
node := mock.Node()
node.Meta["consul.token_preflight_check.timeout"] = "100ms"
node.Meta["consul.token_preflight_check.base"] = "10ms"
clientCfg := &testClientCfg{node}
factory := NewConsulClientFactory(clientCfg)
cfg := &config.ConsulConfig{
Addr: consulSrv.httpSrv.URL,
}
client, err := factory(cfg, testlog.HCLogger(t))
must.NoError(t, err)
token := &consulapi.ACLToken{
SecretID: uuid.Generate(),
Namespace: "foo",
}
preflightErrorCh := make(chan error)
ctx1, cancel1 := context.WithTimeout(context.TODO(), time.Second*5)
defer cancel1()
go func() {
preflightErrorCh <- client.TokenPreflightCheck(ctx1, token)
}()
select {
case <-ctx1.Done():
t.Fatal("test timed out before check timed out")
case err := <-preflightErrorCh:
must.EqError(t, err, "Unexpected response code: 404 ({})")
must.GreaterEq(t, 5, consulSrv.countTokenSelf)
}
consulSrv.resetTokenSelf(0)
ctx2, cancel2 := context.WithTimeout(context.TODO(), time.Second*5)
defer cancel2()
go func() {
preflightErrorCh <- client.TokenPreflightCheck(ctx2, token)
}()
select {
case <-ctx2.Done():
t.Fatal("test timed out and check should not have timed out")
case err := <-preflightErrorCh:
must.NoError(t, err, must.Sprintf("preflight should pass: %v", err))
must.Eq(t, 1, consulSrv.countTokenSelf)
}
}