agent/consul/fsm,state: tests for CA root related changes

This commit is contained in:
Mitchell Hashimoto 2018-03-21 11:20:17 -07:00
parent a8510f8224
commit 17d6b437d2
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
2 changed files with 237 additions and 0 deletions

View File

@ -8,6 +8,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/agent/consul/autopilot" "github.com/hashicorp/consul/agent/consul/autopilot"
"github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/api" "github.com/hashicorp/consul/api"
@ -1217,3 +1218,35 @@ func TestFSM_Intention_CRUD(t *testing.T) {
assert.Nil(actual) assert.Nil(actual)
} }
} }
func TestFSM_CARoots(t *testing.T) {
t.Parallel()
assert := assert.New(t)
fsm, err := New(nil, os.Stderr)
assert.Nil(err)
// Roots
ca1 := connect.TestCA(t, nil)
ca2 := connect.TestCA(t, nil)
ca2.Active = false
// Create a new request.
req := structs.CARequest{
Op: structs.CAOpSet,
Roots: []*structs.CARoot{ca1, ca2},
}
{
buf, err := structs.Encode(structs.ConnectCARequestType, req)
assert.Nil(err)
assert.True(fsm.Apply(makeLog(buf)).(bool))
}
// Verify it's in the state store.
{
_, roots, err := fsm.state.CARoots(nil)
assert.Nil(err)
assert.Len(roots, 2)
}
}

View File

@ -0,0 +1,204 @@
package state
import (
"testing"
"github.com/hashicorp/consul/agent/connect"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/go-memdb"
"github.com/stretchr/testify/assert"
)
func TestStore_CARootSetList(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Call list to populate the watch set
ws := memdb.NewWatchSet()
_, _, err := s.CARoots(ws)
assert.Nil(err)
// Build a valid value
ca1 := connect.TestCA(t, nil)
// Set
ok, err := s.CARootSetCAS(1, 0, []*structs.CARoot{ca1})
assert.Nil(err)
assert.True(ok)
// Make sure the index got updated.
assert.Equal(s.maxIndex(caRootTableName), uint64(1))
assert.True(watchFired(ws), "watch fired")
// Read it back out and verify it.
expected := *ca1
expected.RaftIndex = structs.RaftIndex{
CreateIndex: 1,
ModifyIndex: 1,
}
ws = memdb.NewWatchSet()
_, roots, err := s.CARoots(ws)
assert.Nil(err)
assert.Len(roots, 1)
actual := roots[0]
assert.Equal(&expected, actual)
}
func TestStore_CARootSet_emptyID(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Call list to populate the watch set
ws := memdb.NewWatchSet()
_, _, err := s.CARoots(ws)
assert.Nil(err)
// Build a valid value
ca1 := connect.TestCA(t, nil)
ca1.ID = ""
// Set
ok, err := s.CARootSetCAS(1, 0, []*structs.CARoot{ca1})
assert.NotNil(err)
assert.Contains(err.Error(), ErrMissingCARootID.Error())
assert.False(ok)
// Make sure the index got updated.
assert.Equal(s.maxIndex(caRootTableName), uint64(0))
assert.False(watchFired(ws), "watch fired")
// Read it back out and verify it.
ws = memdb.NewWatchSet()
_, roots, err := s.CARoots(ws)
assert.Nil(err)
assert.Len(roots, 0)
}
func TestStore_CARootActive_valid(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Build a valid value
ca1 := connect.TestCA(t, nil)
ca1.Active = false
ca2 := connect.TestCA(t, nil)
ca3 := connect.TestCA(t, nil)
ca3.Active = false
// Set
ok, err := s.CARootSetCAS(1, 0, []*structs.CARoot{ca1, ca2, ca3})
assert.Nil(err)
assert.True(ok)
// Query
ws := memdb.NewWatchSet()
idx, res, err := s.CARootActive(ws)
assert.Equal(idx, uint64(1))
assert.Nil(err)
assert.NotNil(res)
assert.Equal(ca2.ID, res.ID)
}
// Test that querying the active CA returns the correct value.
func TestStore_CARootActive_none(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Querying with no results returns nil.
ws := memdb.NewWatchSet()
idx, res, err := s.CARootActive(ws)
assert.Equal(idx, uint64(0))
assert.Nil(res)
assert.Nil(err)
}
/*
func TestStore_Intention_Snapshot_Restore(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Create some intentions.
ixns := structs.Intentions{
&structs.Intention{
DestinationName: "foo",
},
&structs.Intention{
DestinationName: "bar",
},
&structs.Intention{
DestinationName: "baz",
},
}
// Force the sort order of the UUIDs before we create them so the
// order is deterministic.
id := testUUID()
ixns[0].ID = "a" + id[1:]
ixns[1].ID = "b" + id[1:]
ixns[2].ID = "c" + id[1:]
// Now create
for i, ixn := range ixns {
assert.Nil(s.IntentionSet(uint64(4+i), ixn))
}
// Snapshot the queries.
snap := s.Snapshot()
defer snap.Close()
// Alter the real state store.
assert.Nil(s.IntentionDelete(7, ixns[0].ID))
// Verify the snapshot.
assert.Equal(snap.LastIndex(), uint64(6))
expected := structs.Intentions{
&structs.Intention{
ID: ixns[0].ID,
DestinationName: "foo",
Meta: map[string]string{},
RaftIndex: structs.RaftIndex{
CreateIndex: 4,
ModifyIndex: 4,
},
},
&structs.Intention{
ID: ixns[1].ID,
DestinationName: "bar",
Meta: map[string]string{},
RaftIndex: structs.RaftIndex{
CreateIndex: 5,
ModifyIndex: 5,
},
},
&structs.Intention{
ID: ixns[2].ID,
DestinationName: "baz",
Meta: map[string]string{},
RaftIndex: structs.RaftIndex{
CreateIndex: 6,
ModifyIndex: 6,
},
},
}
dump, err := snap.Intentions()
assert.Nil(err)
assert.Equal(expected, dump)
// Restore the values into a new state store.
func() {
s := testStateStore(t)
restore := s.Restore()
for _, ixn := range dump {
assert.Nil(restore.Intention(ixn))
}
restore.Commit()
// Read the restored values back out and verify that they match.
idx, actual, err := s.Intentions(nil)
assert.Nil(err)
assert.Equal(idx, uint64(6))
assert.Equal(expected, actual)
}()
}
*/