github.com/jeffjen/go-libkv@v0.0.0-20151212051932-5df59a45a168/libkv/store_test.go (about)

     1  package libkv
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"sort"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func TestStore(t *testing.T) {
    12  	kv := NewStore()
    13  	defer kv.Close()
    14  
    15  	kv.Set("hello_internet", 1)
    16  	kv.Set("hello_world", func() { fmt.Println("hello human") })
    17  
    18  	x := kv.Get("hello_internet").(int)
    19  	if x != 1 {
    20  		t.Errorf("invalid value for stroed key word: \"hello_internet\"")
    21  		return
    22  	}
    23  
    24  	kv.Del("hello_world")
    25  
    26  	y := kv.Get("hello_world")
    27  	if y != nil {
    28  		t.Errorf("unable to delete stored key word: \"hello_world\"")
    29  		return
    30  	}
    31  }
    32  
    33  func TestExpire(t *testing.T) {
    34  	kv := NewStore()
    35  	defer kv.Close()
    36  
    37  	kv.Setexp("hello_internet", 1, time.Now().Add(1*time.Second))
    38  
    39  	kv.Set("hello_world", 2)
    40  
    41  	time.Sleep(2 * time.Second)
    42  
    43  	x := kv.Get("hello_internet")
    44  	if x != nil {
    45  		t.Errorf("key word: \"hello_internet\" not expired")
    46  		return
    47  	}
    48  
    49  	y := kv.Get("hello_world").(int)
    50  	if y != 2 {
    51  		t.Errorf("key word: \"hello_world\" unexpected get failure")
    52  		return
    53  	}
    54  
    55  	if !kv.Expire("hello_world", time.Now().Add(1*time.Second)) {
    56  		t.Errorf("key word: \"hello_world\" missing")
    57  		return
    58  	}
    59  
    60  	time.Sleep(2 * time.Second)
    61  
    62  	z := kv.Get("hello_world")
    63  	if z != nil {
    64  		t.Errorf("key word: \"hello_world\" not expired")
    65  		return
    66  	}
    67  }
    68  
    69  func TestGetSet(t *testing.T) {
    70  	kv := NewStore()
    71  	defer kv.Close()
    72  
    73  	kv.Setexp("hello_internet", 1, time.Now().Add(1*time.Second))
    74  
    75  	kv.Getset("hello_internet", 2)
    76  
    77  	time.Sleep(1 * time.Second)
    78  
    79  	x := kv.Get("hello_internet")
    80  	if x == nil {
    81  		t.Errorf("key word: \"hello_internet\" unexpected expire")
    82  		return
    83  	}
    84  
    85  	if x.(int) != 2 {
    86  		t.Errorf("key word: \"hello_internet\" holds invalid value")
    87  		return
    88  	}
    89  }
    90  
    91  func TestGetExp(t *testing.T) {
    92  	kv := NewStore()
    93  	defer kv.Close()
    94  
    95  	kv.Set("hello_internet", 1)
    96  
    97  	x := kv.Getexp("hello_internet", time.Now().Add(3*time.Second))
    98  	if x != 1 {
    99  		t.Errorf("key word: \"hello_internet\" should be set")
   100  		return
   101  	}
   102  
   103  	time.Sleep(200 * time.Millisecond)
   104  
   105  	kv.Getexp("hello_internet", time.Now().Add(3*time.Second))
   106  
   107  	time.Sleep(4 * time.Second)
   108  
   109  	x = kv.Get("hello_internet")
   110  	if x != nil {
   111  		t.Errorf("key word: \"hello_internet\" unexpected not expire")
   112  		return
   113  	}
   114  }
   115  
   116  func TestAcquireTTL(t *testing.T) {
   117  	kv := NewStore()
   118  	defer kv.Close()
   119  
   120  	kv.Setexp("hello_internet", 1, time.Now().Add(5*time.Second))
   121  
   122  	kv.Set("hello_world", 1)
   123  
   124  	if kv.TTL("hello_internet") == 0 {
   125  		t.Errorf("key word: \"hello_internet\" holds invalid expire time")
   126  		return
   127  	}
   128  
   129  	if kv.TTL("hello_world") != 0 {
   130  		t.Errorf("key word: \"hello_world\" holds expire time")
   131  	}
   132  }
   133  
   134  func TestLpush(t *testing.T) {
   135  	kv := NewStore()
   136  	defer kv.Close()
   137  
   138  	ref := []int{1, 2, 3, 4, 5}
   139  
   140  	for idx := len(ref) - 1; idx >= 0; idx-- {
   141  		kv.Lpush("hello-internet", ref[idx])
   142  	}
   143  
   144  	lobj := kv.Lrange("hello-internet", 0, -1)
   145  
   146  	if len(lobj) != len(ref) {
   147  		t.Errorf("key word: \"hello-internet\" item count does not agree")
   148  		return
   149  	}
   150  
   151  	for idx := 1; idx < len(ref); idx++ {
   152  		if lobj[idx] != ref[idx] {
   153  			t.Errorf("key word: \"hello-internet\" does not agree at %d", idx)
   154  			fmt.Println(lobj, ref)
   155  			return
   156  		}
   157  	}
   158  }
   159  
   160  func TestLtrim(t *testing.T) {
   161  	kv := NewStore()
   162  	defer kv.Close()
   163  
   164  	ref := []string{"a", "b", "c", "d", "e"}
   165  	init := func() {
   166  		kv.Del("hello-internet")
   167  		for idx := len(ref) - 1; idx >= 0; idx-- {
   168  			kv.Lpush("hello-internet", ref[idx])
   169  		}
   170  	}
   171  	verify := func(lobj []interface{}, ref []string) bool {
   172  		if len(lobj) != len(ref) {
   173  			t.Errorf("key word: \"hello-internet\" item count does not agree")
   174  			return false
   175  		}
   176  		for idx := 1; idx < len(ref); idx++ {
   177  			if lobj[idx] != ref[idx] {
   178  				t.Errorf("key word: \"hello-internet\" does not agree at %d", idx)
   179  				fmt.Println(lobj, ref)
   180  				return false
   181  			}
   182  		}
   183  		return true
   184  	}
   185  
   186  	var lobj []interface{}
   187  
   188  	init()
   189  	kv.Ltrim("hello-internet", 1, 3)
   190  	lobj = kv.Lrange("hello-internet", 0, -1)
   191  	if !verify(lobj, ref[1:3]) {
   192  		return
   193  	}
   194  
   195  	init()
   196  	kv.Ltrim("hello-internet", 1000, 3)
   197  	lobj = kv.Lrange("hello-internet", 0, -1)
   198  	if !verify(lobj, ref[len(ref):]) {
   199  		return
   200  	}
   201  
   202  	init()
   203  	kv.Ltrim("hello-internet", 5, 100)
   204  	lobj = kv.Lrange("hello-internet", 0, -1)
   205  	if !verify(lobj, ref[len(ref):]) {
   206  		return
   207  	}
   208  
   209  	init()
   210  	kv.Ltrim("hello-internet", 2, -1)
   211  	lobj = kv.Lrange("hello-internet", 0, -1)
   212  	if !verify(lobj, ref[2:]) {
   213  		return
   214  	}
   215  
   216  	init()
   217  	kv.Ltrim("hello-internet", -4, -2)
   218  	lobj = kv.Lrange("hello-internet", 0, -1)
   219  	if !verify(lobj, ref[1:4]) {
   220  		return
   221  	}
   222  
   223  	init()
   224  	kv.Ltrim("hello-internet", -900, -2)
   225  	lobj = kv.Lrange("hello-internet", 0, -1)
   226  	if !verify(lobj, ref[:4]) {
   227  		return
   228  	}
   229  }
   230  
   231  func TestKey(t *testing.T) {
   232  	kv := NewStore()
   233  	defer kv.Close()
   234  
   235  	const N = 10
   236  
   237  	for idx := 0; idx < N; idx++ {
   238  		kv.Set(fmt.Sprint(idx), idx)
   239  	}
   240  
   241  	k := kv.Key()
   242  	if len(k) != N {
   243  		t.Errorf("unable to list keys stored")
   244  	} else {
   245  		fmt.Println(k)
   246  	}
   247  }
   248  
   249  func TestKeyexp(t *testing.T) {
   250  	kv := NewStore()
   251  	defer kv.Close()
   252  
   253  	const N = 100
   254  
   255  	var exp_k = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
   256  
   257  	now := time.Now().Add(2 * time.Second)
   258  
   259  	for idx, k := range exp_k {
   260  		kv.Setexp(k, idx, now)
   261  	}
   262  	for idx := N; idx < 10+N; idx++ {
   263  		kv.Set(fmt.Sprint(idx), idx)
   264  	}
   265  
   266  	k := kv.Keyexp()
   267  
   268  	sort.Strings(k)
   269  
   270  	if !reflect.DeepEqual(k, exp_k) {
   271  		t.Errorf("unexpected exp keys mismatch")
   272  	} else {
   273  		fmt.Println(k)
   274  	}
   275  }
   276  
   277  func TestWatch(t *testing.T) {
   278  	kv := NewStore()
   279  	defer kv.Close()
   280  
   281  	stop := make(chan struct{})
   282  	defer close(stop)
   283  
   284  	p1 := make(chan int, 1)
   285  	go func() {
   286  		monitor := kv.Watch(stop)
   287  		for _ = range monitor {
   288  			p1 <- 1
   289  		}
   290  	}()
   291  
   292  	p2 := make(chan int, 1)
   293  	go func() {
   294  		monitor := kv.Watch(stop)
   295  		for _ = range monitor {
   296  			p2 <- 1
   297  		}
   298  	}()
   299  
   300  	<-time.After(2 * time.Second)
   301  
   302  	kv.Set("hello_world", 2)
   303  
   304  	kv.Setexp("hello_internet", 1, time.Now().Add(1*time.Second))
   305  
   306  	kv.Get("hello_internet")
   307  
   308  	kv.Getset("hello_world", 3)
   309  
   310  	woe := time.After(5 * time.Second)
   311  	for idx1, ok1, idx2, ok2 := 0, true, 0, true; ok1 || ok2; {
   312  		select {
   313  		case <-p1:
   314  			idx1 += 1
   315  			ok1 = !(idx1 == 6)
   316  		case <-p2:
   317  			idx2 += 1
   318  			ok2 = !(idx2 == 6)
   319  
   320  		case <-woe:
   321  			t.Errorf("unable to complete: expected events incomplete: %d; %d", idx1, idx2)
   322  			return
   323  		}
   324  	}
   325  }
   326  
   327  func TestWatchExtended(t *testing.T) {
   328  	kv := NewStore()
   329  	defer kv.Close()
   330  
   331  	stop := make(chan struct{})
   332  	p1 := make(chan int, 1)
   333  	go func() {
   334  		monitor := kv.Watch(stop)
   335  		for _ = range monitor {
   336  			p1 <- 1
   337  		}
   338  	}()
   339  
   340  	later := make(chan struct{})
   341  	p2 := make(chan int, 1)
   342  	go func() {
   343  		monitor := kv.Watch(later)
   344  		for _ = range monitor {
   345  			p2 <- 1
   346  		}
   347  	}()
   348  
   349  	<-time.After(2 * time.Second)
   350  
   351  	kv.Set("hello_world", 2)
   352  
   353  	kv.Setexp("hello_internet", 1, time.Now().Add(1*time.Second))
   354  
   355  	kv.Get("hello_internet")
   356  
   357  	kv.Getset("hello_world", 3)
   358  
   359  	close(stop) // kill the firs monitor prematruely
   360  
   361  	woe := time.After(5 * time.Second)
   362  	for idx1, idx2, ok := 0, 0, true; ok; {
   363  		select {
   364  		case <-p1:
   365  			idx1 += 1
   366  			if idx1 > 4 {
   367  				t.Errorf("monitor 1 returned more then expected")
   368  				return
   369  			}
   370  
   371  		case <-p2:
   372  			idx2 += 1
   373  			ok = !(idx2 == 6)
   374  
   375  		case <-woe:
   376  			t.Errorf("unable to complete: expected events incomplete")
   377  			return
   378  		}
   379  	}
   380  
   381  	close(later) // kill the second monitor
   382  }
   383  
   384  func TestWatchNotpresent(t *testing.T) {
   385  	kv := NewStore()
   386  	defer kv.Close()
   387  
   388  	stop := make(chan struct{})
   389  	p1 := make(chan *Event, 1)
   390  	go func() {
   391  		monitor := kv.Watch(stop)
   392  		for evt := range monitor {
   393  			p1 <- evt
   394  		}
   395  		close(p1)
   396  	}()
   397  
   398  	<-time.After(1 * time.Second)
   399  
   400  	hits := make(chan []int, 1)
   401  	go func() {
   402  		evts := make([]int, 0)
   403  		for c := range p1 {
   404  			evts = append(evts, c.Action)
   405  		}
   406  		hits <- evts
   407  	}()
   408  
   409  	events := []int{SET, GET, DEL}
   410  
   411  	kv.Get("where")
   412  	kv.Set("hello", 1)
   413  	kv.Del("where")
   414  	kv.Get("hello")
   415  	kv.Del("hello")
   416  
   417  	time.Sleep(250 * time.Millisecond)
   418  	close(stop)
   419  
   420  	if evts := <-hits; !reflect.DeepEqual(events, evts) {
   421  		t.Errorf("uexpected event set mismatch %v", evts)
   422  	}
   423  }
   424  
   425  func TestSaveLoad(t *testing.T) {
   426  	kv := NewStore()
   427  	defer kv.Close()
   428  
   429  	kv.Set("hello_internet", "random string 1")
   430  	kv.Set("hello_world", 1)
   431  	kv.Setexp("hello_bogus", "random string 3", time.Now().Add(3*time.Second))
   432  	kv.Set("hello_rant", 1.23543)
   433  	kv.Lpush("hello_blurp", "A")
   434  	kv.Lpush("hello_blurp", "B")
   435  	kv.Lpush("hello_blurp", "C")
   436  	kv.Lpush("hello_blurp", 1)
   437  	kv.Lpush("hello_blurp", 2)
   438  	kv.Lpush("hello_blurp", 3)
   439  
   440  	fmt.Println(kv.Get("hello_bogus"))
   441  
   442  	if err := kv.Save("/tmp"); err != nil {
   443  		t.Error(err)
   444  		return
   445  	}
   446  
   447  	<-time.After(5 * time.Second)
   448  
   449  	if nkv, err := Load("/tmp"); err != nil {
   450  		t.Error(err)
   451  		return
   452  	} else {
   453  		kv = nkv
   454  	}
   455  	defer kv.Close()
   456  
   457  	if d, ok := kv.Get("hello_internet").(string); !ok || d != "random string 1" {
   458  		t.Errorf("Data mismatch; expect `random string 1`, got `%v`", d)
   459  	}
   460  	if d, ok := kv.Get("hello_world").(int); !ok || d != 1 {
   461  		t.Errorf("Data mismatch; expect `1`, got `%v`", d)
   462  	}
   463  	if d := kv.Get("hello_bogus"); d != nil {
   464  		t.Errorf("Data mismatch; expect object expired, got `%v`", d)
   465  	}
   466  	if d, ok := kv.Get("hello_rant").(float64); !ok {
   467  		t.Errorf("Data mismatch; expect float, got `%v`", d)
   468  	}
   469  	if d := kv.Lrange("hello_blurp", 0, -1); d == nil || len(d) != 6 {
   470  		t.Errorf("Data mismatch; expect list, got `%v`", d)
   471  	} else {
   472  		fmt.Println(d)
   473  	}
   474  }