github.com/looshlee/beatles@v0.0.0-20220727174639-742810ab631c/pkg/kvstore/base_test.go (about)

     1  // Copyright 2016-2019 Authors of Cilium
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build !privileged_tests
    16  
    17  package kvstore
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"time"
    23  
    24  	"github.com/cilium/cilium/pkg/checker"
    25  
    26  	. "gopkg.in/check.v1"
    27  )
    28  
    29  // BaseTests is the struct that needs to be embedded into all test suite
    30  // structs of backend implementations. It contains all test functions that are
    31  // agnostic to the backend implementation.
    32  type BaseTests struct{}
    33  
    34  func (s *BaseTests) TestLock(c *C) {
    35  	prefix := "locktest/"
    36  
    37  	Client().DeletePrefix(prefix)
    38  	defer Client().DeletePrefix(prefix)
    39  
    40  	for i := 0; i < 10; i++ {
    41  		lock, err := LockPath(context.Background(), Client(), fmt.Sprintf("%sfoo/%d", prefix, i))
    42  		c.Assert(err, IsNil)
    43  		c.Assert(lock, Not(IsNil))
    44  		lock.Unlock()
    45  	}
    46  }
    47  
    48  func testKey(prefix string, i int) string {
    49  	return fmt.Sprintf("%s%s/%010d", prefix, "foo", i)
    50  }
    51  
    52  func testValue(i int) []byte {
    53  	return []byte(fmt.Sprintf("blah %d blah %d", i, i))
    54  }
    55  
    56  func (s *BaseTests) TestGetSet(c *C) {
    57  	prefix := "unit-test/"
    58  	maxID := 256
    59  
    60  	Client().DeletePrefix(prefix)
    61  	defer Client().DeletePrefix(prefix)
    62  
    63  	key, val, err := Client().GetPrefix(context.Background(), prefix)
    64  	c.Assert(err, IsNil)
    65  	c.Assert(val, IsNil)
    66  	c.Assert(key, Equals, "")
    67  
    68  	for i := 0; i < maxID; i++ {
    69  		val, err = Client().Get(testKey(prefix, i))
    70  		c.Assert(err, IsNil)
    71  		c.Assert(val, IsNil)
    72  
    73  		key, val, err = Client().GetPrefix(context.Background(), testKey(prefix, i))
    74  		c.Assert(err, IsNil)
    75  		c.Assert(val, IsNil)
    76  		c.Assert(key, Equals, "")
    77  
    78  		c.Assert(Client().Set(testKey(prefix, i), testValue(i)), IsNil)
    79  
    80  		val, err = Client().Get(testKey(prefix, i))
    81  		c.Assert(err, IsNil)
    82  		c.Assert(val, checker.DeepEquals, testValue(i))
    83  
    84  		val, err = Client().Get(testKey(prefix, i))
    85  		c.Assert(err, IsNil)
    86  		c.Assert(val, checker.DeepEquals, testValue(i))
    87  	}
    88  
    89  	for i := 0; i < maxID; i++ {
    90  		c.Assert(Client().Delete(testKey(prefix, i)), IsNil)
    91  
    92  		val, err = Client().Get(testKey(prefix, i))
    93  		c.Assert(err, IsNil)
    94  		c.Assert(val, IsNil)
    95  
    96  		key, val, err = Client().GetPrefix(context.Background(), testKey(prefix, i))
    97  		c.Assert(err, IsNil)
    98  		c.Assert(val, IsNil)
    99  		c.Assert(key, Equals, "")
   100  	}
   101  
   102  	key, val, err = Client().GetPrefix(context.Background(), prefix)
   103  	c.Assert(err, IsNil)
   104  	c.Assert(val, IsNil)
   105  	c.Assert(key, Equals, "")
   106  }
   107  
   108  func (s *BaseTests) TestGetPrefix(c *C) {
   109  	prefix := "unit-test/"
   110  
   111  	Client().DeletePrefix(prefix)
   112  	defer Client().DeletePrefix(prefix)
   113  
   114  	key, val, err := Client().GetPrefix(context.Background(), prefix)
   115  	c.Assert(err, IsNil)
   116  	c.Assert(val, IsNil)
   117  	c.Assert(key, Equals, "")
   118  
   119  	// create
   120  	labelsLong := "foo;/;bar;"
   121  	labelsShort := "foo;/"
   122  	testKey := fmt.Sprintf("%s%s/%010d", prefix, labelsLong, 0)
   123  	c.Assert(Client().Update(context.Background(), testKey, []byte(testValue(0)), true), IsNil)
   124  
   125  	val, err = Client().Get(testKey)
   126  	c.Assert(err, IsNil)
   127  	c.Assert(val, checker.DeepEquals, testValue(0))
   128  
   129  	prefixes := []string{
   130  		prefix,
   131  		fmt.Sprintf("%s%s", prefix, labelsLong),
   132  		fmt.Sprintf("%s%s", prefix, labelsShort),
   133  	}
   134  	for _, p := range prefixes {
   135  		key, val, err = Client().GetPrefix(context.Background(), p)
   136  		c.Assert(err, IsNil)
   137  		c.Assert(val, checker.DeepEquals, testValue(0))
   138  		c.Assert(key, Equals, testKey)
   139  	}
   140  }
   141  
   142  func (s *BaseTests) BenchmarkGet(c *C) {
   143  	prefix := "unit-test/"
   144  	Client().DeletePrefix(prefix)
   145  	defer Client().DeletePrefix(prefix)
   146  
   147  	key := testKey(prefix, 1)
   148  	c.Assert(Client().Set(key, testValue(100)), IsNil)
   149  
   150  	c.ResetTimer()
   151  	for i := 0; i < c.N; i++ {
   152  		Client().Get(key)
   153  	}
   154  }
   155  
   156  func (s *BaseTests) BenchmarkSet(c *C) {
   157  	prefix := "unit-test/"
   158  	Client().DeletePrefix(prefix)
   159  	defer Client().DeletePrefix(prefix)
   160  
   161  	key, val := testKey(prefix, 1), testValue(100)
   162  	c.ResetTimer()
   163  	for i := 0; i < c.N; i++ {
   164  		Client().Set(key, val)
   165  	}
   166  }
   167  
   168  func (s *BaseTests) TestUpdate(c *C) {
   169  	prefix := "unit-test/"
   170  
   171  	Client().DeletePrefix(prefix)
   172  	defer Client().DeletePrefix(prefix)
   173  
   174  	key, val, err := Client().GetPrefix(context.Background(), prefix)
   175  	c.Assert(err, IsNil)
   176  	c.Assert(val, IsNil)
   177  	c.Assert(key, Equals, "")
   178  
   179  	// create
   180  	c.Assert(Client().Update(context.Background(), testKey(prefix, 0), []byte(testValue(0)), true), IsNil)
   181  
   182  	val, err = Client().Get(testKey(prefix, 0))
   183  	c.Assert(err, IsNil)
   184  	c.Assert(val, checker.DeepEquals, testValue(0))
   185  
   186  	// update
   187  	c.Assert(Client().Update(context.Background(), testKey(prefix, 0), []byte(testValue(0)), true), IsNil)
   188  
   189  	val, err = Client().Get(testKey(prefix, 0))
   190  	c.Assert(err, IsNil)
   191  	c.Assert(val, checker.DeepEquals, testValue(0))
   192  }
   193  
   194  func (s *BaseTests) TestCreateOnly(c *C) {
   195  	prefix := "unit-test/"
   196  
   197  	Client().DeletePrefix(prefix)
   198  	defer Client().DeletePrefix(prefix)
   199  
   200  	key, val, err := Client().GetPrefix(context.Background(), prefix)
   201  	c.Assert(err, IsNil)
   202  	c.Assert(val, IsNil)
   203  	c.Assert(key, Equals, "")
   204  
   205  	success, err := Client().CreateOnly(context.Background(), testKey(prefix, 0), []byte(testValue(0)), false)
   206  	c.Assert(err, IsNil)
   207  	c.Assert(success, Equals, true)
   208  
   209  	val, err = Client().Get(testKey(prefix, 0))
   210  	c.Assert(err, IsNil)
   211  	c.Assert(val, checker.DeepEquals, testValue(0))
   212  
   213  	success, err = Client().CreateOnly(context.Background(), testKey(prefix, 0), []byte(testValue(1)), false)
   214  	c.Assert(err, IsNil)
   215  	c.Assert(success, Equals, false)
   216  
   217  	val, err = Client().Get(testKey(prefix, 0))
   218  	c.Assert(err, IsNil)
   219  	c.Assert(val, checker.DeepEquals, testValue(0))
   220  
   221  	// key 1 does not exist so CreateIfExists should fail
   222  	c.Assert(Client().CreateIfExists(testKey(prefix, 1), testKey(prefix, 2), testValue(2), false), Not(IsNil))
   223  
   224  	val, err = Client().Get(testKey(prefix, 2))
   225  	c.Assert(err, IsNil)
   226  	c.Assert(val, IsNil)
   227  
   228  	// key 0 exists so CreateIfExists should succeed
   229  	c.Assert(Client().CreateIfExists(testKey(prefix, 0), testKey(prefix, 2), testValue(2), false), IsNil)
   230  
   231  	val, err = Client().Get(testKey(prefix, 2))
   232  	c.Assert(err, IsNil)
   233  	c.Assert(val, checker.DeepEquals, testValue(2))
   234  }
   235  
   236  func expectEvent(c *C, w *Watcher, typ EventType, key string, val []byte) {
   237  	select {
   238  	case event := <-w.Events:
   239  		c.Assert(event.Typ, Equals, typ)
   240  
   241  		if event.Typ != EventTypeListDone {
   242  			c.Assert(event.Key, checker.DeepEquals, key)
   243  
   244  			// etcd does not provide the value of deleted keys
   245  			if selectedModule == "consul" {
   246  				c.Assert(event.Value, checker.DeepEquals, val)
   247  			}
   248  		}
   249  	case <-time.After(10 * time.Second):
   250  		c.Fatal("timeout while waiting for kvstore watcher event")
   251  	}
   252  }
   253  
   254  func (s *BaseTests) TestListAndWatch(c *C) {
   255  	key1, key2 := "foo2/key1", "foo2/key2"
   256  	val1, val2 := []byte("val1"), []byte("val2")
   257  
   258  	Client().DeletePrefix("foo2/")
   259  	defer Client().DeletePrefix("foo2/")
   260  
   261  	success, err := Client().CreateOnly(context.Background(), key1, []byte(val1), false)
   262  	c.Assert(err, IsNil)
   263  	c.Assert(success, Equals, true)
   264  
   265  	w := ListAndWatch("testWatcher2", "foo2/", 100)
   266  	c.Assert(c, Not(IsNil))
   267  
   268  	expectEvent(c, w, EventTypeCreate, key1, val1)
   269  	expectEvent(c, w, EventTypeListDone, "", []byte{})
   270  
   271  	success, err = Client().CreateOnly(context.Background(), key2, []byte(val2), false)
   272  	c.Assert(err, IsNil)
   273  	c.Assert(success, Equals, true)
   274  	expectEvent(c, w, EventTypeCreate, key2, val2)
   275  
   276  	err = Client().Delete(key1)
   277  	c.Assert(err, IsNil)
   278  	expectEvent(c, w, EventTypeDelete, key1, val1)
   279  
   280  	success, err = Client().CreateOnly(context.Background(), key1, []byte(val1), false)
   281  	c.Assert(err, IsNil)
   282  	c.Assert(success, Equals, true)
   283  	expectEvent(c, w, EventTypeCreate, key1, val1)
   284  
   285  	err = Client().Delete(key1)
   286  	c.Assert(err, IsNil)
   287  	expectEvent(c, w, EventTypeDelete, key1, val1)
   288  
   289  	err = Client().Delete(key2)
   290  	c.Assert(err, IsNil)
   291  	expectEvent(c, w, EventTypeDelete, key2, val2)
   292  
   293  	w.Stop()
   294  }