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 }