agent: convert all intention tests to testify/assert

This commit is contained in:
Mitchell Hashimoto 2018-03-06 10:35:20 -08:00
parent 454ef7d106
commit 0719ff6905
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
6 changed files with 218 additions and 491 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/serf/coordinate"
"github.com/pascaldekloe/goe/verify"
"github.com/stretchr/testify/assert"
)
func generateUUID() (ret string) {
@ -1152,10 +1153,9 @@ func TestFSM_Autopilot(t *testing.T) {
func TestFSM_Intention_CRUD(t *testing.T) {
t.Parallel()
assert := assert.New(t)
fsm, err := New(nil, os.Stderr)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(err)
// Create a new intention.
ixn := structs.IntentionRequest{
@ -1167,28 +1167,19 @@ func TestFSM_Intention_CRUD(t *testing.T) {
{
buf, err := structs.Encode(structs.IntentionRequestType, ixn)
if err != nil {
t.Fatalf("err: %v", err)
}
resp := fsm.Apply(makeLog(buf))
if resp != nil {
t.Fatalf("resp: %v", resp)
}
assert.Nil(err)
assert.Nil(fsm.Apply(makeLog(buf)))
}
// Verify it's in the state store.
{
_, actual, err := fsm.state.IntentionGet(nil, ixn.Intention.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(err)
actual.CreateIndex, actual.ModifyIndex = 0, 0
actual.CreatedAt = ixn.Intention.CreatedAt
actual.UpdatedAt = ixn.Intention.UpdatedAt
if !reflect.DeepEqual(actual, ixn.Intention) {
t.Fatalf("bad: %v", actual)
}
assert.Equal(ixn.Intention, actual)
}
// Make an update
@ -1196,52 +1187,33 @@ func TestFSM_Intention_CRUD(t *testing.T) {
ixn.Intention.SourceName = "api"
{
buf, err := structs.Encode(structs.IntentionRequestType, ixn)
if err != nil {
t.Fatalf("err: %v", err)
}
resp := fsm.Apply(makeLog(buf))
if resp != nil {
t.Fatalf("resp: %v", resp)
}
assert.Nil(err)
assert.Nil(fsm.Apply(makeLog(buf)))
}
// Verify the update.
{
_, actual, err := fsm.state.IntentionGet(nil, ixn.Intention.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(err)
actual.CreateIndex, actual.ModifyIndex = 0, 0
actual.CreatedAt = ixn.Intention.CreatedAt
actual.UpdatedAt = ixn.Intention.UpdatedAt
if !reflect.DeepEqual(actual, ixn.Intention) {
t.Fatalf("bad: %v", actual)
}
assert.Equal(ixn.Intention, actual)
}
// Delete
ixn.Op = structs.IntentionOpDelete
{
buf, err := structs.Encode(structs.IntentionRequestType, ixn)
if err != nil {
t.Fatalf("err: %v", err)
}
resp := fsm.Apply(makeLog(buf))
if resp != nil {
t.Fatalf("resp: %v", resp)
}
assert.Nil(err)
assert.Nil(fsm.Apply(makeLog(buf)))
}
// Make sure it's gone.
{
_, actual, err := fsm.state.IntentionGet(nil, ixn.Intention.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if actual != nil {
t.Fatalf("bad: %v", actual)
}
assert.Nil(err)
assert.Nil(actual)
}
}

View File

@ -13,10 +13,13 @@ import (
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/lib"
"github.com/pascaldekloe/goe/verify"
"github.com/stretchr/testify/assert"
)
func TestFSM_SnapshotRestore_OSS(t *testing.T) {
t.Parallel()
assert := assert.New(t)
fsm, err := New(nil, os.Stderr)
if err != nil {
t.Fatalf("err: %v", err)
@ -105,9 +108,7 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) {
CreateIndex: 14,
ModifyIndex: 14,
}
if err := fsm.state.IntentionSet(14, ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(fsm.state.IntentionSet(14, ixn))
// Snapshot
snap, err := fsm.Snapshot()
@ -273,15 +274,9 @@ func TestFSM_SnapshotRestore_OSS(t *testing.T) {
// Verify intentions are restored.
_, ixns, err := fsm2.state.Intentions(nil)
if err != nil {
t.Fatalf("err: %s", err)
}
if len(ixns) != 1 {
t.Fatalf("bad: %#v", ixns)
}
if !reflect.DeepEqual(ixns[0], ixn) {
t.Fatalf("bad: %#v", ixns[0])
}
assert.Nil(err)
assert.Len(ixns, 1)
assert.Equal(ixn, ixns[0])
// Snapshot
snap, err = fsm2.Snapshot()

View File

@ -2,19 +2,20 @@ package consul
import (
"os"
"reflect"
"strings"
"testing"
"time"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/testrpc"
"github.com/hashicorp/net-rpc-msgpackrpc"
"github.com/stretchr/testify/assert"
)
// Test basic creation
func TestIntentionApply_new(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -43,12 +44,8 @@ func TestIntentionApply_new(t *testing.T) {
now := time.Now()
// Create
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if reply == "" {
t.Fatal("reply should be non-empty")
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
assert.NotEmpty(reply)
// Read
ixn.Intention.ID = reply
@ -58,45 +55,25 @@ func TestIntentionApply_new(t *testing.T) {
IntentionID: ixn.Intention.ID,
}
var resp structs.IndexedIntentions
if err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
if resp.Index != actual.ModifyIndex {
t.Fatalf("bad index: %d", resp.Index)
}
// Test CreatedAt
{
timeDiff := actual.CreatedAt.Sub(now)
if timeDiff < 0 || timeDiff > 5*time.Second {
t.Fatalf("should set created at: %s", actual.CreatedAt)
}
}
// Test UpdatedAt
{
timeDiff := actual.UpdatedAt.Sub(now)
if timeDiff < 0 || timeDiff > 5*time.Second {
t.Fatalf("should set updated at: %s", actual.CreatedAt)
}
}
assert.Equal(resp.Index, actual.ModifyIndex)
assert.WithinDuration(now, actual.CreatedAt, 5*time.Second)
assert.WithinDuration(now, actual.UpdatedAt, 5*time.Second)
actual.CreateIndex, actual.ModifyIndex = 0, 0
actual.CreatedAt = ixn.Intention.CreatedAt
actual.UpdatedAt = ixn.Intention.UpdatedAt
if !reflect.DeepEqual(actual, ixn.Intention) {
t.Fatalf("bad:\n\n%#v\n\n%#v", actual, ixn.Intention)
}
assert.Equal(ixn.Intention, actual)
}
}
// Test the source type defaults
func TestIntentionApply_defaultSourceType(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -120,12 +97,8 @@ func TestIntentionApply_defaultSourceType(t *testing.T) {
var reply string
// Create
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if reply == "" {
t.Fatal("reply should be non-empty")
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
assert.NotEmpty(reply)
// Read
ixn.Intention.ID = reply
@ -135,23 +108,18 @@ func TestIntentionApply_defaultSourceType(t *testing.T) {
IntentionID: ixn.Intention.ID,
}
var resp structs.IndexedIntentions
if err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
if actual.SourceType != structs.IntentionSourceConsul {
t.Fatalf("bad:\n\n%#v\n\n%#v", actual, ixn.Intention)
}
assert.Equal(structs.IntentionSourceConsul, actual.SourceType)
}
}
// Shouldn't be able to create with an ID set
func TestIntentionApply_createWithID(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -173,14 +141,15 @@ func TestIntentionApply_createWithID(t *testing.T) {
// Create
err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
if err == nil || !strings.Contains(err.Error(), "ID must be empty") {
t.Fatalf("bad: %v", err)
}
assert.NotNil(err)
assert.Contains(err, "ID must be empty")
}
// Test basic updating
func TestIntentionApply_updateGood(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -206,12 +175,8 @@ func TestIntentionApply_updateGood(t *testing.T) {
var reply string
// Create
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if reply == "" {
t.Fatal("reply should be non-empty")
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
assert.NotEmpty(reply)
// Read CreatedAt
var createdAt time.Time
@ -222,12 +187,8 @@ func TestIntentionApply_updateGood(t *testing.T) {
IntentionID: ixn.Intention.ID,
}
var resp structs.IndexedIntentions
if err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
createdAt = actual.CreatedAt
}
@ -239,9 +200,7 @@ func TestIntentionApply_updateGood(t *testing.T) {
ixn.Op = structs.IntentionOpUpdate
ixn.Intention.ID = reply
ixn.Intention.SourceName = "bar"
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
// Read
ixn.Intention.ID = reply
@ -251,39 +210,24 @@ func TestIntentionApply_updateGood(t *testing.T) {
IntentionID: ixn.Intention.ID,
}
var resp structs.IndexedIntentions
if err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
// Test CreatedAt
if !actual.CreatedAt.Equal(createdAt) {
t.Fatalf("should not modify created at: %s", actual.CreatedAt)
}
// Test UpdatedAt
{
timeDiff := actual.UpdatedAt.Sub(createdAt)
if timeDiff <= 0 || timeDiff > 5*time.Second {
t.Fatalf("should set updated at: %s", actual.CreatedAt)
}
}
assert.Equal(createdAt, actual.CreatedAt)
assert.WithinDuration(time.Now(), actual.UpdatedAt, 5*time.Second)
actual.CreateIndex, actual.ModifyIndex = 0, 0
actual.CreatedAt = ixn.Intention.CreatedAt
actual.UpdatedAt = ixn.Intention.UpdatedAt
if !reflect.DeepEqual(actual, ixn.Intention) {
t.Fatalf("bad: %v", actual)
}
assert.Equal(ixn.Intention, actual)
}
}
// Shouldn't be able to update a non-existent intention
func TestIntentionApply_updateNonExist(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -305,14 +249,15 @@ func TestIntentionApply_updateNonExist(t *testing.T) {
// Create
err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
if err == nil || !strings.Contains(err.Error(), "Cannot modify non-existent intention") {
t.Fatalf("bad: %v", err)
}
assert.NotNil(err)
assert.Contains(err, "Cannot modify non-existent intention")
}
// Test basic deleting
func TestIntentionApply_deleteGood(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -336,19 +281,13 @@ func TestIntentionApply_deleteGood(t *testing.T) {
var reply string
// Create
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
if reply == "" {
t.Fatal("reply should be non-empty")
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
assert.NotEmpty(reply)
// Delete
ixn.Op = structs.IntentionOpDelete
ixn.Intention.ID = reply
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
// Read
ixn.Intention.ID = reply
@ -359,14 +298,15 @@ func TestIntentionApply_deleteGood(t *testing.T) {
}
var resp structs.IndexedIntentions
err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp)
if err == nil || !strings.Contains(err.Error(), ErrIntentionNotFound.Error()) {
t.Fatalf("err: %v", err)
}
assert.NotNil(err)
assert.Contains(err, ErrIntentionNotFound.Error())
}
}
func TestIntentionList(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -381,16 +321,9 @@ func TestIntentionList(t *testing.T) {
Datacenter: "dc1",
}
var resp structs.IndexedIntentions
if err := msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if resp.Intentions == nil {
t.Fatal("should not be nil")
}
if len(resp.Intentions) != 0 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.List", req, &resp))
assert.NotNil(resp.Intentions)
assert.Len(resp.Intentions, 0)
}
}
@ -398,6 +331,8 @@ func TestIntentionList(t *testing.T) {
// is tested in the agent/consul/state package.
func TestIntentionMatch_good(t *testing.T) {
t.Parallel()
assert := assert.New(t)
dir1, s1 := testServer(t)
defer os.RemoveAll(dir1)
defer s1.Shutdown()
@ -432,9 +367,7 @@ func TestIntentionMatch_good(t *testing.T) {
// Create
var reply string
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply))
}
}
@ -452,21 +385,13 @@ func TestIntentionMatch_good(t *testing.T) {
},
}
var resp structs.IndexedIntentionMatches
if err := msgpackrpc.CallWithCodec(codec, "Intention.Match", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Matches) != 1 {
t.Fatalf("bad: %#v", resp.Matches)
}
assert.Nil(msgpackrpc.CallWithCodec(codec, "Intention.Match", req, &resp))
assert.Len(resp.Matches, 1)
expected := [][]string{{"foo", "bar"}, {"foo", "*"}, {"*", "*"}}
var actual [][]string
for _, ixn := range resp.Matches[0] {
actual = append(actual, []string{ixn.DestinationNS, ixn.DestinationName})
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad (got, wanted):\n\n%#v\n\n%#v", actual, expected)
}
assert.Equal(expected, actual)
}

View File

@ -1,34 +1,34 @@
package state
import (
"reflect"
"testing"
"time"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/go-memdb"
"github.com/stretchr/testify/assert"
)
func TestStore_IntentionGet_none(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Querying with no results returns nil.
ws := memdb.NewWatchSet()
idx, res, err := s.IntentionGet(ws, testUUID())
if idx != 0 || res != nil || err != nil {
t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
}
assert.Equal(idx, uint64(0))
assert.Nil(res)
assert.Nil(err)
}
func TestStore_IntentionSetGet_basic(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Call Get to populate the watch set
ws := memdb.NewWatchSet()
_, _, err := s.IntentionGet(ws, testUUID())
if err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(err)
// Build a valid intention
ixn := &structs.Intention{
@ -37,17 +37,11 @@ func TestStore_IntentionSetGet_basic(t *testing.T) {
}
// Inserting a with empty ID is disallowed.
if err := s.IntentionSet(1, ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(1, ixn))
// Make sure the index got updated.
if idx := s.maxIndex(intentionsTableName); idx != 1 {
t.Fatalf("bad index: %d", idx)
}
if !watchFired(ws) {
t.Fatalf("bad")
}
assert.Equal(s.maxIndex(intentionsTableName), uint64(1))
assert.True(watchFired(ws), "watch fired")
// Read it back out and verify it.
expected := &structs.Intention{
@ -61,70 +55,48 @@ func TestStore_IntentionSetGet_basic(t *testing.T) {
ws = memdb.NewWatchSet()
idx, actual, err := s.IntentionGet(ws, ixn.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != expected.CreateIndex {
t.Fatalf("bad index: %d", idx)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %v", actual)
}
assert.Nil(err)
assert.Equal(expected.CreateIndex, idx)
assert.Equal(expected, actual)
// Change a value and test updating
ixn.SourceNS = "foo"
if err := s.IntentionSet(2, ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(2, ixn))
// Make sure the index got updated.
if idx := s.maxIndex(intentionsTableName); idx != 2 {
t.Fatalf("bad index: %d", idx)
}
if !watchFired(ws) {
t.Fatalf("bad")
}
assert.Equal(s.maxIndex(intentionsTableName), uint64(2))
assert.True(watchFired(ws), "watch fired")
// Read it back and verify the data was updated
expected.SourceNS = ixn.SourceNS
expected.ModifyIndex = 2
ws = memdb.NewWatchSet()
idx, actual, err = s.IntentionGet(ws, ixn.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != expected.ModifyIndex {
t.Fatalf("bad index: %d", idx)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
assert.Nil(err)
assert.Equal(expected.ModifyIndex, idx)
assert.Equal(expected, actual)
}
func TestStore_IntentionSet_emptyId(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
ws := memdb.NewWatchSet()
_, _, err := s.IntentionGet(ws, testUUID())
if err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(err)
// Inserting a with empty ID is disallowed.
if err := s.IntentionSet(1, &structs.Intention{}); err == nil {
t.Fatalf("expected %#v, got: %#v", ErrMissingIntentionID, err)
}
err = s.IntentionSet(1, &structs.Intention{})
assert.NotNil(err)
assert.Contains(err.Error(), ErrMissingIntentionID.Error())
// Index is not updated if nothing is saved.
if idx := s.maxIndex(intentionsTableName); idx != 0 {
t.Fatalf("bad index: %d", idx)
}
if watchFired(ws) {
t.Fatalf("bad")
}
assert.Equal(s.maxIndex(intentionsTableName), uint64(0))
assert.False(watchFired(ws), "watch fired")
}
func TestStore_IntentionSet_updateCreatedAt(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Build a valid intention
@ -135,28 +107,21 @@ func TestStore_IntentionSet_updateCreatedAt(t *testing.T) {
}
// Insert
if err := s.IntentionSet(1, &ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(1, &ixn))
// Change a value and test updating
ixnUpdate := ixn
ixnUpdate.CreatedAt = now.Add(10 * time.Second)
if err := s.IntentionSet(2, &ixnUpdate); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(2, &ixnUpdate))
// Read it back and verify
_, actual, err := s.IntentionGet(nil, ixn.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if !actual.CreatedAt.Equal(now) {
t.Fatalf("bad: %#v", actual)
}
assert.Nil(err)
assert.Equal(now, actual.CreatedAt)
}
func TestStore_IntentionSet_metaNil(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Build a valid intention
@ -165,21 +130,16 @@ func TestStore_IntentionSet_metaNil(t *testing.T) {
}
// Insert
if err := s.IntentionSet(1, &ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(1, &ixn))
// Read it back and verify
_, actual, err := s.IntentionGet(nil, ixn.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if actual.Meta == nil {
t.Fatal("meta should be non-nil")
}
assert.Nil(err)
assert.NotNil(actual.Meta)
}
func TestStore_IntentionSet_metaSet(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Build a valid intention
@ -189,79 +149,55 @@ func TestStore_IntentionSet_metaSet(t *testing.T) {
}
// Insert
if err := s.IntentionSet(1, &ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(1, &ixn))
// Read it back and verify
_, actual, err := s.IntentionGet(nil, ixn.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(actual.Meta, ixn.Meta) {
t.Fatalf("bad: %#v", actual)
}
assert.Nil(err)
assert.Equal(ixn.Meta, actual.Meta)
}
func TestStore_IntentionDelete(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Call Get to populate the watch set
ws := memdb.NewWatchSet()
_, _, err := s.IntentionGet(ws, testUUID())
if err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(err)
// Create
ixn := &structs.Intention{ID: testUUID()}
if err := s.IntentionSet(1, ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(1, ixn))
// Make sure the index got updated.
if idx := s.maxIndex(intentionsTableName); idx != 1 {
t.Fatalf("bad index: %d", idx)
}
if !watchFired(ws) {
t.Fatalf("bad")
}
assert.Equal(s.maxIndex(intentionsTableName), uint64(1))
assert.True(watchFired(ws), "watch fired")
// Delete
if err := s.IntentionDelete(2, ixn.ID); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionDelete(2, ixn.ID))
// Make sure the index got updated.
if idx := s.maxIndex(intentionsTableName); idx != 2 {
t.Fatalf("bad index: %d", idx)
}
if !watchFired(ws) {
t.Fatalf("bad")
}
assert.Equal(s.maxIndex(intentionsTableName), uint64(2))
assert.True(watchFired(ws), "watch fired")
// Sanity check to make sure it's not there.
idx, actual, err := s.IntentionGet(nil, ixn.ID)
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 2 {
t.Fatalf("bad index: %d", idx)
}
if actual != nil {
t.Fatalf("bad: %v", actual)
}
assert.Nil(err)
assert.Equal(idx, uint64(2))
assert.Nil(actual)
}
func TestStore_IntentionsList(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Querying with no results returns nil.
ws := memdb.NewWatchSet()
idx, res, err := s.Intentions(ws)
if idx != 0 || res != nil || err != nil {
t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err)
}
assert.Nil(err)
assert.Nil(res)
assert.Equal(idx, uint64(0))
// Create some intentions
ixns := structs.Intentions{
@ -281,13 +217,9 @@ func TestStore_IntentionsList(t *testing.T) {
// Create
for i, ixn := range ixns {
if err := s.IntentionSet(uint64(1+i), ixn); err != nil {
t.Fatalf("err: %s", err)
}
}
if !watchFired(ws) {
t.Fatalf("bad")
assert.Nil(s.IntentionSet(uint64(1+i), ixn))
}
assert.True(watchFired(ws), "watch fired")
// Read it back and verify.
expected := structs.Intentions{
@ -309,15 +241,9 @@ func TestStore_IntentionsList(t *testing.T) {
},
}
idx, actual, err := s.Intentions(nil)
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 2 {
t.Fatalf("bad index: %d", idx)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %v", actual)
}
assert.Nil(err)
assert.Equal(idx, uint64(2))
assert.Equal(expected, actual)
}
// Test the matrix of match logic.
@ -386,6 +312,7 @@ func TestStore_IntentionMatch_table(t *testing.T) {
// test both cases.
testRunner := func(t *testing.T, tc testCase, typ structs.IntentionMatchType) {
// Insert the set
assert := assert.New(t)
s := testStateStore(t)
var idx uint64 = 1
for _, v := range tc.Insert {
@ -399,10 +326,7 @@ func TestStore_IntentionMatch_table(t *testing.T) {
ixn.SourceName = v[1]
}
err := s.IntentionSet(idx, ixn)
if err != nil {
t.Fatalf("error inserting: %s", err)
}
assert.Nil(s.IntentionSet(idx, ixn))
idx++
}
@ -418,14 +342,10 @@ func TestStore_IntentionMatch_table(t *testing.T) {
// Match
_, matches, err := s.IntentionMatch(nil, args)
if err != nil {
t.Fatalf("error matching: %s", err)
}
assert.Nil(err)
// Should have equal lengths
if len(matches) != len(tc.Expected) {
t.Fatalf("bad (got, wanted):\n\n%#v\n\n%#v", tc.Expected, matches)
}
assert.Len(matches, len(tc.Expected))
// Verify matches
for i, expected := range tc.Expected {
@ -439,9 +359,7 @@ func TestStore_IntentionMatch_table(t *testing.T) {
}
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad (got, wanted):\n\n%#v\n\n%#v", actual, expected)
}
assert.Equal(expected, actual)
}
}
@ -457,6 +375,7 @@ func TestStore_IntentionMatch_table(t *testing.T) {
}
func TestStore_Intention_Snapshot_Restore(t *testing.T) {
assert := assert.New(t)
s := testStateStore(t)
// Create some intentions.
@ -481,9 +400,7 @@ func TestStore_Intention_Snapshot_Restore(t *testing.T) {
// Now create
for i, ixn := range ixns {
if err := s.IntentionSet(uint64(4+i), ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionSet(uint64(4+i), ixn))
}
// Snapshot the queries.
@ -491,14 +408,10 @@ func TestStore_Intention_Snapshot_Restore(t *testing.T) {
defer snap.Close()
// Alter the real state store.
if err := s.IntentionDelete(7, ixns[0].ID); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(s.IntentionDelete(7, ixns[0].ID))
// Verify the snapshot.
if idx := snap.LastIndex(); idx != 6 {
t.Fatalf("bad index: %d", idx)
}
assert.Equal(snap.LastIndex(), uint64(6))
expected := structs.Intentions{
&structs.Intention{
ID: ixns[0].ID,
@ -529,34 +442,22 @@ func TestStore_Intention_Snapshot_Restore(t *testing.T) {
},
}
dump, err := snap.Intentions()
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(dump, expected) {
t.Fatalf("bad: %#v", dump[0])
}
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 {
if err := restore.Intention(ixn); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(restore.Intention(ixn))
}
restore.Commit()
// Read the restored values back out and verify that they match.
idx, actual, err := s.Intentions(nil)
if err != nil {
t.Fatalf("err: %s", err)
}
if idx != 6 {
t.Fatalf("bad index: %d", idx)
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %v", actual)
}
assert.Nil(err)
assert.Equal(idx, uint64(6))
assert.Equal(expected, actual)
}()
}

View File

@ -4,17 +4,17 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"sort"
"strings"
"testing"
"github.com/hashicorp/consul/agent/structs"
"github.com/stretchr/testify/assert"
)
func TestIntentionsList_empty(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -22,19 +22,17 @@ func TestIntentionsList_empty(t *testing.T) {
req, _ := http.NewRequest("GET", "/v1/connect/intentions", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionList(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(err)
value := obj.(structs.Intentions)
if value == nil || len(value) != 0 {
t.Fatalf("bad: %v", value)
}
assert.NotNil(value)
assert.Len(value, 0)
}
func TestIntentionsList_values(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -48,35 +46,28 @@ func TestIntentionsList_values(t *testing.T) {
req.Intention.SourceName = v
var reply string
if err := a.RPC("Intention.Apply", &req, &reply); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(a.RPC("Intention.Apply", &req, &reply))
}
// Request
req, _ := http.NewRequest("GET", "/v1/connect/intentions", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionList(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(err)
value := obj.(structs.Intentions)
if len(value) != 2 {
t.Fatalf("bad: %v", value)
}
assert.Len(value, 2)
expected := []string{"bar", "foo"}
actual := []string{value[0].SourceName, value[1].SourceName}
sort.Strings(actual)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
assert.Equal(expected, actual)
}
func TestIntentionsMatch_basic(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -102,9 +93,7 @@ func TestIntentionsMatch_basic(t *testing.T) {
// Create
var reply string
if err := a.RPC("Intention.Apply", &ixn, &reply); err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(a.RPC("Intention.Apply", &ixn, &reply))
}
}
@ -113,14 +102,10 @@ func TestIntentionsMatch_basic(t *testing.T) {
"/v1/connect/intentions/match?by=destination&name=foo/bar", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionMatch(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(err)
value := obj.(map[string]structs.Intentions)
if len(value) != 1 {
t.Fatalf("bad: %v", value)
}
assert.Len(value, 1)
var actual [][]string
expected := [][]string{{"foo", "bar"}, {"foo", "*"}, {"*", "*"}}
@ -128,14 +113,13 @@ func TestIntentionsMatch_basic(t *testing.T) {
actual = append(actual, []string{ixn.DestinationNS, ixn.DestinationName})
}
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad (got, wanted):\n\n%#v\n\n%#v", actual, expected)
}
assert.Equal(expected, actual)
}
func TestIntentionsMatch_noBy(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -144,17 +128,15 @@ func TestIntentionsMatch_noBy(t *testing.T) {
"/v1/connect/intentions/match?name=foo/bar", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionMatch(resp, req)
if err == nil || !strings.Contains(err.Error(), "by") {
t.Fatalf("err: %v", err)
}
if obj != nil {
t.Fatal("should have no response")
}
assert.NotNil(err)
assert.Contains(err.Error(), "by")
assert.Nil(obj)
}
func TestIntentionsMatch_byInvalid(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -163,17 +145,15 @@ func TestIntentionsMatch_byInvalid(t *testing.T) {
"/v1/connect/intentions/match?by=datacenter", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionMatch(resp, req)
if err == nil || !strings.Contains(err.Error(), "'by' parameter") {
t.Fatalf("err: %v", err)
}
if obj != nil {
t.Fatal("should have no response")
}
assert.NotNil(err)
assert.Contains(err.Error(), "'by' parameter")
assert.Nil(obj)
}
func TestIntentionsMatch_noName(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -182,17 +162,15 @@ func TestIntentionsMatch_noName(t *testing.T) {
"/v1/connect/intentions/match?by=source", nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionMatch(resp, req)
if err == nil || !strings.Contains(err.Error(), "'name' not set") {
t.Fatalf("err: %v", err)
}
if obj != nil {
t.Fatal("should have no response")
}
assert.NotNil(err)
assert.Contains(err.Error(), "'name' not set")
assert.Nil(obj)
}
func TestIntentionsCreate_good(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -202,14 +180,10 @@ func TestIntentionsCreate_good(t *testing.T) {
req, _ := http.NewRequest("POST", "/v1/connect/intentions", jsonReader(args))
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionCreate(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(err)
value := obj.(intentionCreateResponse)
if value.ID == "" {
t.Fatalf("bad: %v", value)
}
assert.NotEqual("", value.ID)
// Read the value
{
@ -218,22 +192,17 @@ func TestIntentionsCreate_good(t *testing.T) {
IntentionID: value.ID,
}
var resp structs.IndexedIntentions
if err := a.RPC("Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(a.RPC("Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
if actual.SourceName != "foo" {
t.Fatalf("bad: %#v", actual)
}
assert.Equal("foo", actual.SourceName)
}
}
func TestIntentionsSpecificGet_good(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -248,35 +217,28 @@ func TestIntentionsSpecificGet_good(t *testing.T) {
Op: structs.IntentionOpCreate,
Intention: ixn,
}
if err := a.RPC("Intention.Apply", &req, &reply); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(a.RPC("Intention.Apply", &req, &reply))
}
// Get the value
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/connect/intentions/%s", reply), nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionSpecific(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
assert.Nil(err)
value := obj.(*structs.Intention)
if value.ID != reply {
t.Fatalf("bad: %v", value)
}
assert.Equal(reply, value.ID)
ixn.ID = value.ID
ixn.RaftIndex = value.RaftIndex
ixn.CreatedAt, ixn.UpdatedAt = value.CreatedAt, value.UpdatedAt
if !reflect.DeepEqual(value, ixn) {
t.Fatalf("bad (got, want):\n\n%#v\n\n%#v", value, ixn)
}
assert.Equal(ixn, value)
}
func TestIntentionsSpecificUpdate_good(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -291,9 +253,7 @@ func TestIntentionsSpecificUpdate_good(t *testing.T) {
Op: structs.IntentionOpCreate,
Intention: ixn,
}
if err := a.RPC("Intention.Apply", &req, &reply); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(a.RPC("Intention.Apply", &req, &reply))
}
// Update the intention
@ -302,12 +262,8 @@ func TestIntentionsSpecificUpdate_good(t *testing.T) {
req, _ := http.NewRequest("PUT", fmt.Sprintf("/v1/connect/intentions/%s", reply), jsonReader(ixn))
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionSpecific(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
if obj != nil {
t.Fatalf("obj should be nil: %v", err)
}
assert.Nil(err)
assert.Nil(obj)
// Read the value
{
@ -316,22 +272,17 @@ func TestIntentionsSpecificUpdate_good(t *testing.T) {
IntentionID: reply,
}
var resp structs.IndexedIntentions
if err := a.RPC("Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(a.RPC("Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
if actual.SourceName != "bar" {
t.Fatalf("bad: %#v", actual)
}
assert.Equal("bar", actual.SourceName)
}
}
func TestIntentionsSpecificDelete_good(t *testing.T) {
t.Parallel()
assert := assert.New(t)
a := NewTestAgent(t.Name(), "")
defer a.Shutdown()
@ -347,9 +298,7 @@ func TestIntentionsSpecificDelete_good(t *testing.T) {
Op: structs.IntentionOpCreate,
Intention: ixn,
}
if err := a.RPC("Intention.Apply", &req, &reply); err != nil {
t.Fatalf("err: %s", err)
}
assert.Nil(a.RPC("Intention.Apply", &req, &reply))
}
// Sanity check that the intention exists
@ -359,28 +308,18 @@ func TestIntentionsSpecificDelete_good(t *testing.T) {
IntentionID: reply,
}
var resp structs.IndexedIntentions
if err := a.RPC("Intention.Get", req, &resp); err != nil {
t.Fatalf("err: %v", err)
}
if len(resp.Intentions) != 1 {
t.Fatalf("bad: %v", resp)
}
assert.Nil(a.RPC("Intention.Get", req, &resp))
assert.Len(resp.Intentions, 1)
actual := resp.Intentions[0]
if actual.SourceName != "foo" {
t.Fatalf("bad: %#v", actual)
}
assert.Equal("foo", actual.SourceName)
}
// Delete the intention
req, _ := http.NewRequest("DELETE", fmt.Sprintf("/v1/connect/intentions/%s", reply), nil)
resp := httptest.NewRecorder()
obj, err := a.srv.IntentionSpecific(resp, req)
if err != nil {
t.Fatalf("err: %v", err)
}
if obj != nil {
t.Fatalf("obj should be nil: %v", err)
}
assert.Nil(err)
assert.Nil(obj)
// Verify the intention is gone
{
@ -390,9 +329,8 @@ func TestIntentionsSpecificDelete_good(t *testing.T) {
}
var resp structs.IndexedIntentions
err := a.RPC("Intention.Get", req, &resp)
if err == nil || !strings.Contains(err.Error(), "not found") {
t.Fatalf("err: %v", err)
}
assert.NotNil(err)
assert.Contains(err.Error(), "not found")
}
}
@ -429,17 +367,14 @@ func TestParseIntentionMatchEntry(t *testing.T) {
for _, tc := range cases {
t.Run(tc.Input, func(t *testing.T) {
assert := assert.New(t)
actual, err := parseIntentionMatchEntry(tc.Input)
if (err != nil) != tc.Err {
t.Fatalf("err: %s", err)
}
assert.Equal(err != nil, tc.Err, err)
if err != nil {
return
}
if !reflect.DeepEqual(actual, tc.Expected) {
t.Fatalf("bad: %#v", actual)
}
assert.Equal(tc.Expected, actual)
})
}
}

View File

@ -1,10 +1,11 @@
package structs
import (
"reflect"
"sort"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestIntentionValidate(t *testing.T) {
@ -108,19 +109,17 @@ func TestIntentionValidate(t *testing.T) {
for _, tc := range cases {
t.Run(tc.Name, func(t *testing.T) {
assert := assert.New(t)
ixn := TestIntention(t)
tc.Modify(ixn)
err := ixn.Validate()
if (err != nil) != (tc.Err != "") {
t.Fatalf("err: %s", err)
}
assert.Equal(err != nil, tc.Err != "", err)
if err == nil {
return
}
if !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.Err)) {
t.Fatalf("err: %s", err)
}
assert.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.Err))
})
}
}
@ -160,6 +159,8 @@ func TestIntentionPrecedenceSorter(t *testing.T) {
for _, tc := range cases {
t.Run(tc.Name, func(t *testing.T) {
assert := assert.New(t)
var input Intentions
for _, v := range tc.Input {
input = append(input, &Intention{
@ -183,9 +184,7 @@ func TestIntentionPrecedenceSorter(t *testing.T) {
v.DestinationName,
})
}
if !reflect.DeepEqual(actual, tc.Expected) {
t.Fatalf("bad (got, wanted):\n\n%#v\n\n%#v", actual, tc.Expected)
}
assert.Equal(tc.Expected, actual)
})
}
}