Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Removing inter-test dependency in list
Browse files Browse the repository at this point in the history
marco6 committed Jul 4, 2024
1 parent 31648dc commit cc45e26
Showing 1 changed file with 128 additions and 136 deletions.
264 changes: 128 additions & 136 deletions test/list_test.go
Original file line number Diff line number Diff line change
@@ -12,175 +12,167 @@ import (

// TestList is the unit test for List operation.
func TestList(t *testing.T) {
g := NewWithT(t)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

client, _ := newKine(ctx, t)

t.Run("ListSuccess", func(t *testing.T) {
keys := shuffleList([]string{"/key/1", "/key/2", "/key/3", "/key/4", "/key/5"})
for _, key := range keys {
createKey(ctx, g, client, key, "value")
}

t.Run("ListAll", func(t *testing.T) {
g := NewWithT(t)
// Get a list of all the keys
resp, err := client.Get(ctx, "/key", clientv3.WithPrefix())

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(5))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/2")))
g.Expect(resp.Kvs[2].Key).To(Equal([]byte("/key/3")))
g.Expect(resp.Kvs[3].Key).To(Equal([]byte("/key/4")))
g.Expect(resp.Kvs[4].Key).To(Equal([]byte("/key/5")))
})

t.Run("ListAllLimit", func(t *testing.T) {
g := NewWithT(t)

resp, err := client.Get(ctx, "/key", clientv3.WithPrefix(), clientv3.WithLimit(2))

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(2))
g.Expect(resp.More).To(BeTrue())
g.Expect(resp.Count).To(Equal(int64(5)))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/2")))

rev := resp.Header.Revision

// Inspired from https://github.com/kubernetes/kubernetes/blob/3f4d3b67682335db510f85deb65b322127a3a0a1/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go#L788-L793
// Key is "last_key" + "\x00", and we use the prefix range end
resp, err = client.Get(ctx, "/key/2\x00",
clientv3.WithRange(clientv3.GetPrefixRangeEnd("/key")),
clientv3.WithLimit(2),
clientv3.WithRev(rev))

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(2))
g.Expect(resp.More).To(BeTrue())
g.Expect(resp.Count).To(Equal(int64(3)))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/3")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/4")))

rev = resp.Header.Revision

resp, err = client.Get(ctx, "/key/4\x00",
clientv3.WithRange(clientv3.GetPrefixRangeEnd("/key")),
clientv3.WithLimit(2),
clientv3.WithRev(rev))

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.More).To(BeFalse())
g.Expect(resp.Count).To(Equal(int64(1)))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/5")))
})

t.Run("ListPrefix", func(t *testing.T) {
g := NewWithT(t)
// Create some keys
keys := shuffleList([]string{"/key/1", "/key/2", "/key/3", "/key/4", "/key/5"})
keys := []string{"key/sub/2", "key/sub/1", "key/other/1"}
for _, key := range keys {
createKey(ctx, g, client, key, "value")
}

t.Run("ListAll", func(t *testing.T) {
g := NewWithT(t)
// Get a list of all the keys
resp, err := client.Get(ctx, "/key", clientv3.WithPrefix())
// Get a list of all the keys sice they have '/key' prefix
resp, err := client.Get(ctx, "/key", clientv3.WithPrefix())

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(5))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/2")))
g.Expect(resp.Kvs[2].Key).To(Equal([]byte("/key/3")))
g.Expect(resp.Kvs[3].Key).To(Equal([]byte("/key/4")))
g.Expect(resp.Kvs[4].Key).To(Equal([]byte("/key/5")))
})
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(5))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/2")))
g.Expect(resp.Kvs[2].Key).To(Equal([]byte("/key/3")))
g.Expect(resp.Kvs[3].Key).To(Equal([]byte("/key/4")))
g.Expect(resp.Kvs[4].Key).To(Equal([]byte("/key/5")))

t.Run("ListAllLimit", func(t *testing.T) {
var revision int64
t.Run("FirstPage", func(t *testing.T) {
g := NewWithT(t)

resp, err := client.Get(ctx, "/key", clientv3.WithPrefix(), clientv3.WithLimit(2))

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(2))
g.Expect(resp.More).To(BeTrue())
g.Expect(resp.Count).To(Equal(int64(5)))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/2")))

revision = resp.Header.Revision
})

t.Run("SecondPage", func(t *testing.T) {
g := NewWithT(t)

// Inspired from https://github.com/kubernetes/kubernetes/blob/3f4d3b67682335db510f85deb65b322127a3a0a1/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go#L788-L793
// Key is "last_key" + "\x00", and we use the prefix range end
resp, err := client.Get(ctx, "/key/2\x00", clientv3.WithRange(clientv3.GetPrefixRangeEnd("/key")), clientv3.WithLimit(2), clientv3.WithRev(revision))

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(2))
g.Expect(resp.More).To(BeTrue())
g.Expect(resp.Count).To(Equal(int64(3)))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/3")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/4")))

revision = resp.Header.Revision
})

t.Run("ThirdPage", func(t *testing.T) {
g := NewWithT(t)

// Get a list of all the keys
resp, err := client.Get(ctx, "/key/4\x00", clientv3.WithRange(clientv3.GetPrefixRangeEnd("/key")), clientv3.WithLimit(2), clientv3.WithRev(revision))

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.More).To(BeFalse())
g.Expect(resp.Count).To(Equal(int64(1)))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/5")))
})
})
// Get a list of all the keys sice they have '/key/sub' prefix
resp, err = client.Get(ctx, "key/sub", clientv3.WithPrefix())

t.Run("ListPrefix", func(t *testing.T) {
g := NewWithT(t)
// Create some keys
keys := []string{"key/sub/2", "key/sub/1", "key/other/1"}
for _, key := range keys {
createKey(ctx, g, client, key, "value")
}
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(2))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("key/sub/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("key/sub/2")))

// Get a list of all the keys sice they have '/key' prefix
resp, err := client.Get(ctx, "/key", clientv3.WithPrefix())
// Get a list of all the keys sice they have '/key/other' prefix
resp, err = client.Get(ctx, "key/other", clientv3.WithPrefix())

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(5))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("/key/2")))
g.Expect(resp.Kvs[2].Key).To(Equal([]byte("/key/3")))
g.Expect(resp.Kvs[3].Key).To(Equal([]byte("/key/4")))
g.Expect(resp.Kvs[4].Key).To(Equal([]byte("/key/5")))
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("key/other/1")))
})

// Get a list of all the keys sice they have '/key/sub' prefix
resp, err = client.Get(ctx, "key/sub", clientv3.WithPrefix())
t.Run("ListRange", func(t *testing.T) {
g := NewWithT(t)

g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(2))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("key/sub/1")))
g.Expect(resp.Kvs[1].Key).To(Equal([]byte("key/sub/2")))
// Get a list of with key/1, as only key/1 falls within the specified range.
resp, err := client.Get(ctx, "/key/1", clientv3.WithRange(""))

// Get a list of all the keys sice they have '/key/other' prefix
resp, err = client.Get(ctx, "key/other", clientv3.WithPrefix())
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
})

t.Run("ListRevision", func(t *testing.T) {
g := NewWithT(t)

const key = "/revkey/1"
createRev := createKey(ctx, g, client, key, "value")

const updates = 50
for i, rev := 0, createRev; i < updates; i++ {
rev = updateRev(ctx, g, client, key, rev, fmt.Sprintf("val-%d", i))
}

t.Run("NoRevision", func(t *testing.T) {
g := NewWithT(t)

resp, err := client.Get(ctx, "/revkey/", clientv3.WithPrefix())
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("key/other/1")))
g.Expect(resp.Kvs[0].ModRevision).To(Equal(int64(createRev + updates)))
g.Expect(resp.Count).To(Equal(int64(1)))
})

t.Run("ListRange", func(t *testing.T) {
t.Run("OldRevision", func(t *testing.T) {
g := NewWithT(t)

// Get a list of with key/1, as only key/1 falls within the specified range.
resp, err := client.Get(ctx, "/key/1", clientv3.WithRange(""))

resp, err := client.Get(ctx, "/revkey/", clientv3.WithPrefix(), clientv3.WithRev(createRev+30))
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Header.Revision).ToNot(BeZero())
g.Expect(resp.Kvs[0].Key).To(Equal([]byte("/key/1")))
g.Expect(resp.Kvs[0].ModRevision).To(Equal(int64(createRev + 30)))
g.Expect(resp.Count).To(Equal(int64(1)))
})

t.Run("ListRevision", func(t *testing.T) {
t.Run("LaterRevision", func(t *testing.T) {
g := NewWithT(t)

// Create some keys
const key = "/revkey/1"
initialRevision := createKey(ctx, g, client, key, "value")

const updates = 50
for i := 0; i < updates; i++ {
updateKey(ctx, g, client, key, fmt.Sprintf("val-%d", i))
}

t.Run("List", func(t *testing.T) {
t.Run("NoRevision", func(t *testing.T) {
g := NewWithT(t)
resp, err := client.Get(ctx, "/revkey/", clientv3.WithPrefix())
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Kvs[0].ModRevision).To(Equal(int64(initialRevision + updates)))
g.Expect(resp.Count).To(Equal(int64(1)))
})

t.Run("OldRevision", func(t *testing.T) {
g := NewWithT(t)
resp, err := client.Get(ctx, "/revkey/", clientv3.WithPrefix(), clientv3.WithRev(initialRevision+30))
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Kvs[0].ModRevision).To(Equal(int64(initialRevision + 30)))
g.Expect(resp.Count).To(Equal(int64(1)))
})
t.Run("LaterRevision", func(t *testing.T) {
g := NewWithT(t)
resp, err := client.Get(ctx, "/revkey/", clientv3.WithPrefix(), clientv3.WithRev(initialRevision+100))
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Kvs[0].ModRevision).To(Equal(int64(initialRevision + updates)))
g.Expect(resp.Count).To(Equal(int64(1)))
})
})
resp, err := client.Get(ctx, "/revkey/", clientv3.WithPrefix(), clientv3.WithRev(createRev+100))
g.Expect(err).To(BeNil())
g.Expect(resp.Kvs).To(HaveLen(1))
g.Expect(resp.Kvs[0].ModRevision).To(Equal(int64(createRev + updates)))
g.Expect(resp.Count).To(Equal(int64(1)))
})
})
}

0 comments on commit cc45e26

Please sign in to comment.