mirror of https://github.com/hashicorp/consul
249 lines
8.3 KiB
Go
249 lines
8.3 KiB
Go
package token
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestStore_RegularTokens(t *testing.T) {
|
|
type tokens struct {
|
|
userSource TokenSource
|
|
user string
|
|
agent string
|
|
agentSource TokenSource
|
|
master string
|
|
masterSource TokenSource
|
|
repl string
|
|
replSource TokenSource
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
set tokens
|
|
raw tokens
|
|
effective tokens
|
|
}{
|
|
{
|
|
name: "set user - config",
|
|
set: tokens{user: "U", userSource: TokenSourceConfig},
|
|
raw: tokens{user: "U", userSource: TokenSourceConfig},
|
|
effective: tokens{user: "U", agent: "U"},
|
|
},
|
|
{
|
|
name: "set user - api",
|
|
set: tokens{user: "U", userSource: TokenSourceAPI},
|
|
raw: tokens{user: "U", userSource: TokenSourceAPI},
|
|
effective: tokens{user: "U", agent: "U"},
|
|
},
|
|
{
|
|
name: "set agent - config",
|
|
set: tokens{agent: "A", agentSource: TokenSourceConfig},
|
|
raw: tokens{agent: "A", agentSource: TokenSourceConfig},
|
|
effective: tokens{agent: "A"},
|
|
},
|
|
{
|
|
name: "set agent - api",
|
|
set: tokens{agent: "A", agentSource: TokenSourceAPI},
|
|
raw: tokens{agent: "A", agentSource: TokenSourceAPI},
|
|
effective: tokens{agent: "A"},
|
|
},
|
|
{
|
|
name: "set user and agent",
|
|
set: tokens{agent: "A", user: "U"},
|
|
raw: tokens{agent: "A", user: "U"},
|
|
effective: tokens{agent: "A", user: "U"},
|
|
},
|
|
{
|
|
name: "set repl - config",
|
|
set: tokens{repl: "R", replSource: TokenSourceConfig},
|
|
raw: tokens{repl: "R", replSource: TokenSourceConfig},
|
|
effective: tokens{repl: "R"},
|
|
},
|
|
{
|
|
name: "set repl - api",
|
|
set: tokens{repl: "R", replSource: TokenSourceAPI},
|
|
raw: tokens{repl: "R", replSource: TokenSourceAPI},
|
|
effective: tokens{repl: "R"},
|
|
},
|
|
{
|
|
name: "set master - config",
|
|
set: tokens{master: "M", masterSource: TokenSourceConfig},
|
|
raw: tokens{master: "M", masterSource: TokenSourceConfig},
|
|
effective: tokens{master: "M"},
|
|
},
|
|
{
|
|
name: "set master - api",
|
|
set: tokens{master: "M", masterSource: TokenSourceAPI},
|
|
raw: tokens{master: "M", masterSource: TokenSourceAPI},
|
|
effective: tokens{master: "M"},
|
|
},
|
|
{
|
|
name: "set all",
|
|
set: tokens{user: "U", agent: "A", repl: "R", master: "M"},
|
|
raw: tokens{user: "U", agent: "A", repl: "R", master: "M"},
|
|
effective: tokens{user: "U", agent: "A", repl: "R", master: "M"},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
s := new(Store)
|
|
if tt.set.user != "" {
|
|
require.True(t, s.UpdateUserToken(tt.set.user, tt.set.userSource))
|
|
}
|
|
|
|
if tt.set.agent != "" {
|
|
require.True(t, s.UpdateAgentToken(tt.set.agent, tt.set.agentSource))
|
|
}
|
|
|
|
if tt.set.repl != "" {
|
|
require.True(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
|
}
|
|
|
|
if tt.set.master != "" {
|
|
require.True(t, s.UpdateAgentMasterToken(tt.set.master, tt.set.masterSource))
|
|
}
|
|
|
|
// If they don't change then they return false.
|
|
require.False(t, s.UpdateUserToken(tt.set.user, tt.set.userSource))
|
|
require.False(t, s.UpdateAgentToken(tt.set.agent, tt.set.agentSource))
|
|
require.False(t, s.UpdateReplicationToken(tt.set.repl, tt.set.replSource))
|
|
require.False(t, s.UpdateAgentMasterToken(tt.set.master, tt.set.masterSource))
|
|
|
|
require.Equal(t, tt.effective.user, s.UserToken())
|
|
require.Equal(t, tt.effective.agent, s.AgentToken())
|
|
require.Equal(t, tt.effective.master, s.AgentMasterToken())
|
|
require.Equal(t, tt.effective.repl, s.ReplicationToken())
|
|
|
|
tok, src := s.UserTokenAndSource()
|
|
require.Equal(t, tt.raw.user, tok)
|
|
require.Equal(t, tt.raw.userSource, src)
|
|
|
|
tok, src = s.AgentTokenAndSource()
|
|
require.Equal(t, tt.raw.agent, tok)
|
|
require.Equal(t, tt.raw.agentSource, src)
|
|
|
|
tok, src = s.AgentMasterTokenAndSource()
|
|
require.Equal(t, tt.raw.master, tok)
|
|
require.Equal(t, tt.raw.masterSource, src)
|
|
|
|
tok, src = s.ReplicationTokenAndSource()
|
|
require.Equal(t, tt.raw.repl, tok)
|
|
require.Equal(t, tt.raw.replSource, src)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStore_AgentMasterToken(t *testing.T) {
|
|
s := new(Store)
|
|
|
|
verify := func(want bool, toks ...string) {
|
|
for _, tok := range toks {
|
|
require.Equal(t, want, s.IsAgentMasterToken(tok))
|
|
}
|
|
}
|
|
|
|
verify(false, "", "nope")
|
|
|
|
s.UpdateAgentMasterToken("master", TokenSourceConfig)
|
|
verify(true, "master")
|
|
verify(false, "", "nope")
|
|
|
|
s.UpdateAgentMasterToken("another", TokenSourceConfig)
|
|
verify(true, "another")
|
|
verify(false, "", "nope", "master")
|
|
|
|
s.UpdateAgentMasterToken("", TokenSourceConfig)
|
|
verify(false, "", "nope", "master", "another")
|
|
}
|
|
|
|
func TestStore_Notify(t *testing.T) {
|
|
s := new(Store)
|
|
|
|
newNotification := func(t *testing.T, s *Store, kind TokenKind) Notifier {
|
|
n := s.Notify(kind)
|
|
require.NotNil(t, n.Ch)
|
|
return n
|
|
}
|
|
|
|
requireNotNotified := func(t *testing.T, ch <-chan struct{}) {
|
|
require.Empty(t, ch)
|
|
}
|
|
|
|
requireNotifiedOnce := func(t *testing.T, ch <-chan struct{}) {
|
|
require.Len(t, ch, 1)
|
|
// drain the channel
|
|
<-ch
|
|
// just to be safe
|
|
require.Empty(t, ch)
|
|
}
|
|
|
|
agentNotifier := newNotification(t, s, TokenKindAgent)
|
|
userNotifier := newNotification(t, s, TokenKindUser)
|
|
agentMasterNotifier := newNotification(t, s, TokenKindAgentMaster)
|
|
replicationNotifier := newNotification(t, s, TokenKindReplication)
|
|
replicationNotifier2 := newNotification(t, s, TokenKindReplication)
|
|
|
|
// perform an update of the user token
|
|
require.True(t, s.UpdateUserToken("edcae2a2-3b51-4864-b412-c7a568f49cb1", TokenSourceConfig))
|
|
// do it again to ensure it doesn't block even though nothing has read from the 1 buffered chan yet
|
|
require.True(t, s.UpdateUserToken("47788919-f944-476a-bda5-446d64be1df8", TokenSourceAPI))
|
|
|
|
// ensure notifications were sent to the user and all notifiers
|
|
requireNotNotified(t, agentNotifier.Ch)
|
|
requireNotifiedOnce(t, userNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier.Ch)
|
|
requireNotNotified(t, agentMasterNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier2.Ch)
|
|
|
|
// now update the agent token which should send notificaitons to the agent and all notifier
|
|
require.True(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
|
|
|
requireNotifiedOnce(t, agentNotifier.Ch)
|
|
requireNotNotified(t, userNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier.Ch)
|
|
requireNotNotified(t, agentMasterNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier2.Ch)
|
|
|
|
// now update the agent master token which should send notificaitons to the agent master and all notifier
|
|
require.True(t, s.UpdateAgentMasterToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
|
|
|
requireNotNotified(t, agentNotifier.Ch)
|
|
requireNotNotified(t, userNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier.Ch)
|
|
requireNotifiedOnce(t, agentMasterNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier2.Ch)
|
|
|
|
// now update the replication token which should send notificaitons to the replication and all notifier
|
|
require.True(t, s.UpdateReplicationToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
|
|
|
requireNotNotified(t, agentNotifier.Ch)
|
|
requireNotNotified(t, userNotifier.Ch)
|
|
requireNotifiedOnce(t, replicationNotifier.Ch)
|
|
requireNotNotified(t, agentMasterNotifier.Ch)
|
|
requireNotifiedOnce(t, replicationNotifier2.Ch)
|
|
|
|
s.StopNotify(replicationNotifier2)
|
|
|
|
// now update the replication token which should send notificaitons to the replication and all notifier
|
|
require.True(t, s.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", TokenSourceAPI))
|
|
|
|
requireNotNotified(t, agentNotifier.Ch)
|
|
requireNotNotified(t, userNotifier.Ch)
|
|
requireNotifiedOnce(t, replicationNotifier.Ch)
|
|
requireNotNotified(t, agentMasterNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier2.Ch)
|
|
|
|
// request updates but that are not changes
|
|
require.False(t, s.UpdateAgentToken("5d748ec2-d536-461f-8e2a-1f7eae98d559", TokenSourceAPI))
|
|
require.False(t, s.UpdateAgentMasterToken("789badc8-f850-43e1-8742-9b9f484957cc", TokenSourceAPI))
|
|
require.False(t, s.UpdateUserToken("47788919-f944-476a-bda5-446d64be1df8", TokenSourceAPI))
|
|
require.False(t, s.UpdateReplicationToken("eb0b56b9-fa65-4ae1-902a-c64457c62ac6", TokenSourceAPI))
|
|
|
|
// ensure that notifications were not sent
|
|
requireNotNotified(t, agentNotifier.Ch)
|
|
requireNotNotified(t, userNotifier.Ch)
|
|
requireNotNotified(t, replicationNotifier.Ch)
|
|
requireNotNotified(t, agentMasterNotifier.Ch)
|
|
}
|