mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
e.g. Error: nomad/leader_test.go:382:12: non-constant format string in call to (*testing.common).Fatalf
132 lines
3.0 KiB
Go
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)
|
|
}
|
|
}
|