80ff174880
Replaces #7559 Running tests in parallel, with background goroutines, results in test output not being associated with the correct test. `go test` does not make any guarantees about output from goroutines being attributed to the correct test case. Attaching log output from background goroutines also cause data races. If the goroutine outlives the test, it will race with the test being marked done. Previously this was noticed as a panic when logging, but with the race detector enabled it is shown as a data race. The previous solution did not address the problem of correct test attribution because test output could still be hidden when it was associated with a test that did not fail. You would have to look at all of the log output to find the relevant lines. It also made debugging test failures more difficult because each log line was very long. This commit attempts a new approach. Instead of printing all the logs, only print when a test fails. This should work well when there are a small number of failures, but may not work well when there are many test failures at the same time. In those cases the failures are unlikely a result of a specific test, and the log output is likely less useful. All of the logs are printed from the test goroutine, so they should be associated with the correct test. Also removes some test helpers that were not used, or only had a single caller. Packages which expose many functions with similar names can be difficult to use correctly. Related: https://github.com/golang/go/issues/38458 (may be fixed in go1.15) https://github.com/golang/go/issues/38382#issuecomment-612940030
555 lines
17 KiB
Go
555 lines
17 KiB
Go
package agent
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/armon/go-metrics"
|
|
"github.com/hashicorp/consul/acl"
|
|
"github.com/hashicorp/consul/agent/config"
|
|
"github.com/hashicorp/consul/agent/consul"
|
|
"github.com/hashicorp/consul/agent/local"
|
|
"github.com/hashicorp/consul/agent/structs"
|
|
"github.com/hashicorp/consul/lib"
|
|
"github.com/hashicorp/consul/sdk/testutil"
|
|
"github.com/hashicorp/consul/types"
|
|
"github.com/hashicorp/go-hclog"
|
|
"github.com/hashicorp/serf/serf"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type authzResolver func(string) (structs.ACLIdentity, acl.Authorizer, error)
|
|
type identResolver func(string) (structs.ACLIdentity, error)
|
|
|
|
type TestACLAgent struct {
|
|
// Name is an optional name of the agent.
|
|
Name string
|
|
|
|
HCL string
|
|
|
|
// Config is the agent configuration. If Config is nil then
|
|
// TestConfig() is used. If Config.DataDir is set then it is
|
|
// the callers responsibility to clean up the data directory.
|
|
// Otherwise, a temporary data directory is created and removed
|
|
// when Shutdown() is called.
|
|
Config *config.RuntimeConfig
|
|
|
|
// LogOutput is the sink for the logs. If nil, logs are written
|
|
// to os.Stderr.
|
|
LogOutput io.Writer
|
|
|
|
// DataDir is the data directory which is used when Config.DataDir
|
|
// is not set. It is created automatically and removed when
|
|
// Shutdown() is called.
|
|
DataDir string
|
|
|
|
resolveAuthzFn authzResolver
|
|
resolveIdentFn identResolver
|
|
|
|
*Agent
|
|
}
|
|
|
|
// NewTestACLAgent does just enough so that all the code within agent/acl.go can work
|
|
// Basically it needs a local state for some of the vet* functions, a logger and a delegate.
|
|
// The key is that we are the delegate so we can control the ResolveToken responses
|
|
func NewTestACLAgent(t *testing.T, name string, hcl string, resolveAuthz authzResolver, resolveIdent identResolver) *TestACLAgent {
|
|
a := &TestACLAgent{Name: name, HCL: hcl, resolveAuthzFn: resolveAuthz, resolveIdentFn: resolveIdent}
|
|
dataDir := `data_dir = "acl-agent"`
|
|
|
|
logOutput := testutil.NewLogBuffer(t)
|
|
logger := hclog.NewInterceptLogger(&hclog.LoggerOptions{
|
|
Name: a.Name,
|
|
Level: hclog.Debug,
|
|
Output: logOutput,
|
|
})
|
|
|
|
opts := []AgentOption{
|
|
WithLogger(logger),
|
|
WithBuilderOpts(config.BuilderOpts{
|
|
HCL: []string{
|
|
TestConfigHCL(NodeID()),
|
|
a.HCL,
|
|
dataDir,
|
|
},
|
|
}),
|
|
}
|
|
|
|
agent, err := New(opts...)
|
|
require.NoError(t, err)
|
|
a.Config = agent.GetConfig()
|
|
a.Agent = agent
|
|
|
|
agent.LogOutput = logOutput
|
|
agent.logger = logger
|
|
agent.MemSink = metrics.NewInmemSink(1*time.Second, time.Minute)
|
|
|
|
a.Agent.delegate = a
|
|
a.Agent.State = local.NewState(LocalConfig(a.Config), a.Agent.logger, a.Agent.tokens)
|
|
a.Agent.State.TriggerSyncChanges = func() {}
|
|
return a
|
|
}
|
|
|
|
func (a *TestACLAgent) UseLegacyACLs() bool {
|
|
return false
|
|
}
|
|
|
|
func (a *TestACLAgent) ResolveToken(secretID string) (acl.Authorizer, error) {
|
|
if a.resolveAuthzFn == nil {
|
|
return nil, fmt.Errorf("ResolveToken call is unexpected - no authz resolver callback set")
|
|
}
|
|
|
|
_, authz, err := a.resolveAuthzFn(secretID)
|
|
return authz, err
|
|
}
|
|
|
|
func (a *TestACLAgent) ResolveTokenToIdentityAndAuthorizer(secretID string) (structs.ACLIdentity, acl.Authorizer, error) {
|
|
if a.resolveAuthzFn == nil {
|
|
return nil, nil, fmt.Errorf("ResolveTokenToIdentityAndAuthorizer call is unexpected - no authz resolver callback set")
|
|
}
|
|
|
|
return a.resolveAuthzFn(secretID)
|
|
}
|
|
|
|
func (a *TestACLAgent) ResolveTokenToIdentity(secretID string) (structs.ACLIdentity, error) {
|
|
if a.resolveIdentFn == nil {
|
|
return nil, fmt.Errorf("ResolveTokenToIdentity call is unexpected - no ident resolver callback set")
|
|
}
|
|
|
|
return a.resolveIdentFn(secretID)
|
|
}
|
|
|
|
func (a *TestACLAgent) ResolveTokenAndDefaultMeta(secretID string, entMeta *structs.EnterpriseMeta, authzContext *acl.AuthorizerContext) (acl.Authorizer, error) {
|
|
identity, authz, err := a.ResolveTokenToIdentityAndAuthorizer(secretID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Default the EnterpriseMeta based on the Tokens meta or actual defaults
|
|
// in the case of unknown identity
|
|
if identity != nil {
|
|
entMeta.Merge(identity.EnterpriseMetadata())
|
|
} else {
|
|
entMeta.Merge(structs.DefaultEnterpriseMeta())
|
|
}
|
|
|
|
// Use the meta to fill in the ACL authorization context
|
|
entMeta.FillAuthzContext(authzContext)
|
|
|
|
return authz, err
|
|
}
|
|
|
|
// All of these are stubs to satisfy the interface
|
|
func (a *TestACLAgent) GetLANCoordinate() (lib.CoordinateSet, error) {
|
|
return nil, fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) Leave() error {
|
|
return fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) LANMembers() []serf.Member {
|
|
return nil
|
|
}
|
|
func (a *TestACLAgent) LANMembersAllSegments() ([]serf.Member, error) {
|
|
return nil, fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) LANSegmentMembers(segment string) ([]serf.Member, error) {
|
|
return nil, fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) LocalMember() serf.Member {
|
|
return serf.Member{}
|
|
}
|
|
func (a *TestACLAgent) JoinLAN(addrs []string) (n int, err error) {
|
|
return 0, fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) RemoveFailedNode(node string, prune bool) error {
|
|
return fmt.Errorf("Unimplemented")
|
|
}
|
|
|
|
func (a *TestACLAgent) RPC(method string, args interface{}, reply interface{}) error {
|
|
return fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) SnapshotRPC(args *structs.SnapshotRequest, in io.Reader, out io.Writer, replyFn structs.SnapshotReplyFn) error {
|
|
return fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) Shutdown() error {
|
|
return fmt.Errorf("Unimplemented")
|
|
}
|
|
func (a *TestACLAgent) Stats() map[string]map[string]string {
|
|
return nil
|
|
}
|
|
func (a *TestACLAgent) ReloadConfig(config *consul.Config) error {
|
|
return fmt.Errorf("Unimplemented")
|
|
}
|
|
|
|
func TestACL_Version8EnabledByDefault(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
called := false
|
|
resolveFn := func(string) (structs.ACLIdentity, acl.Authorizer, error) {
|
|
called = true
|
|
return nil, nil, acl.ErrNotFound
|
|
}
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), resolveFn, nil)
|
|
|
|
_, err := a.resolveToken("nope")
|
|
require.Error(t, err)
|
|
require.True(t, called)
|
|
}
|
|
|
|
func TestACL_AgentMasterToken(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), nil, nil)
|
|
a.loadTokens(a.config)
|
|
authz, err := a.resolveToken("towel")
|
|
require.NotNil(t, authz)
|
|
require.Nil(t, err)
|
|
|
|
require.Equal(t, acl.Allow, authz.AgentRead(a.config.NodeName, nil))
|
|
require.Equal(t, acl.Allow, authz.AgentWrite(a.config.NodeName, nil))
|
|
require.Equal(t, acl.Allow, authz.NodeRead("foobarbaz", nil))
|
|
require.Equal(t, acl.Deny, authz.NodeWrite("foobarbaz", nil))
|
|
}
|
|
|
|
func TestACL_RootAuthorizersDenied(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), nil, nil)
|
|
authz, err := a.resolveToken("deny")
|
|
require.Nil(t, authz)
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrRootDenied(err))
|
|
authz, err = a.resolveToken("allow")
|
|
require.Nil(t, authz)
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrRootDenied(err))
|
|
authz, err = a.resolveToken("manage")
|
|
require.Nil(t, authz)
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrRootDenied(err))
|
|
}
|
|
|
|
func authzFromPolicy(policy *acl.Policy, cfg *acl.Config) (acl.Authorizer, error) {
|
|
return acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), []*acl.Policy{policy}, cfg)
|
|
}
|
|
|
|
type testToken struct {
|
|
token structs.ACLToken
|
|
// yes the rules can exist on the token itself but that is legacy behavior
|
|
// that I would prefer these tests not rely on
|
|
rules string
|
|
}
|
|
|
|
var (
|
|
nodeROSecret = "7e80d017-bccc-492f-8dec-65f03aeaebf3"
|
|
nodeRWSecret = "e3586ee5-02a2-4bf4-9ec3-9c4be7606e8c"
|
|
serviceROSecret = "3d2c8552-df3b-4da7-9890-36885cbf56ac"
|
|
serviceRWSecret = "4a1017a2-f788-4be3-93f2-90566f1340bb"
|
|
otherRWSecret = "a38e8016-91b6-4876-b3e7-a307abbb2002"
|
|
|
|
testTokens = map[string]testToken{
|
|
nodeROSecret: {
|
|
token: structs.ACLToken{
|
|
AccessorID: "9df2d1a4-2d07-414e-8ead-6053f56ed2eb",
|
|
SecretID: nodeROSecret,
|
|
},
|
|
rules: `node_prefix "Node" { policy = "read" }`,
|
|
},
|
|
nodeRWSecret: {
|
|
token: structs.ACLToken{
|
|
AccessorID: "efb6b7d5-d343-47c1-b4cb-aa6b94d2f490",
|
|
SecretID: nodeRWSecret,
|
|
},
|
|
rules: `node_prefix "Node" { policy = "write" }`,
|
|
},
|
|
serviceROSecret: {
|
|
token: structs.ACLToken{
|
|
AccessorID: "0da53edb-36e5-4603-9c31-79965bad45f5",
|
|
SecretID: serviceROSecret,
|
|
},
|
|
rules: `service_prefix "service" { policy = "read" }`,
|
|
},
|
|
serviceRWSecret: {
|
|
token: structs.ACLToken{
|
|
AccessorID: "52504258-137a-41e6-9326-01f40e80872e",
|
|
SecretID: serviceRWSecret,
|
|
},
|
|
rules: `service_prefix "service" { policy = "write" }`,
|
|
},
|
|
otherRWSecret: {
|
|
token: structs.ACLToken{
|
|
AccessorID: "5e032c5b-c39e-4552-b5ad-8a9365b099c4",
|
|
SecretID: otherRWSecret,
|
|
},
|
|
rules: `service_prefix "other" { policy = "write" }`,
|
|
},
|
|
}
|
|
)
|
|
|
|
func catalogPolicy(token string) (structs.ACLIdentity, acl.Authorizer, error) {
|
|
tok, ok := testTokens[token]
|
|
if !ok {
|
|
return nil, nil, acl.ErrNotFound
|
|
}
|
|
|
|
policy, err := acl.NewPolicyFromSource("", 0, tok.rules, acl.SyntaxCurrent, nil, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
authz, err := authzFromPolicy(policy, nil)
|
|
return &tok.token, authz, err
|
|
}
|
|
|
|
func catalogIdent(token string) (structs.ACLIdentity, error) {
|
|
tok, ok := testTokens[token]
|
|
if !ok {
|
|
return nil, acl.ErrNotFound
|
|
}
|
|
|
|
return &tok.token, nil
|
|
}
|
|
|
|
func TestACL_vetServiceRegister(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
// Register a new service, with permission.
|
|
err := a.vetServiceRegister(serviceRWSecret, &structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "service",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Register a new service without write privs.
|
|
err = a.vetServiceRegister(serviceROSecret, &structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "service",
|
|
})
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
|
|
// Try to register over a service without write privs to the existing
|
|
// service.
|
|
a.State.AddService(&structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "other",
|
|
}, "")
|
|
err = a.vetServiceRegister(serviceRWSecret, &structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "service",
|
|
})
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
}
|
|
|
|
func TestACL_vetServiceUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
// Update a service that doesn't exist.
|
|
err := a.vetServiceUpdate(serviceRWSecret, structs.NewServiceID("my-service", nil))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "Unknown service")
|
|
|
|
// Update with write privs.
|
|
a.State.AddService(&structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "service",
|
|
}, "")
|
|
err = a.vetServiceUpdate(serviceRWSecret, structs.NewServiceID("my-service", nil))
|
|
require.NoError(t, err)
|
|
|
|
// Update without write privs.
|
|
err = a.vetServiceUpdate(serviceROSecret, structs.NewServiceID("my-service", nil))
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
}
|
|
|
|
func TestACL_vetCheckRegister(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
// Register a new service check with write privs.
|
|
err := a.vetCheckRegister(serviceRWSecret, &structs.HealthCheck{
|
|
CheckID: types.CheckID("my-check"),
|
|
ServiceID: "my-service",
|
|
ServiceName: "service",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Register a new service check without write privs.
|
|
err = a.vetCheckRegister(serviceROSecret, &structs.HealthCheck{
|
|
CheckID: types.CheckID("my-check"),
|
|
ServiceID: "my-service",
|
|
ServiceName: "service",
|
|
})
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
|
|
// Register a new node check with write privs.
|
|
err = a.vetCheckRegister(nodeRWSecret, &structs.HealthCheck{
|
|
CheckID: types.CheckID("my-check"),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Register a new node check without write privs.
|
|
err = a.vetCheckRegister(nodeROSecret, &structs.HealthCheck{
|
|
CheckID: types.CheckID("my-check"),
|
|
})
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
|
|
// Try to register over a service check without write privs to the
|
|
// existing service.
|
|
a.State.AddService(&structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "service",
|
|
}, "")
|
|
a.State.AddCheck(&structs.HealthCheck{
|
|
CheckID: types.CheckID("my-check"),
|
|
ServiceID: "my-service",
|
|
ServiceName: "other",
|
|
}, "")
|
|
err = a.vetCheckRegister(serviceRWSecret, &structs.HealthCheck{
|
|
CheckID: types.CheckID("my-check"),
|
|
ServiceID: "my-service",
|
|
ServiceName: "service",
|
|
})
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
|
|
// Try to register over a node check without write privs to the node.
|
|
a.State.AddCheck(&structs.HealthCheck{
|
|
CheckID: types.CheckID("my-node-check"),
|
|
}, "")
|
|
err = a.vetCheckRegister(serviceRWSecret, &structs.HealthCheck{
|
|
CheckID: types.CheckID("my-node-check"),
|
|
ServiceID: "my-service",
|
|
ServiceName: "service",
|
|
})
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
}
|
|
|
|
func TestACL_vetCheckUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
// Update a check that doesn't exist.
|
|
err := a.vetCheckUpdate(nodeRWSecret, structs.NewCheckID("my-check", nil))
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "Unknown check")
|
|
|
|
// Update service check with write privs.
|
|
a.State.AddService(&structs.NodeService{
|
|
ID: "my-service",
|
|
Service: "service",
|
|
}, "")
|
|
a.State.AddCheck(&structs.HealthCheck{
|
|
CheckID: types.CheckID("my-service-check"),
|
|
ServiceID: "my-service",
|
|
ServiceName: "service",
|
|
}, "")
|
|
err = a.vetCheckUpdate(serviceRWSecret, structs.NewCheckID("my-service-check", nil))
|
|
require.NoError(t, err)
|
|
|
|
// Update service check without write privs.
|
|
err = a.vetCheckUpdate(serviceROSecret, structs.NewCheckID("my-service-check", nil))
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err), "not permission denied: %s", err.Error())
|
|
|
|
// Update node check with write privs.
|
|
a.State.AddCheck(&structs.HealthCheck{
|
|
CheckID: types.CheckID("my-node-check"),
|
|
}, "")
|
|
err = a.vetCheckUpdate(nodeRWSecret, structs.NewCheckID("my-node-check", nil))
|
|
require.NoError(t, err)
|
|
|
|
// Update without write privs.
|
|
err = a.vetCheckUpdate(nodeROSecret, structs.NewCheckID("my-node-check", nil))
|
|
require.Error(t, err)
|
|
require.True(t, acl.IsErrPermissionDenied(err))
|
|
}
|
|
|
|
func TestACL_filterMembers(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
var members []serf.Member
|
|
require.NoError(t, a.filterMembers(nodeROSecret, &members))
|
|
require.Len(t, members, 0)
|
|
|
|
members = []serf.Member{
|
|
{Name: "Node 1"},
|
|
{Name: "Nope"},
|
|
{Name: "Node 2"},
|
|
}
|
|
require.NoError(t, a.filterMembers(nodeROSecret, &members))
|
|
require.Len(t, members, 2)
|
|
require.Equal(t, members[0].Name, "Node 1")
|
|
require.Equal(t, members[1].Name, "Node 2")
|
|
}
|
|
|
|
func TestACL_filterServices(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
services := make(map[structs.ServiceID]*structs.NodeService)
|
|
require.NoError(t, a.filterServices(nodeROSecret, &services))
|
|
|
|
services[structs.NewServiceID("my-service", nil)] = &structs.NodeService{ID: "my-service", Service: "service"}
|
|
services[structs.NewServiceID("my-other", nil)] = &structs.NodeService{ID: "my-other", Service: "other"}
|
|
require.NoError(t, a.filterServices(serviceROSecret, &services))
|
|
require.Contains(t, services, structs.NewServiceID("my-service", nil))
|
|
require.NotContains(t, services, structs.NewServiceID("my-other", nil))
|
|
}
|
|
|
|
func TestACL_filterChecks(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), catalogPolicy, catalogIdent)
|
|
|
|
checks := make(map[structs.CheckID]*structs.HealthCheck)
|
|
require.NoError(t, a.filterChecks(nodeROSecret, &checks))
|
|
|
|
checks[structs.NewCheckID("my-node", nil)] = &structs.HealthCheck{}
|
|
checks[structs.NewCheckID("my-service", nil)] = &structs.HealthCheck{ServiceName: "service"}
|
|
checks[structs.NewCheckID("my-other", nil)] = &structs.HealthCheck{ServiceName: "other"}
|
|
require.NoError(t, a.filterChecks(serviceROSecret, &checks))
|
|
_, ok := checks[structs.NewCheckID("my-node", nil)]
|
|
require.False(t, ok)
|
|
_, ok = checks[structs.NewCheckID("my-service", nil)]
|
|
require.True(t, ok)
|
|
_, ok = checks[structs.NewCheckID("my-other", nil)]
|
|
require.False(t, ok)
|
|
|
|
checks[structs.NewCheckID("my-node", nil)] = &structs.HealthCheck{}
|
|
checks[structs.NewCheckID("my-service", nil)] = &structs.HealthCheck{ServiceName: "service"}
|
|
checks[structs.NewCheckID("my-other", nil)] = &structs.HealthCheck{ServiceName: "other"}
|
|
require.NoError(t, a.filterChecks(nodeROSecret, &checks))
|
|
_, ok = checks[structs.NewCheckID("my-node", nil)]
|
|
require.True(t, ok)
|
|
_, ok = checks[structs.NewCheckID("my-service", nil)]
|
|
require.False(t, ok)
|
|
_, ok = checks[structs.NewCheckID("my-other", nil)]
|
|
require.False(t, ok)
|
|
}
|
|
|
|
func TestACL_ResolveIdentity(t *testing.T) {
|
|
t.Parallel()
|
|
a := NewTestACLAgent(t, t.Name(), TestACLConfig(), nil, catalogIdent)
|
|
|
|
// this test is meant to ensure we are calling the correct function
|
|
// which is ResolveTokenToIdentity on the Agent delegate. Our
|
|
// nil authz resolver will cause it to emit an error if used
|
|
ident, err := a.resolveIdentityFromToken(nodeROSecret)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, ident)
|
|
|
|
// just double checkingto ensure if we had used the wrong function
|
|
// that an error would be produced
|
|
_, err = a.resolveToken(nodeROSecret)
|
|
require.Error(t, err)
|
|
|
|
}
|