From a44ddea9ba1f715dc243271af07ac43cfff24a32 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Wed, 22 Jul 2020 16:26:49 -0400 Subject: [PATCH] state: Use subtests in TestStateStore_ServicesByNodeMeta These subtests make it much easier to identify the slow part of the test, but they also help enumerate all the different cases which are being tested. --- agent/consul/state/catalog_test.go | 157 ++++++++++++++--------------- 1 file changed, 75 insertions(+), 82 deletions(-) diff --git a/agent/consul/state/catalog_test.go b/agent/consul/state/catalog_test.go index c080f2a0d..c21b203db 100644 --- a/agent/consul/state/catalog_test.go +++ b/agent/consul/state/catalog_test.go @@ -1611,12 +1611,14 @@ func TestStateStore_Services(t *testing.T) { func TestStateStore_ServicesByNodeMeta(t *testing.T) { s := testStateStore(t) - // Listing with no results returns nil. ws := memdb.NewWatchSet() - idx, res, err := s.ServicesByNodeMeta(ws, map[string]string{"somekey": "somevalue"}, nil) - if idx != 0 || len(res) != 0 || err != nil { - t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err) - } + + t.Run("Listing with no results returns nil", func(t *testing.T) { + idx, res, err := s.ServicesByNodeMeta(ws, map[string]string{"somekey": "somevalue"}, nil) + if idx != 0 || len(res) != 0 || err != nil { + t.Fatalf("expected (0, nil, nil), got: (%d, %#v, %#v)", idx, res, err) + } + }) // Create some nodes and services in the state store. node0 := &structs.Node{Node: "node0", Address: "127.0.0.1", Meta: map[string]string{"role": "client", "common": "1"}} @@ -1648,94 +1650,85 @@ func TestStateStore_ServicesByNodeMeta(t *testing.T) { t.Fatalf("err: %s", err) } if !watchFired(ws) { - t.Fatalf("bad") + t.Fatalf("expected the watch to be triggered by the queries") } - // Filter the services by the first node's meta value. ws = memdb.NewWatchSet() - _, res, err = s.ServicesByNodeMeta(ws, map[string]string{"role": "client"}, nil) - if err != nil { - t.Fatalf("err: %s", err) - } - expected := structs.Services{ - "redis": []string{"master", "prod"}, - } - sort.Strings(res["redis"]) - if !reflect.DeepEqual(res, expected) { - t.Fatalf("bad: %v %v", res, expected) - } - // Get all services using the common meta value - _, res, err = s.ServicesByNodeMeta(ws, map[string]string{"common": "1"}, nil) - if err != nil { - t.Fatalf("err: %s", err) - } - expected = structs.Services{ - "redis": []string{"master", "prod", "slave"}, - } - sort.Strings(res["redis"]) - if !reflect.DeepEqual(res, expected) { - t.Fatalf("bad: %v %v", res, expected) - } + t.Run("Filter the services by the first node's meta value", func(t *testing.T) { + _, res, err := s.ServicesByNodeMeta(ws, map[string]string{"role": "client"}, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + expected := structs.Services{ + "redis": []string{"master", "prod"}, + } + sort.Strings(res["redis"]) + require.Equal(t, expected, res) + }) - // Get an empty list for an invalid meta value - _, res, err = s.ServicesByNodeMeta(ws, map[string]string{"invalid": "nope"}, nil) - if err != nil { - t.Fatalf("err: %s", err) - } - expected = structs.Services{} - if !reflect.DeepEqual(res, expected) { - t.Fatalf("bad: %v %v", res, expected) - } + t.Run("Get all services using the common meta value", func(t *testing.T) { + _, res, err := s.ServicesByNodeMeta(ws, map[string]string{"common": "1"}, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + expected := structs.Services{ + "redis": []string{"master", "prod", "slave"}, + } + sort.Strings(res["redis"]) + require.Equal(t, expected, res) + }) - // Get the first node's service instance using multiple meta filters - _, res, err = s.ServicesByNodeMeta(ws, map[string]string{"role": "client", "common": "1"}, nil) - if err != nil { - t.Fatalf("err: %s", err) - } - expected = structs.Services{ - "redis": []string{"master", "prod"}, - } - sort.Strings(res["redis"]) - if !reflect.DeepEqual(res, expected) { - t.Fatalf("bad: %v %v", res, expected) - } + t.Run("Get an empty list for an invalid meta value", func(t *testing.T) { + _, res, err := s.ServicesByNodeMeta(ws, map[string]string{"invalid": "nope"}, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + expected := structs.Services{} + require.Equal(t, expected, res) + }) - // Sanity check the watch before we proceed. - if watchFired(ws) { - t.Fatalf("bad") - } + t.Run("Get the first node's service instance using multiple meta filters", func(t *testing.T) { + _, res, err := s.ServicesByNodeMeta(ws, map[string]string{"role": "client", "common": "1"}, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + expected := structs.Services{ + "redis": []string{"master", "prod"}, + } + sort.Strings(res["redis"]) + require.Equal(t, expected, res) + }) - // Registering some unrelated node + service should not fire the watch. - testRegisterNode(t, s, 4, "nope") - testRegisterService(t, s, 5, "nope", "nope") - if watchFired(ws) { - t.Fatalf("bad") - } + t.Run("Registering some unrelated node + service should not fire the watch.", func(t *testing.T) { + testRegisterNode(t, s, 4, "nope") + testRegisterService(t, s, 5, "nope", "nope") + if watchFired(ws) { + t.Fatalf("expected the watch to timeout and not be triggered") + } + }) - // Overwhelm the service tracking. - idx = 6 - for i := 0; i < 2*watchLimit; i++ { - node := fmt.Sprintf("many%d", i) - testRegisterNodeWithMeta(t, s, idx, node, map[string]string{"common": "1"}) - idx++ - testRegisterService(t, s, idx, node, "nope") - idx++ - } + t.Run("Uses watchLimit to limit the number of watches", func(t *testing.T) { + var idx uint64 = 6 + for i := 0; i < 2*watchLimit; i++ { + node := fmt.Sprintf("many%d", i) + testRegisterNodeWithMeta(t, s, idx, node, map[string]string{"common": "1"}) + idx++ + testRegisterService(t, s, idx, node, "nope") + idx++ + } - // Now get a fresh watch, which will be forced to watch the whole - // service table. - ws = memdb.NewWatchSet() - _, _, err = s.ServicesByNodeMeta(ws, map[string]string{"common": "1"}, nil) - if err != nil { - t.Fatalf("err: %s", err) - } + // Now get a fresh watch, which will be forced to watch the whole + // service table. + ws := memdb.NewWatchSet() + _, _, err := s.ServicesByNodeMeta(ws, map[string]string{"common": "1"}, nil) + require.NoError(t, err) - // Registering some unrelated node + service should not fire the watch. - testRegisterService(t, s, idx, "nope", "more-nope") - if !watchFired(ws) { - t.Fatalf("bad") - } + testRegisterService(t, s, idx, "nope", "more-nope") + if !watchFired(ws) { + t.Fatalf("expected the watch to timeout and not be triggered") + } + }) } func TestStateStore_ServiceNodes(t *testing.T) {