Repository: etcd-io/etcd
File: tests/integration/cache_test.go (Go)

Code before:
					if diff := cmp.Diff(tc.wantKVs, resp.Kvs); diff != "" {
						t.Fatalf("unexpected KVs (-want +got):\n%s", diff)
					}
					if resp.Header.Revision != tc.wantRevision {
						t.Fatalf("revision: got %d, want %d", resp.Header.Revision, tc.wantRevision)
					}
				})
			}
		})
	}
}

func TestGet(t *testing.T) {
	integration.BeforeTest(t)
	clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1})
	t.Cleanup(func() { clus.Terminate(t) })

	client := clus.Client(0)
	testGet(t, client.KV, client.KV)
}

func testGet(t *testing.T, kv clientv3.KV, reader Getter) {
	ctx := t.Context()

	t.Log("Setup")
	lastRev := applyEvents(ctx, t, kv, TestGetEvents)

	if c, ok := reader.(*cache.Cache); ok {
		if err := c.WaitForRevision(ctx, lastRev); err != nil {
			t.Fatalf("cache never caught up to rev %d: %v", lastRev, err)
		}
	}

	t.Log("Validate")
	for _, tc := range getTestCases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			resp, err := reader.Get(ctx, tc.key, tc.opts...)
			if err != nil {
				t.Fatalf("Get %q failed: %v", tc.key, err)
			}
			if diff := cmp.Diff(tc.wantKVs, resp.Kvs); diff != "" {
				t.Fatalf("unexpected KVs (-want +got):\n%s", diff)
			}
			if resp.Header.Revision != tc.wantRevision {
				t.Fatalf("revision: got %d, want %d", resp.Header.Revision, tc.wantRevision)
			}
		})
	}
}


Review comment (performance):
Maybe you could unify the code:
```
func testGet(t *testing.T, kv clientv3.KV, getReader func() Getter, initialEvents, followupEvents []*clientv3.Event) {
	ctx := t.Context()
	t.Log("Setup")
	lastRev := applyEvents(ctx, t, kv, initialEvents)
	reader := getReader()
	if c, ok := reader.(*cache.Cache); ok {
		if err := c.WaitForRevision(ctx, lastRev); err != nil {
			t.Fatalf("cache never caught up to rev %d: %v", lastRev, err)
		}
	}
	lastRev = applyEvents(ctx, t, kv, followupEvents)
	if c, ok := reader.(*cache.Cache); ok {
		if err := c.WaitForRevision(ctx, lastRev); err != nil {
			t.Fatalf("cache never caught up to rev %d: %v", lastRev, err)
		}
	}
```

Code after:
	t.Log("Validate")
	for _, tc := range getTestCases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			resp, err := reader.Get(ctx, tc.key, tc.opts...)
			if err != nil {
				t.Fatalf("Get %q failed: %v", tc.key, err)
			}
			if diff := cmp.Diff(tc.wantKVs, resp.Kvs); diff != "" {
				t.Fatalf("unexpected KVs (-want +got):\n%s", diff)
			}
			if resp.Header.Revision != tc.wantRevision {
				t.Fatalf("revision: got %d, want %d", resp.Header.Revision, tc.wantRevision)
			}
		})
	}
}

var TestGetEvents = []*clientv3.Event{
	Rev2PutFooA, Rev3PutFooB, Rev4PutFooC, Rev5PutFooD, Rev6DeleteFooD, Rev7TxnPutFooA, Rev7TxnPutFooB, Rev8PutFooA,
}

var (
	Rev2PutFooA = &clientv3.Event{
		Type: clientv3.EventTypePut,
		Kv: &mvccpb.KeyValue{
			Key:            []byte("/foo/a"),
			Value:          []byte("a1"),
			CreateRevision: 2,
			ModRevision:    2,
			Version:        1,
		},
	}
	Rev3PutFooB = &clientv3.Event{
		Type: clientv3.EventTypePut,
		Kv: &mvccpb.KeyValue{
			Key:            []byte("/foo/b"),
			Value:          []byte("b1"),
			CreateRevision: 3,
			ModRevision:    3,
			Version:        1,
		},
	}
	Rev4PutFooC = &clientv3.Event{
		Type: clientv3.EventTypePut,
		Kv: &mvccpb.KeyValue{
			Key:            []byte("/foo/c"),
			Value:          []byte("c1"),
			CreateRevision: 4,
			ModRevision:    4,
			Version:        1,