1 package cache
2
3 import (
4 "bytes"
5 "io/ioutil"
6 "runtime"
7 "strconv"
8 "sync"
9 "testing"
10 "time"
11 )
12
13 type TestStruct struct {
14 Num int
15 Children []*TestStruct
16 }
17
18 func TestCache(t *testing.T) {
19 tc := New(DefaultExpiration, 0)
20
21 a, found := tc.Get("a")
22 if found || a != nil {
23 t.Error("Getting A found value that shouldn't exist:", a)
24 }
25
26 b, found := tc.Get("b")
27 if found || b != nil {
28 t.Error("Getting B found value that shouldn't exist:", b)
29 }
30
31 c, found := tc.Get("c")
32 if found || c != nil {
33 t.Error("Getting C found value that shouldn't exist:", c)
34 }
35
36 tc.Set("a", 1, DefaultExpiration)
37 tc.Set("b", "b", DefaultExpiration)
38 tc.Set("c", 3.5, DefaultExpiration)
39
40 x, found := tc.Get("a")
41 if !found {
42 t.Error("a was not found while getting a2")
43 }
44 if x == nil {
45 t.Error("x for a is nil")
46 } else if a2 := x.(int); a2+2 != 3 {
47 t.Error("a2 (which should be 1) plus 2 does not equal 3; value:", a2)
48 }
49
50 x, found = tc.Get("b")
51 if !found {
52 t.Error("b was not found while getting b2")
53 }
54 if x == nil {
55 t.Error("x for b is nil")
56 } else if b2 := x.(string); b2+"B" != "bB" {
57 t.Error("b2 (which should be b) plus B does not equal bB; value:", b2)
58 }
59
60 x, found = tc.Get("c")
61 if !found {
62 t.Error("c was not found while getting c2")
63 }
64 if x == nil {
65 t.Error("x for c is nil")
66 } else if c2 := x.(float64); c2+1.2 != 4.7 {
67 t.Error("c2 (which should be 3.5) plus 1.2 does not equal 4.7; value:", c2)
68 }
69 }
70
71 func TestCacheTimes(t *testing.T) {
72 var found bool
73
74 tc := New(50*time.Millisecond, 1*time.Millisecond)
75 tc.Set("a", 1, DefaultExpiration)
76 tc.Set("b", 2, NoExpiration)
77 tc.Set("c", 3, 20*time.Millisecond)
78 tc.Set("d", 4, 70*time.Millisecond)
79
80 <-time.After(25 * time.Millisecond)
81 _, found = tc.Get("c")
82 if found {
83 t.Error("Found c when it should have been automatically deleted")
84 }
85
86 <-time.After(30 * time.Millisecond)
87 _, found = tc.Get("a")
88 if found {
89 t.Error("Found a when it should have been automatically deleted")
90 }
91
92 _, found = tc.Get("b")
93 if !found {
94 t.Error("Did not find b even though it was set to never expire")
95 }
96
97 _, found = tc.Get("d")
98 if !found {
99 t.Error("Did not find d even though it was set to expire later than the default")
100 }
101
102 <-time.After(20 * time.Millisecond)
103 _, found = tc.Get("d")
104 if found {
105 t.Error("Found d when it should have been automatically deleted (later than the default)")
106 }
107 }
108
109 func TestNewFrom(t *testing.T) {
110 m := map[string]Item{
111 "a": Item{
112 Object: 1,
113 Expiration: 0,
114 },
115 "b": Item{
116 Object: 2,
117 Expiration: 0,
118 },
119 }
120 tc := NewFrom(DefaultExpiration, 0, m)
121 a, found := tc.Get("a")
122 if !found {
123 t.Fatal("Did not find a")
124 }
125 if a.(int) != 1 {
126 t.Fatal("a is not 1")
127 }
128 b, found := tc.Get("b")
129 if !found {
130 t.Fatal("Did not find b")
131 }
132 if b.(int) != 2 {
133 t.Fatal("b is not 2")
134 }
135 }
136
137 func TestStorePointerToStruct(t *testing.T) {
138 tc := New(DefaultExpiration, 0)
139 tc.Set("foo", &TestStruct{Num: 1}, DefaultExpiration)
140 x, found := tc.Get("foo")
141 if !found {
142 t.Fatal("*TestStruct was not found for foo")
143 }
144 foo := x.(*TestStruct)
145 foo.Num++
146
147 y, found := tc.Get("foo")
148 if !found {
149 t.Fatal("*TestStruct was not found for foo (second time)")
150 }
151 bar := y.(*TestStruct)
152 if bar.Num != 2 {
153 t.Fatal("TestStruct.Num is not 2")
154 }
155 }
156
157 func TestIncrementWithInt(t *testing.T) {
158 tc := New(DefaultExpiration, 0)
159 tc.Set("tint", 1, DefaultExpiration)
160 err := tc.Increment("tint", 2)
161 if err != nil {
162 t.Error("Error incrementing:", err)
163 }
164 x, found := tc.Get("tint")
165 if !found {
166 t.Error("tint was not found")
167 }
168 if x.(int) != 3 {
169 t.Error("tint is not 3:", x)
170 }
171 }
172
173 func TestIncrementWithInt8(t *testing.T) {
174 tc := New(DefaultExpiration, 0)
175 tc.Set("tint8", int8(1), DefaultExpiration)
176 err := tc.Increment("tint8", 2)
177 if err != nil {
178 t.Error("Error incrementing:", err)
179 }
180 x, found := tc.Get("tint8")
181 if !found {
182 t.Error("tint8 was not found")
183 }
184 if x.(int8) != 3 {
185 t.Error("tint8 is not 3:", x)
186 }
187 }
188
189 func TestIncrementWithInt16(t *testing.T) {
190 tc := New(DefaultExpiration, 0)
191 tc.Set("tint16", int16(1), DefaultExpiration)
192 err := tc.Increment("tint16", 2)
193 if err != nil {
194 t.Error("Error incrementing:", err)
195 }
196 x, found := tc.Get("tint16")
197 if !found {
198 t.Error("tint16 was not found")
199 }
200 if x.(int16) != 3 {
201 t.Error("tint16 is not 3:", x)
202 }
203 }
204
205 func TestIncrementWithInt32(t *testing.T) {
206 tc := New(DefaultExpiration, 0)
207 tc.Set("tint32", int32(1), DefaultExpiration)
208 err := tc.Increment("tint32", 2)
209 if err != nil {
210 t.Error("Error incrementing:", err)
211 }
212 x, found := tc.Get("tint32")
213 if !found {
214 t.Error("tint32 was not found")
215 }
216 if x.(int32) != 3 {
217 t.Error("tint32 is not 3:", x)
218 }
219 }
220
221 func TestIncrementWithInt64(t *testing.T) {
222 tc := New(DefaultExpiration, 0)
223 tc.Set("tint64", int64(1), DefaultExpiration)
224 err := tc.Increment("tint64", 2)
225 if err != nil {
226 t.Error("Error incrementing:", err)
227 }
228 x, found := tc.Get("tint64")
229 if !found {
230 t.Error("tint64 was not found")
231 }
232 if x.(int64) != 3 {
233 t.Error("tint64 is not 3:", x)
234 }
235 }
236
237 func TestIncrementWithUint(t *testing.T) {
238 tc := New(DefaultExpiration, 0)
239 tc.Set("tuint", uint(1), DefaultExpiration)
240 err := tc.Increment("tuint", 2)
241 if err != nil {
242 t.Error("Error incrementing:", err)
243 }
244 x, found := tc.Get("tuint")
245 if !found {
246 t.Error("tuint was not found")
247 }
248 if x.(uint) != 3 {
249 t.Error("tuint is not 3:", x)
250 }
251 }
252
253 func TestIncrementWithUintptr(t *testing.T) {
254 tc := New(DefaultExpiration, 0)
255 tc.Set("tuintptr", uintptr(1), DefaultExpiration)
256 err := tc.Increment("tuintptr", 2)
257 if err != nil {
258 t.Error("Error incrementing:", err)
259 }
260
261 x, found := tc.Get("tuintptr")
262 if !found {
263 t.Error("tuintptr was not found")
264 }
265 if x.(uintptr) != 3 {
266 t.Error("tuintptr is not 3:", x)
267 }
268 }
269
270 func TestIncrementWithUint8(t *testing.T) {
271 tc := New(DefaultExpiration, 0)
272 tc.Set("tuint8", uint8(1), DefaultExpiration)
273 err := tc.Increment("tuint8", 2)
274 if err != nil {
275 t.Error("Error incrementing:", err)
276 }
277 x, found := tc.Get("tuint8")
278 if !found {
279 t.Error("tuint8 was not found")
280 }
281 if x.(uint8) != 3 {
282 t.Error("tuint8 is not 3:", x)
283 }
284 }
285
286 func TestIncrementWithUint16(t *testing.T) {
287 tc := New(DefaultExpiration, 0)
288 tc.Set("tuint16", uint16(1), DefaultExpiration)
289 err := tc.Increment("tuint16", 2)
290 if err != nil {
291 t.Error("Error incrementing:", err)
292 }
293
294 x, found := tc.Get("tuint16")
295 if !found {
296 t.Error("tuint16 was not found")
297 }
298 if x.(uint16) != 3 {
299 t.Error("tuint16 is not 3:", x)
300 }
301 }
302
303 func TestIncrementWithUint32(t *testing.T) {
304 tc := New(DefaultExpiration, 0)
305 tc.Set("tuint32", uint32(1), DefaultExpiration)
306 err := tc.Increment("tuint32", 2)
307 if err != nil {
308 t.Error("Error incrementing:", err)
309 }
310 x, found := tc.Get("tuint32")
311 if !found {
312 t.Error("tuint32 was not found")
313 }
314 if x.(uint32) != 3 {
315 t.Error("tuint32 is not 3:", x)
316 }
317 }
318
319 func TestIncrementWithUint64(t *testing.T) {
320 tc := New(DefaultExpiration, 0)
321 tc.Set("tuint64", uint64(1), DefaultExpiration)
322 err := tc.Increment("tuint64", 2)
323 if err != nil {
324 t.Error("Error incrementing:", err)
325 }
326
327 x, found := tc.Get("tuint64")
328 if !found {
329 t.Error("tuint64 was not found")
330 }
331 if x.(uint64) != 3 {
332 t.Error("tuint64 is not 3:", x)
333 }
334 }
335
336 func TestIncrementWithFloat32(t *testing.T) {
337 tc := New(DefaultExpiration, 0)
338 tc.Set("float32", float32(1.5), DefaultExpiration)
339 err := tc.Increment("float32", 2)
340 if err != nil {
341 t.Error("Error incrementing:", err)
342 }
343 x, found := tc.Get("float32")
344 if !found {
345 t.Error("float32 was not found")
346 }
347 if x.(float32) != 3.5 {
348 t.Error("float32 is not 3.5:", x)
349 }
350 }
351
352 func TestIncrementWithFloat64(t *testing.T) {
353 tc := New(DefaultExpiration, 0)
354 tc.Set("float64", float64(1.5), DefaultExpiration)
355 err := tc.Increment("float64", 2)
356 if err != nil {
357 t.Error("Error incrementing:", err)
358 }
359 x, found := tc.Get("float64")
360 if !found {
361 t.Error("float64 was not found")
362 }
363 if x.(float64) != 3.5 {
364 t.Error("float64 is not 3.5:", x)
365 }
366 }
367
368 func TestIncrementFloatWithFloat32(t *testing.T) {
369 tc := New(DefaultExpiration, 0)
370 tc.Set("float32", float32(1.5), DefaultExpiration)
371 err := tc.IncrementFloat("float32", 2)
372 if err != nil {
373 t.Error("Error incrementfloating:", err)
374 }
375 x, found := tc.Get("float32")
376 if !found {
377 t.Error("float32 was not found")
378 }
379 if x.(float32) != 3.5 {
380 t.Error("float32 is not 3.5:", x)
381 }
382 }
383
384 func TestIncrementFloatWithFloat64(t *testing.T) {
385 tc := New(DefaultExpiration, 0)
386 tc.Set("float64", float64(1.5), DefaultExpiration)
387 err := tc.IncrementFloat("float64", 2)
388 if err != nil {
389 t.Error("Error incrementfloating:", err)
390 }
391 x, found := tc.Get("float64")
392 if !found {
393 t.Error("float64 was not found")
394 }
395 if x.(float64) != 3.5 {
396 t.Error("float64 is not 3.5:", x)
397 }
398 }
399
400 func TestDecrementWithInt(t *testing.T) {
401 tc := New(DefaultExpiration, 0)
402 tc.Set("int", int(5), DefaultExpiration)
403 err := tc.Decrement("int", 2)
404 if err != nil {
405 t.Error("Error decrementing:", err)
406 }
407 x, found := tc.Get("int")
408 if !found {
409 t.Error("int was not found")
410 }
411 if x.(int) != 3 {
412 t.Error("int is not 3:", x)
413 }
414 }
415
416 func TestDecrementWithInt8(t *testing.T) {
417 tc := New(DefaultExpiration, 0)
418 tc.Set("int8", int8(5), DefaultExpiration)
419 err := tc.Decrement("int8", 2)
420 if err != nil {
421 t.Error("Error decrementing:", err)
422 }
423 x, found := tc.Get("int8")
424 if !found {
425 t.Error("int8 was not found")
426 }
427 if x.(int8) != 3 {
428 t.Error("int8 is not 3:", x)
429 }
430 }
431
432 func TestDecrementWithInt16(t *testing.T) {
433 tc := New(DefaultExpiration, 0)
434 tc.Set("int16", int16(5), DefaultExpiration)
435 err := tc.Decrement("int16", 2)
436 if err != nil {
437 t.Error("Error decrementing:", err)
438 }
439 x, found := tc.Get("int16")
440 if !found {
441 t.Error("int16 was not found")
442 }
443 if x.(int16) != 3 {
444 t.Error("int16 is not 3:", x)
445 }
446 }
447
448 func TestDecrementWithInt32(t *testing.T) {
449 tc := New(DefaultExpiration, 0)
450 tc.Set("int32", int32(5), DefaultExpiration)
451 err := tc.Decrement("int32", 2)
452 if err != nil {
453 t.Error("Error decrementing:", err)
454 }
455 x, found := tc.Get("int32")
456 if !found {
457 t.Error("int32 was not found")
458 }
459 if x.(int32) != 3 {
460 t.Error("int32 is not 3:", x)
461 }
462 }
463
464 func TestDecrementWithInt64(t *testing.T) {
465 tc := New(DefaultExpiration, 0)
466 tc.Set("int64", int64(5), DefaultExpiration)
467 err := tc.Decrement("int64", 2)
468 if err != nil {
469 t.Error("Error decrementing:", err)
470 }
471 x, found := tc.Get("int64")
472 if !found {
473 t.Error("int64 was not found")
474 }
475 if x.(int64) != 3 {
476 t.Error("int64 is not 3:", x)
477 }
478 }
479
480 func TestDecrementWithUint(t *testing.T) {
481 tc := New(DefaultExpiration, 0)
482 tc.Set("uint", uint(5), DefaultExpiration)
483 err := tc.Decrement("uint", 2)
484 if err != nil {
485 t.Error("Error decrementing:", err)
486 }
487 x, found := tc.Get("uint")
488 if !found {
489 t.Error("uint was not found")
490 }
491 if x.(uint) != 3 {
492 t.Error("uint is not 3:", x)
493 }
494 }
495
496 func TestDecrementWithUintptr(t *testing.T) {
497 tc := New(DefaultExpiration, 0)
498 tc.Set("uintptr", uintptr(5), DefaultExpiration)
499 err := tc.Decrement("uintptr", 2)
500 if err != nil {
501 t.Error("Error decrementing:", err)
502 }
503 x, found := tc.Get("uintptr")
504 if !found {
505 t.Error("uintptr was not found")
506 }
507 if x.(uintptr) != 3 {
508 t.Error("uintptr is not 3:", x)
509 }
510 }
511
512 func TestDecrementWithUint8(t *testing.T) {
513 tc := New(DefaultExpiration, 0)
514 tc.Set("uint8", uint8(5), DefaultExpiration)
515 err := tc.Decrement("uint8", 2)
516 if err != nil {
517 t.Error("Error decrementing:", err)
518 }
519 x, found := tc.Get("uint8")
520 if !found {
521 t.Error("uint8 was not found")
522 }
523 if x.(uint8) != 3 {
524 t.Error("uint8 is not 3:", x)
525 }
526 }
527
528 func TestDecrementWithUint16(t *testing.T) {
529 tc := New(DefaultExpiration, 0)
530 tc.Set("uint16", uint16(5), DefaultExpiration)
531 err := tc.Decrement("uint16", 2)
532 if err != nil {
533 t.Error("Error decrementing:", err)
534 }
535 x, found := tc.Get("uint16")
536 if !found {
537 t.Error("uint16 was not found")
538 }
539 if x.(uint16) != 3 {
540 t.Error("uint16 is not 3:", x)
541 }
542 }
543
544 func TestDecrementWithUint32(t *testing.T) {
545 tc := New(DefaultExpiration, 0)
546 tc.Set("uint32", uint32(5), DefaultExpiration)
547 err := tc.Decrement("uint32", 2)
548 if err != nil {
549 t.Error("Error decrementing:", err)
550 }
551 x, found := tc.Get("uint32")
552 if !found {
553 t.Error("uint32 was not found")
554 }
555 if x.(uint32) != 3 {
556 t.Error("uint32 is not 3:", x)
557 }
558 }
559
560 func TestDecrementWithUint64(t *testing.T) {
561 tc := New(DefaultExpiration, 0)
562 tc.Set("uint64", uint64(5), DefaultExpiration)
563 err := tc.Decrement("uint64", 2)
564 if err != nil {
565 t.Error("Error decrementing:", err)
566 }
567 x, found := tc.Get("uint64")
568 if !found {
569 t.Error("uint64 was not found")
570 }
571 if x.(uint64) != 3 {
572 t.Error("uint64 is not 3:", x)
573 }
574 }
575
576 func TestDecrementWithFloat32(t *testing.T) {
577 tc := New(DefaultExpiration, 0)
578 tc.Set("float32", float32(5.5), DefaultExpiration)
579 err := tc.Decrement("float32", 2)
580 if err != nil {
581 t.Error("Error decrementing:", err)
582 }
583 x, found := tc.Get("float32")
584 if !found {
585 t.Error("float32 was not found")
586 }
587 if x.(float32) != 3.5 {
588 t.Error("float32 is not 3:", x)
589 }
590 }
591
592 func TestDecrementWithFloat64(t *testing.T) {
593 tc := New(DefaultExpiration, 0)
594 tc.Set("float64", float64(5.5), DefaultExpiration)
595 err := tc.Decrement("float64", 2)
596 if err != nil {
597 t.Error("Error decrementing:", err)
598 }
599 x, found := tc.Get("float64")
600 if !found {
601 t.Error("float64 was not found")
602 }
603 if x.(float64) != 3.5 {
604 t.Error("float64 is not 3:", x)
605 }
606 }
607
608 func TestDecrementFloatWithFloat32(t *testing.T) {
609 tc := New(DefaultExpiration, 0)
610 tc.Set("float32", float32(5.5), DefaultExpiration)
611 err := tc.DecrementFloat("float32", 2)
612 if err != nil {
613 t.Error("Error decrementing:", err)
614 }
615 x, found := tc.Get("float32")
616 if !found {
617 t.Error("float32 was not found")
618 }
619 if x.(float32) != 3.5 {
620 t.Error("float32 is not 3:", x)
621 }
622 }
623
624 func TestDecrementFloatWithFloat64(t *testing.T) {
625 tc := New(DefaultExpiration, 0)
626 tc.Set("float64", float64(5.5), DefaultExpiration)
627 err := tc.DecrementFloat("float64", 2)
628 if err != nil {
629 t.Error("Error decrementing:", err)
630 }
631 x, found := tc.Get("float64")
632 if !found {
633 t.Error("float64 was not found")
634 }
635 if x.(float64) != 3.5 {
636 t.Error("float64 is not 3:", x)
637 }
638 }
639
640 func TestIncrementInt(t *testing.T) {
641 tc := New(DefaultExpiration, 0)
642 tc.Set("tint", 1, DefaultExpiration)
643 n, err := tc.IncrementInt("tint", 2)
644 if err != nil {
645 t.Error("Error incrementing:", err)
646 }
647 if n != 3 {
648 t.Error("Returned number is not 3:", n)
649 }
650 x, found := tc.Get("tint")
651 if !found {
652 t.Error("tint was not found")
653 }
654 if x.(int) != 3 {
655 t.Error("tint is not 3:", x)
656 }
657 }
658
659 func TestIncrementInt8(t *testing.T) {
660 tc := New(DefaultExpiration, 0)
661 tc.Set("tint8", int8(1), DefaultExpiration)
662 n, err := tc.IncrementInt8("tint8", 2)
663 if err != nil {
664 t.Error("Error incrementing:", err)
665 }
666 if n != 3 {
667 t.Error("Returned number is not 3:", n)
668 }
669 x, found := tc.Get("tint8")
670 if !found {
671 t.Error("tint8 was not found")
672 }
673 if x.(int8) != 3 {
674 t.Error("tint8 is not 3:", x)
675 }
676 }
677
678 func TestIncrementInt16(t *testing.T) {
679 tc := New(DefaultExpiration, 0)
680 tc.Set("tint16", int16(1), DefaultExpiration)
681 n, err := tc.IncrementInt16("tint16", 2)
682 if err != nil {
683 t.Error("Error incrementing:", err)
684 }
685 if n != 3 {
686 t.Error("Returned number is not 3:", n)
687 }
688 x, found := tc.Get("tint16")
689 if !found {
690 t.Error("tint16 was not found")
691 }
692 if x.(int16) != 3 {
693 t.Error("tint16 is not 3:", x)
694 }
695 }
696
697 func TestIncrementInt32(t *testing.T) {
698 tc := New(DefaultExpiration, 0)
699 tc.Set("tint32", int32(1), DefaultExpiration)
700 n, err := tc.IncrementInt32("tint32", 2)
701 if err != nil {
702 t.Error("Error incrementing:", err)
703 }
704 if n != 3 {
705 t.Error("Returned number is not 3:", n)
706 }
707 x, found := tc.Get("tint32")
708 if !found {
709 t.Error("tint32 was not found")
710 }
711 if x.(int32) != 3 {
712 t.Error("tint32 is not 3:", x)
713 }
714 }
715
716 func TestIncrementInt64(t *testing.T) {
717 tc := New(DefaultExpiration, 0)
718 tc.Set("tint64", int64(1), DefaultExpiration)
719 n, err := tc.IncrementInt64("tint64", 2)
720 if err != nil {
721 t.Error("Error incrementing:", err)
722 }
723 if n != 3 {
724 t.Error("Returned number is not 3:", n)
725 }
726 x, found := tc.Get("tint64")
727 if !found {
728 t.Error("tint64 was not found")
729 }
730 if x.(int64) != 3 {
731 t.Error("tint64 is not 3:", x)
732 }
733 }
734
735 func TestIncrementUint(t *testing.T) {
736 tc := New(DefaultExpiration, 0)
737 tc.Set("tuint", uint(1), DefaultExpiration)
738 n, err := tc.IncrementUint("tuint", 2)
739 if err != nil {
740 t.Error("Error incrementing:", err)
741 }
742 if n != 3 {
743 t.Error("Returned number is not 3:", n)
744 }
745 x, found := tc.Get("tuint")
746 if !found {
747 t.Error("tuint was not found")
748 }
749 if x.(uint) != 3 {
750 t.Error("tuint is not 3:", x)
751 }
752 }
753
754 func TestIncrementUintptr(t *testing.T) {
755 tc := New(DefaultExpiration, 0)
756 tc.Set("tuintptr", uintptr(1), DefaultExpiration)
757 n, err := tc.IncrementUintptr("tuintptr", 2)
758 if err != nil {
759 t.Error("Error incrementing:", err)
760 }
761 if n != 3 {
762 t.Error("Returned number is not 3:", n)
763 }
764 x, found := tc.Get("tuintptr")
765 if !found {
766 t.Error("tuintptr was not found")
767 }
768 if x.(uintptr) != 3 {
769 t.Error("tuintptr is not 3:", x)
770 }
771 }
772
773 func TestIncrementUint8(t *testing.T) {
774 tc := New(DefaultExpiration, 0)
775 tc.Set("tuint8", uint8(1), DefaultExpiration)
776 n, err := tc.IncrementUint8("tuint8", 2)
777 if err != nil {
778 t.Error("Error incrementing:", err)
779 }
780 if n != 3 {
781 t.Error("Returned number is not 3:", n)
782 }
783 x, found := tc.Get("tuint8")
784 if !found {
785 t.Error("tuint8 was not found")
786 }
787 if x.(uint8) != 3 {
788 t.Error("tuint8 is not 3:", x)
789 }
790 }
791
792 func TestIncrementUint16(t *testing.T) {
793 tc := New(DefaultExpiration, 0)
794 tc.Set("tuint16", uint16(1), DefaultExpiration)
795 n, err := tc.IncrementUint16("tuint16", 2)
796 if err != nil {
797 t.Error("Error incrementing:", err)
798 }
799 if n != 3 {
800 t.Error("Returned number is not 3:", n)
801 }
802 x, found := tc.Get("tuint16")
803 if !found {
804 t.Error("tuint16 was not found")
805 }
806 if x.(uint16) != 3 {
807 t.Error("tuint16 is not 3:", x)
808 }
809 }
810
811 func TestIncrementUint32(t *testing.T) {
812 tc := New(DefaultExpiration, 0)
813 tc.Set("tuint32", uint32(1), DefaultExpiration)
814 n, err := tc.IncrementUint32("tuint32", 2)
815 if err != nil {
816 t.Error("Error incrementing:", err)
817 }
818 if n != 3 {
819 t.Error("Returned number is not 3:", n)
820 }
821 x, found := tc.Get("tuint32")
822 if !found {
823 t.Error("tuint32 was not found")
824 }
825 if x.(uint32) != 3 {
826 t.Error("tuint32 is not 3:", x)
827 }
828 }
829
830 func TestIncrementUint64(t *testing.T) {
831 tc := New(DefaultExpiration, 0)
832 tc.Set("tuint64", uint64(1), DefaultExpiration)
833 n, err := tc.IncrementUint64("tuint64", 2)
834 if err != nil {
835 t.Error("Error incrementing:", err)
836 }
837 if n != 3 {
838 t.Error("Returned number is not 3:", n)
839 }
840 x, found := tc.Get("tuint64")
841 if !found {
842 t.Error("tuint64 was not found")
843 }
844 if x.(uint64) != 3 {
845 t.Error("tuint64 is not 3:", x)
846 }
847 }
848
849 func TestIncrementFloat32(t *testing.T) {
850 tc := New(DefaultExpiration, 0)
851 tc.Set("float32", float32(1.5), DefaultExpiration)
852 n, err := tc.IncrementFloat32("float32", 2)
853 if err != nil {
854 t.Error("Error incrementing:", err)
855 }
856 if n != 3.5 {
857 t.Error("Returned number is not 3.5:", n)
858 }
859 x, found := tc.Get("float32")
860 if !found {
861 t.Error("float32 was not found")
862 }
863 if x.(float32) != 3.5 {
864 t.Error("float32 is not 3.5:", x)
865 }
866 }
867
868 func TestIncrementFloat64(t *testing.T) {
869 tc := New(DefaultExpiration, 0)
870 tc.Set("float64", float64(1.5), DefaultExpiration)
871 n, err := tc.IncrementFloat64("float64", 2)
872 if err != nil {
873 t.Error("Error incrementing:", err)
874 }
875 if n != 3.5 {
876 t.Error("Returned number is not 3.5:", n)
877 }
878 x, found := tc.Get("float64")
879 if !found {
880 t.Error("float64 was not found")
881 }
882 if x.(float64) != 3.5 {
883 t.Error("float64 is not 3.5:", x)
884 }
885 }
886
887 func TestDecrementInt8(t *testing.T) {
888 tc := New(DefaultExpiration, 0)
889 tc.Set("int8", int8(5), DefaultExpiration)
890 n, err := tc.DecrementInt8("int8", 2)
891 if err != nil {
892 t.Error("Error decrementing:", err)
893 }
894 if n != 3 {
895 t.Error("Returned number is not 3:", n)
896 }
897 x, found := tc.Get("int8")
898 if !found {
899 t.Error("int8 was not found")
900 }
901 if x.(int8) != 3 {
902 t.Error("int8 is not 3:", x)
903 }
904 }
905
906 func TestDecrementInt16(t *testing.T) {
907 tc := New(DefaultExpiration, 0)
908 tc.Set("int16", int16(5), DefaultExpiration)
909 n, err := tc.DecrementInt16("int16", 2)
910 if err != nil {
911 t.Error("Error decrementing:", err)
912 }
913 if n != 3 {
914 t.Error("Returned number is not 3:", n)
915 }
916 x, found := tc.Get("int16")
917 if !found {
918 t.Error("int16 was not found")
919 }
920 if x.(int16) != 3 {
921 t.Error("int16 is not 3:", x)
922 }
923 }
924
925 func TestDecrementInt32(t *testing.T) {
926 tc := New(DefaultExpiration, 0)
927 tc.Set("int32", int32(5), DefaultExpiration)
928 n, err := tc.DecrementInt32("int32", 2)
929 if err != nil {
930 t.Error("Error decrementing:", err)
931 }
932 if n != 3 {
933 t.Error("Returned number is not 3:", n)
934 }
935 x, found := tc.Get("int32")
936 if !found {
937 t.Error("int32 was not found")
938 }
939 if x.(int32) != 3 {
940 t.Error("int32 is not 3:", x)
941 }
942 }
943
944 func TestDecrementInt64(t *testing.T) {
945 tc := New(DefaultExpiration, 0)
946 tc.Set("int64", int64(5), DefaultExpiration)
947 n, err := tc.DecrementInt64("int64", 2)
948 if err != nil {
949 t.Error("Error decrementing:", err)
950 }
951 if n != 3 {
952 t.Error("Returned number is not 3:", n)
953 }
954 x, found := tc.Get("int64")
955 if !found {
956 t.Error("int64 was not found")
957 }
958 if x.(int64) != 3 {
959 t.Error("int64 is not 3:", x)
960 }
961 }
962
963 func TestDecrementUint(t *testing.T) {
964 tc := New(DefaultExpiration, 0)
965 tc.Set("uint", uint(5), DefaultExpiration)
966 n, err := tc.DecrementUint("uint", 2)
967 if err != nil {
968 t.Error("Error decrementing:", err)
969 }
970 if n != 3 {
971 t.Error("Returned number is not 3:", n)
972 }
973 x, found := tc.Get("uint")
974 if !found {
975 t.Error("uint was not found")
976 }
977 if x.(uint) != 3 {
978 t.Error("uint is not 3:", x)
979 }
980 }
981
982 func TestDecrementUintptr(t *testing.T) {
983 tc := New(DefaultExpiration, 0)
984 tc.Set("uintptr", uintptr(5), DefaultExpiration)
985 n, err := tc.DecrementUintptr("uintptr", 2)
986 if err != nil {
987 t.Error("Error decrementing:", err)
988 }
989 if n != 3 {
990 t.Error("Returned number is not 3:", n)
991 }
992 x, found := tc.Get("uintptr")
993 if !found {
994 t.Error("uintptr was not found")
995 }
996 if x.(uintptr) != 3 {
997 t.Error("uintptr is not 3:", x)
998 }
999 }
1000
1001 func TestDecrementUint8(t *testing.T) {
1002 tc := New(DefaultExpiration, 0)
1003 tc.Set("uint8", uint8(5), DefaultExpiration)
1004 n, err := tc.DecrementUint8("uint8", 2)
1005 if err != nil {
1006 t.Error("Error decrementing:", err)
1007 }
1008 if n != 3 {
1009 t.Error("Returned number is not 3:", n)
1010 }
1011 x, found := tc.Get("uint8")
1012 if !found {
1013 t.Error("uint8 was not found")
1014 }
1015 if x.(uint8) != 3 {
1016 t.Error("uint8 is not 3:", x)
1017 }
1018 }
1019
1020 func TestDecrementUint16(t *testing.T) {
1021 tc := New(DefaultExpiration, 0)
1022 tc.Set("uint16", uint16(5), DefaultExpiration)
1023 n, err := tc.DecrementUint16("uint16", 2)
1024 if err != nil {
1025 t.Error("Error decrementing:", err)
1026 }
1027 if n != 3 {
1028 t.Error("Returned number is not 3:", n)
1029 }
1030 x, found := tc.Get("uint16")
1031 if !found {
1032 t.Error("uint16 was not found")
1033 }
1034 if x.(uint16) != 3 {
1035 t.Error("uint16 is not 3:", x)
1036 }
1037 }
1038
1039 func TestDecrementUint32(t *testing.T) {
1040 tc := New(DefaultExpiration, 0)
1041 tc.Set("uint32", uint32(5), DefaultExpiration)
1042 n, err := tc.DecrementUint32("uint32", 2)
1043 if err != nil {
1044 t.Error("Error decrementing:", err)
1045 }
1046 if n != 3 {
1047 t.Error("Returned number is not 3:", n)
1048 }
1049 x, found := tc.Get("uint32")
1050 if !found {
1051 t.Error("uint32 was not found")
1052 }
1053 if x.(uint32) != 3 {
1054 t.Error("uint32 is not 3:", x)
1055 }
1056 }
1057
1058 func TestDecrementUint64(t *testing.T) {
1059 tc := New(DefaultExpiration, 0)
1060 tc.Set("uint64", uint64(5), DefaultExpiration)
1061 n, err := tc.DecrementUint64("uint64", 2)
1062 if err != nil {
1063 t.Error("Error decrementing:", err)
1064 }
1065 if n != 3 {
1066 t.Error("Returned number is not 3:", n)
1067 }
1068 x, found := tc.Get("uint64")
1069 if !found {
1070 t.Error("uint64 was not found")
1071 }
1072 if x.(uint64) != 3 {
1073 t.Error("uint64 is not 3:", x)
1074 }
1075 }
1076
1077 func TestDecrementFloat32(t *testing.T) {
1078 tc := New(DefaultExpiration, 0)
1079 tc.Set("float32", float32(5), DefaultExpiration)
1080 n, err := tc.DecrementFloat32("float32", 2)
1081 if err != nil {
1082 t.Error("Error decrementing:", err)
1083 }
1084 if n != 3 {
1085 t.Error("Returned number is not 3:", n)
1086 }
1087 x, found := tc.Get("float32")
1088 if !found {
1089 t.Error("float32 was not found")
1090 }
1091 if x.(float32) != 3 {
1092 t.Error("float32 is not 3:", x)
1093 }
1094 }
1095
1096 func TestDecrementFloat64(t *testing.T) {
1097 tc := New(DefaultExpiration, 0)
1098 tc.Set("float64", float64(5), DefaultExpiration)
1099 n, err := tc.DecrementFloat64("float64", 2)
1100 if err != nil {
1101 t.Error("Error decrementing:", err)
1102 }
1103 if n != 3 {
1104 t.Error("Returned number is not 3:", n)
1105 }
1106 x, found := tc.Get("float64")
1107 if !found {
1108 t.Error("float64 was not found")
1109 }
1110 if x.(float64) != 3 {
1111 t.Error("float64 is not 3:", x)
1112 }
1113 }
1114
1115 func TestAdd(t *testing.T) {
1116 tc := New(DefaultExpiration, 0)
1117 err := tc.Add("foo", "bar", DefaultExpiration)
1118 if err != nil {
1119 t.Error("Couldn't add foo even though it shouldn't exist")
1120 }
1121 err = tc.Add("foo", "baz", DefaultExpiration)
1122 if err == nil {
1123 t.Error("Successfully added another foo when it should have returned an error")
1124 }
1125 }
1126
1127 func TestReplace(t *testing.T) {
1128 tc := New(DefaultExpiration, 0)
1129 err := tc.Replace("foo", "bar", DefaultExpiration)
1130 if err == nil {
1131 t.Error("Replaced foo when it shouldn't exist")
1132 }
1133 tc.Set("foo", "bar", DefaultExpiration)
1134 err = tc.Replace("foo", "bar", DefaultExpiration)
1135 if err != nil {
1136 t.Error("Couldn't replace existing key foo")
1137 }
1138 }
1139
1140 func TestDelete(t *testing.T) {
1141 tc := New(DefaultExpiration, 0)
1142 tc.Set("foo", "bar", DefaultExpiration)
1143 tc.Delete("foo")
1144 x, found := tc.Get("foo")
1145 if found {
1146 t.Error("foo was found, but it should have been deleted")
1147 }
1148 if x != nil {
1149 t.Error("x is not nil:", x)
1150 }
1151 }
1152
1153 func TestItemCount(t *testing.T) {
1154 tc := New(DefaultExpiration, 0)
1155 tc.Set("foo", "1", DefaultExpiration)
1156 tc.Set("bar", "2", DefaultExpiration)
1157 tc.Set("baz", "3", DefaultExpiration)
1158 if n := tc.ItemCount(); n != 3 {
1159 t.Errorf("Item count is not 3: %d", n)
1160 }
1161 }
1162
1163 func TestFlush(t *testing.T) {
1164 tc := New(DefaultExpiration, 0)
1165 tc.Set("foo", "bar", DefaultExpiration)
1166 tc.Set("baz", "yes", DefaultExpiration)
1167 tc.Flush()
1168 x, found := tc.Get("foo")
1169 if found {
1170 t.Error("foo was found, but it should have been deleted")
1171 }
1172 if x != nil {
1173 t.Error("x is not nil:", x)
1174 }
1175 x, found = tc.Get("baz")
1176 if found {
1177 t.Error("baz was found, but it should have been deleted")
1178 }
1179 if x != nil {
1180 t.Error("x is not nil:", x)
1181 }
1182 }
1183
1184 func TestIncrementOverflowInt(t *testing.T) {
1185 tc := New(DefaultExpiration, 0)
1186 tc.Set("int8", int8(127), DefaultExpiration)
1187 err := tc.Increment("int8", 1)
1188 if err != nil {
1189 t.Error("Error incrementing int8:", err)
1190 }
1191 x, _ := tc.Get("int8")
1192 int8 := x.(int8)
1193 if int8 != -128 {
1194 t.Error("int8 did not overflow as expected; value:", int8)
1195 }
1196
1197 }
1198
1199 func TestIncrementOverflowUint(t *testing.T) {
1200 tc := New(DefaultExpiration, 0)
1201 tc.Set("uint8", uint8(255), DefaultExpiration)
1202 err := tc.Increment("uint8", 1)
1203 if err != nil {
1204 t.Error("Error incrementing int8:", err)
1205 }
1206 x, _ := tc.Get("uint8")
1207 uint8 := x.(uint8)
1208 if uint8 != 0 {
1209 t.Error("uint8 did not overflow as expected; value:", uint8)
1210 }
1211 }
1212
1213 func TestDecrementUnderflowUint(t *testing.T) {
1214 tc := New(DefaultExpiration, 0)
1215 tc.Set("uint8", uint8(0), DefaultExpiration)
1216 err := tc.Decrement("uint8", 1)
1217 if err != nil {
1218 t.Error("Error decrementing int8:", err)
1219 }
1220 x, _ := tc.Get("uint8")
1221 uint8 := x.(uint8)
1222 if uint8 != 255 {
1223 t.Error("uint8 did not underflow as expected; value:", uint8)
1224 }
1225 }
1226
1227 func TestOnEvicted(t *testing.T) {
1228 tc := New(DefaultExpiration, 0)
1229 tc.Set("foo", 3, DefaultExpiration)
1230 if tc.onEvicted != nil {
1231 t.Fatal("tc.onEvicted is not nil")
1232 }
1233 works := false
1234 tc.OnEvicted(func(k string, v interface{}) {
1235 if k == "foo" && v.(int) == 3 {
1236 works = true
1237 }
1238 tc.Set("bar", 4, DefaultExpiration)
1239 })
1240 tc.Delete("foo")
1241 x, _ := tc.Get("bar")
1242 if !works {
1243 t.Error("works bool not true")
1244 }
1245 if x.(int) != 4 {
1246 t.Error("bar was not 4")
1247 }
1248 }
1249
1250 func TestCacheSerialization(t *testing.T) {
1251 tc := New(DefaultExpiration, 0)
1252 testFillAndSerialize(t, tc)
1253
1254
1255
1256 testFillAndSerialize(t, tc)
1257 }
1258
1259 func testFillAndSerialize(t *testing.T, tc *Cache) {
1260 tc.Set("a", "a", DefaultExpiration)
1261 tc.Set("b", "b", DefaultExpiration)
1262 tc.Set("c", "c", DefaultExpiration)
1263 tc.Set("expired", "foo", 1*time.Millisecond)
1264 tc.Set("*struct", &TestStruct{Num: 1}, DefaultExpiration)
1265 tc.Set("[]struct", []TestStruct{
1266 {Num: 2},
1267 {Num: 3},
1268 }, DefaultExpiration)
1269 tc.Set("[]*struct", []*TestStruct{
1270 &TestStruct{Num: 4},
1271 &TestStruct{Num: 5},
1272 }, DefaultExpiration)
1273 tc.Set("structception", &TestStruct{
1274 Num: 42,
1275 Children: []*TestStruct{
1276 &TestStruct{Num: 6174},
1277 &TestStruct{Num: 4716},
1278 },
1279 }, DefaultExpiration)
1280
1281 fp := &bytes.Buffer{}
1282 err := tc.Save(fp)
1283 if err != nil {
1284 t.Fatal("Couldn't save cache to fp:", err)
1285 }
1286
1287 oc := New(DefaultExpiration, 0)
1288 err = oc.Load(fp)
1289 if err != nil {
1290 t.Fatal("Couldn't load cache from fp:", err)
1291 }
1292
1293 a, found := oc.Get("a")
1294 if !found {
1295 t.Error("a was not found")
1296 }
1297 if a.(string) != "a" {
1298 t.Error("a is not a")
1299 }
1300
1301 b, found := oc.Get("b")
1302 if !found {
1303 t.Error("b was not found")
1304 }
1305 if b.(string) != "b" {
1306 t.Error("b is not b")
1307 }
1308
1309 c, found := oc.Get("c")
1310 if !found {
1311 t.Error("c was not found")
1312 }
1313 if c.(string) != "c" {
1314 t.Error("c is not c")
1315 }
1316
1317 <-time.After(5 * time.Millisecond)
1318 _, found = oc.Get("expired")
1319 if found {
1320 t.Error("expired was found")
1321 }
1322
1323 s1, found := oc.Get("*struct")
1324 if !found {
1325 t.Error("*struct was not found")
1326 }
1327 if s1.(*TestStruct).Num != 1 {
1328 t.Error("*struct.Num is not 1")
1329 }
1330
1331 s2, found := oc.Get("[]struct")
1332 if !found {
1333 t.Error("[]struct was not found")
1334 }
1335 s2r := s2.([]TestStruct)
1336 if len(s2r) != 2 {
1337 t.Error("Length of s2r is not 2")
1338 }
1339 if s2r[0].Num != 2 {
1340 t.Error("s2r[0].Num is not 2")
1341 }
1342 if s2r[1].Num != 3 {
1343 t.Error("s2r[1].Num is not 3")
1344 }
1345
1346 s3, found := oc.get("[]*struct")
1347 if !found {
1348 t.Error("[]*struct was not found")
1349 }
1350 s3r := s3.([]*TestStruct)
1351 if len(s3r) != 2 {
1352 t.Error("Length of s3r is not 2")
1353 }
1354 if s3r[0].Num != 4 {
1355 t.Error("s3r[0].Num is not 4")
1356 }
1357 if s3r[1].Num != 5 {
1358 t.Error("s3r[1].Num is not 5")
1359 }
1360
1361 s4, found := oc.get("structception")
1362 if !found {
1363 t.Error("structception was not found")
1364 }
1365 s4r := s4.(*TestStruct)
1366 if len(s4r.Children) != 2 {
1367 t.Error("Length of s4r.Children is not 2")
1368 }
1369 if s4r.Children[0].Num != 6174 {
1370 t.Error("s4r.Children[0].Num is not 6174")
1371 }
1372 if s4r.Children[1].Num != 4716 {
1373 t.Error("s4r.Children[1].Num is not 4716")
1374 }
1375 }
1376
1377 func TestFileSerialization(t *testing.T) {
1378 tc := New(DefaultExpiration, 0)
1379 tc.Add("a", "a", DefaultExpiration)
1380 tc.Add("b", "b", DefaultExpiration)
1381 f, err := ioutil.TempFile("", "go-cache-cache.dat")
1382 if err != nil {
1383 t.Fatal("Couldn't create cache file:", err)
1384 }
1385 fname := f.Name()
1386 f.Close()
1387 tc.SaveFile(fname)
1388
1389 oc := New(DefaultExpiration, 0)
1390 oc.Add("a", "aa", 0)
1391 err = oc.LoadFile(fname)
1392 if err != nil {
1393 t.Error(err)
1394 }
1395 a, found := oc.Get("a")
1396 if !found {
1397 t.Error("a was not found")
1398 }
1399 astr := a.(string)
1400 if astr != "aa" {
1401 if astr == "a" {
1402 t.Error("a was overwritten")
1403 } else {
1404 t.Error("a is not aa")
1405 }
1406 }
1407 b, found := oc.Get("b")
1408 if !found {
1409 t.Error("b was not found")
1410 }
1411 if b.(string) != "b" {
1412 t.Error("b is not b")
1413 }
1414 }
1415
1416 func TestSerializeUnserializable(t *testing.T) {
1417 tc := New(DefaultExpiration, 0)
1418 ch := make(chan bool, 1)
1419 ch <- true
1420 tc.Set("chan", ch, DefaultExpiration)
1421 fp := &bytes.Buffer{}
1422 err := tc.Save(fp)
1423 if err.Error() != "gob NewTypeObject can't handle type: chan bool" {
1424 t.Error("Error from Save was not gob NewTypeObject can't handle type chan bool:", err)
1425 }
1426 }
1427
1428 func BenchmarkCacheGetExpiring(b *testing.B) {
1429 benchmarkCacheGet(b, 5*time.Minute)
1430 }
1431
1432 func BenchmarkCacheGetNotExpiring(b *testing.B) {
1433 benchmarkCacheGet(b, NoExpiration)
1434 }
1435
1436 func benchmarkCacheGet(b *testing.B, exp time.Duration) {
1437 b.StopTimer()
1438 tc := New(exp, 0)
1439 tc.Set("foo", "bar", DefaultExpiration)
1440 b.StartTimer()
1441 for i := 0; i < b.N; i++ {
1442 tc.Get("foo")
1443 }
1444 }
1445
1446 func BenchmarkRWMutexMapGet(b *testing.B) {
1447 b.StopTimer()
1448 m := map[string]string{
1449 "foo": "bar",
1450 }
1451 mu := sync.RWMutex{}
1452 b.StartTimer()
1453 for i := 0; i < b.N; i++ {
1454 mu.RLock()
1455 _, _ = m["foo"]
1456 mu.RUnlock()
1457 }
1458 }
1459
1460 func BenchmarkRWMutexInterfaceMapGetStruct(b *testing.B) {
1461 b.StopTimer()
1462 s := struct{ name string }{name: "foo"}
1463 m := map[interface{}]string{
1464 s: "bar",
1465 }
1466 mu := sync.RWMutex{}
1467 b.StartTimer()
1468 for i := 0; i < b.N; i++ {
1469 mu.RLock()
1470 _, _ = m[s]
1471 mu.RUnlock()
1472 }
1473 }
1474
1475 func BenchmarkRWMutexInterfaceMapGetString(b *testing.B) {
1476 b.StopTimer()
1477 m := map[interface{}]string{
1478 "foo": "bar",
1479 }
1480 mu := sync.RWMutex{}
1481 b.StartTimer()
1482 for i := 0; i < b.N; i++ {
1483 mu.RLock()
1484 _, _ = m["foo"]
1485 mu.RUnlock()
1486 }
1487 }
1488
1489 func BenchmarkCacheGetConcurrentExpiring(b *testing.B) {
1490 benchmarkCacheGetConcurrent(b, 5*time.Minute)
1491 }
1492
1493 func BenchmarkCacheGetConcurrentNotExpiring(b *testing.B) {
1494 benchmarkCacheGetConcurrent(b, NoExpiration)
1495 }
1496
1497 func benchmarkCacheGetConcurrent(b *testing.B, exp time.Duration) {
1498 b.StopTimer()
1499 tc := New(exp, 0)
1500 tc.Set("foo", "bar", DefaultExpiration)
1501 wg := new(sync.WaitGroup)
1502 workers := runtime.NumCPU()
1503 each := b.N / workers
1504 wg.Add(workers)
1505 b.StartTimer()
1506 for i := 0; i < workers; i++ {
1507 go func() {
1508 for j := 0; j < each; j++ {
1509 tc.Get("foo")
1510 }
1511 wg.Done()
1512 }()
1513 }
1514 wg.Wait()
1515 }
1516
1517 func BenchmarkRWMutexMapGetConcurrent(b *testing.B) {
1518 b.StopTimer()
1519 m := map[string]string{
1520 "foo": "bar",
1521 }
1522 mu := sync.RWMutex{}
1523 wg := new(sync.WaitGroup)
1524 workers := runtime.NumCPU()
1525 each := b.N / workers
1526 wg.Add(workers)
1527 b.StartTimer()
1528 for i := 0; i < workers; i++ {
1529 go func() {
1530 for j := 0; j < each; j++ {
1531 mu.RLock()
1532 _, _ = m["foo"]
1533 mu.RUnlock()
1534 }
1535 wg.Done()
1536 }()
1537 }
1538 wg.Wait()
1539 }
1540
1541 func BenchmarkCacheGetManyConcurrentExpiring(b *testing.B) {
1542 benchmarkCacheGetManyConcurrent(b, 5*time.Minute)
1543 }
1544
1545 func BenchmarkCacheGetManyConcurrentNotExpiring(b *testing.B) {
1546 benchmarkCacheGetManyConcurrent(b, NoExpiration)
1547 }
1548
1549 func benchmarkCacheGetManyConcurrent(b *testing.B, exp time.Duration) {
1550
1551
1552
1553 b.StopTimer()
1554 n := 10000
1555 tc := New(exp, 0)
1556 keys := make([]string, n)
1557 for i := 0; i < n; i++ {
1558 k := "foo" + strconv.Itoa(n)
1559 keys[i] = k
1560 tc.Set(k, "bar", DefaultExpiration)
1561 }
1562 each := b.N / n
1563 wg := new(sync.WaitGroup)
1564 wg.Add(n)
1565 for _, v := range keys {
1566 go func() {
1567 for j := 0; j < each; j++ {
1568 tc.Get(v)
1569 }
1570 wg.Done()
1571 }()
1572 }
1573 b.StartTimer()
1574 wg.Wait()
1575 }
1576
1577 func BenchmarkCacheSetExpiring(b *testing.B) {
1578 benchmarkCacheSet(b, 5*time.Minute)
1579 }
1580
1581 func BenchmarkCacheSetNotExpiring(b *testing.B) {
1582 benchmarkCacheSet(b, NoExpiration)
1583 }
1584
1585 func benchmarkCacheSet(b *testing.B, exp time.Duration) {
1586 b.StopTimer()
1587 tc := New(exp, 0)
1588 b.StartTimer()
1589 for i := 0; i < b.N; i++ {
1590 tc.Set("foo", "bar", DefaultExpiration)
1591 }
1592 }
1593
1594 func BenchmarkRWMutexMapSet(b *testing.B) {
1595 b.StopTimer()
1596 m := map[string]string{}
1597 mu := sync.RWMutex{}
1598 b.StartTimer()
1599 for i := 0; i < b.N; i++ {
1600 mu.Lock()
1601 m["foo"] = "bar"
1602 mu.Unlock()
1603 }
1604 }
1605
1606 func BenchmarkCacheSetDelete(b *testing.B) {
1607 b.StopTimer()
1608 tc := New(DefaultExpiration, 0)
1609 b.StartTimer()
1610 for i := 0; i < b.N; i++ {
1611 tc.Set("foo", "bar", DefaultExpiration)
1612 tc.Delete("foo")
1613 }
1614 }
1615
1616 func BenchmarkRWMutexMapSetDelete(b *testing.B) {
1617 b.StopTimer()
1618 m := map[string]string{}
1619 mu := sync.RWMutex{}
1620 b.StartTimer()
1621 for i := 0; i < b.N; i++ {
1622 mu.Lock()
1623 m["foo"] = "bar"
1624 mu.Unlock()
1625 mu.Lock()
1626 delete(m, "foo")
1627 mu.Unlock()
1628 }
1629 }
1630
1631 func BenchmarkCacheSetDeleteSingleLock(b *testing.B) {
1632 b.StopTimer()
1633 tc := New(DefaultExpiration, 0)
1634 b.StartTimer()
1635 for i := 0; i < b.N; i++ {
1636 tc.mu.Lock()
1637 tc.set("foo", "bar", DefaultExpiration)
1638 tc.delete("foo")
1639 tc.mu.Unlock()
1640 }
1641 }
1642
1643 func BenchmarkRWMutexMapSetDeleteSingleLock(b *testing.B) {
1644 b.StopTimer()
1645 m := map[string]string{}
1646 mu := sync.RWMutex{}
1647 b.StartTimer()
1648 for i := 0; i < b.N; i++ {
1649 mu.Lock()
1650 m["foo"] = "bar"
1651 delete(m, "foo")
1652 mu.Unlock()
1653 }
1654 }
1655
1656 func BenchmarkIncrementInt(b *testing.B) {
1657 b.StopTimer()
1658 tc := New(DefaultExpiration, 0)
1659 tc.Set("foo", 0, DefaultExpiration)
1660 b.StartTimer()
1661 for i := 0; i < b.N; i++ {
1662 tc.IncrementInt("foo", 1)
1663 }
1664 }
1665
1666 func BenchmarkDeleteExpiredLoop(b *testing.B) {
1667 b.StopTimer()
1668 tc := New(5*time.Minute, 0)
1669 tc.mu.Lock()
1670 for i := 0; i < 100000; i++ {
1671 tc.set(strconv.Itoa(i), "bar", DefaultExpiration)
1672 }
1673 tc.mu.Unlock()
1674 b.StartTimer()
1675 for i := 0; i < b.N; i++ {
1676 tc.DeleteExpired()
1677 }
1678 }
1679
1680 func TestGetWithExpiration(t *testing.T) {
1681 tc := New(DefaultExpiration, 0)
1682
1683 a, expiration, found := tc.GetWithExpiration("a")
1684 if found || a != nil || !expiration.IsZero() {
1685 t.Error("Getting A found value that shouldn't exist:", a)
1686 }
1687
1688 b, expiration, found := tc.GetWithExpiration("b")
1689 if found || b != nil || !expiration.IsZero() {
1690 t.Error("Getting B found value that shouldn't exist:", b)
1691 }
1692
1693 c, expiration, found := tc.GetWithExpiration("c")
1694 if found || c != nil || !expiration.IsZero() {
1695 t.Error("Getting C found value that shouldn't exist:", c)
1696 }
1697
1698 tc.Set("a", 1, DefaultExpiration)
1699 tc.Set("b", "b", DefaultExpiration)
1700 tc.Set("c", 3.5, DefaultExpiration)
1701 tc.Set("d", 1, NoExpiration)
1702 tc.Set("e", 1, 50*time.Millisecond)
1703
1704 x, expiration, found := tc.GetWithExpiration("a")
1705 if !found {
1706 t.Error("a was not found while getting a2")
1707 }
1708 if x == nil {
1709 t.Error("x for a is nil")
1710 } else if a2 := x.(int); a2+2 != 3 {
1711 t.Error("a2 (which should be 1) plus 2 does not equal 3; value:", a2)
1712 }
1713 if !expiration.IsZero() {
1714 t.Error("expiration for a is not a zeroed time")
1715 }
1716
1717 x, expiration, found = tc.GetWithExpiration("b")
1718 if !found {
1719 t.Error("b was not found while getting b2")
1720 }
1721 if x == nil {
1722 t.Error("x for b is nil")
1723 } else if b2 := x.(string); b2+"B" != "bB" {
1724 t.Error("b2 (which should be b) plus B does not equal bB; value:", b2)
1725 }
1726 if !expiration.IsZero() {
1727 t.Error("expiration for b is not a zeroed time")
1728 }
1729
1730 x, expiration, found = tc.GetWithExpiration("c")
1731 if !found {
1732 t.Error("c was not found while getting c2")
1733 }
1734 if x == nil {
1735 t.Error("x for c is nil")
1736 } else if c2 := x.(float64); c2+1.2 != 4.7 {
1737 t.Error("c2 (which should be 3.5) plus 1.2 does not equal 4.7; value:", c2)
1738 }
1739 if !expiration.IsZero() {
1740 t.Error("expiration for c is not a zeroed time")
1741 }
1742
1743 x, expiration, found = tc.GetWithExpiration("d")
1744 if !found {
1745 t.Error("d was not found while getting d2")
1746 }
1747 if x == nil {
1748 t.Error("x for d is nil")
1749 } else if d2 := x.(int); d2+2 != 3 {
1750 t.Error("d (which should be 1) plus 2 does not equal 3; value:", d2)
1751 }
1752 if !expiration.IsZero() {
1753 t.Error("expiration for d is not a zeroed time")
1754 }
1755
1756 x, expiration, found = tc.GetWithExpiration("e")
1757 if !found {
1758 t.Error("e was not found while getting e2")
1759 }
1760 if x == nil {
1761 t.Error("x for e is nil")
1762 } else if e2 := x.(int); e2+2 != 3 {
1763 t.Error("e (which should be 1) plus 2 does not equal 3; value:", e2)
1764 }
1765 if expiration.UnixNano() != tc.items["e"].Expiration {
1766 t.Error("expiration for e is not the correct time")
1767 }
1768 if expiration.UnixNano() < time.Now().UnixNano() {
1769 t.Error("expiration for e is in the past")
1770 }
1771 }
1772
View as plain text