@@ -30,9 +30,9 @@ import (
3030 "unsafe"
3131
3232 "github.com/golang/protobuf/proto"
33-
3433 pb "github.com/mailgun/groupcache/v2/groupcachepb"
3534 "github.com/mailgun/groupcache/v2/testpb"
35+ "github.com/stretchr/testify/assert"
3636)
3737
3838var (
@@ -536,17 +536,105 @@ func TestContextDeadlineOnPeer(t *testing.T) {
536536 }
537537}
538538
539- func TestCacheRemovesBytesOfReplacedValues (t * testing.T ) {
540- c := cache {}
539+ func TestEnsureSizeReportedCorrectly (t * testing.T ) {
540+ c := & cache {}
541541
542- const key = "test"
543- keyLen := len (key )
542+ // Add the first value
543+ bv1 := ByteView {s : "first" , e : time .Now ().Add (100 * time .Second )}
544+ c .add ("key1" , bv1 )
545+ v , ok := c .get ("key1" )
544546
545- for _ , bytes := range []int {100 , 1000 , 2000 } {
546- c .add (key , ByteView {b : make ([]byte , bytes )})
547- expected := int64 (bytes + keyLen )
548- if c .nbytes != expected {
549- t .Fatalf ("%s: expected %d was %d" , t .Name (), expected , c .nbytes )
550- }
547+ // Should be len("key1" + "first") == 9
548+ assert .True (t , ok )
549+ assert .True (t , v .Equal (bv1 ))
550+ assert .Equal (t , int64 (9 ), c .bytes ())
551+
552+ // Add a second value
553+ bv2 := ByteView {s : "second" , e : time .Now ().Add (200 * time .Second )}
554+
555+ c .add ("key2" , bv2 )
556+ v , ok = c .get ("key2" )
557+
558+ // Should be len("key2" + "second") == (10 + 9) == 19
559+ assert .True (t , ok )
560+ assert .True (t , v .Equal (bv2 ))
561+ assert .Equal (t , int64 (19 ), c .bytes ())
562+
563+ // Replace the first value with a shorter value
564+ bv3 := ByteView {s : "3" , e : time .Now ().Add (200 * time .Second )}
565+
566+ c .add ("key1" , bv3 )
567+ v , ok = c .get ("key1" )
568+
569+ // len("key1" + "3") == 5
570+ // len("key2" + "second") == 10
571+ assert .True (t , ok )
572+ assert .True (t , v .Equal (bv3 ))
573+ assert .Equal (t , int64 (15 ), c .bytes ())
574+
575+ // Replace the second value with a longer value
576+ bv4 := ByteView {s : "this-string-is-28-chars-long" , e : time .Now ().Add (200 * time .Second )}
577+
578+ c .add ("key2" , bv4 )
579+ v , ok = c .get ("key2" )
580+
581+ // len("key1" + "3") == 5
582+ // len("key2" + "this-string-is-28-chars-long") == 32
583+ assert .True (t , ok )
584+ assert .True (t , v .Equal (bv4 ))
585+ assert .Equal (t , int64 (37 ), c .bytes ())
586+ }
587+
588+ func TestEnsureUpdateExpiredValue (t * testing.T ) {
589+ c := & cache {}
590+ curTime := time .Now ()
591+
592+ // Override the now function so we control time
593+ NowFunc = func () time.Time {
594+ return curTime
551595 }
596+
597+ // Expires in 1 second
598+ c .add ("key1" , ByteView {s : "value1" , e : curTime .Add (time .Second )})
599+ _ , ok := c .get ("key1" )
600+ assert .True (t , ok )
601+
602+ // Advance 1.1 seconds into the future
603+ curTime = curTime .Add (time .Millisecond * 1100 )
604+
605+ // Value should have expired
606+ _ , ok = c .get ("key1" )
607+ assert .False (t , ok )
608+
609+ // Add a new key that expires in 1 second
610+ c .add ("key2" , ByteView {s : "value2" , e : curTime .Add (time .Second )})
611+ _ , ok = c .get ("key2" )
612+ assert .True (t , ok )
613+
614+ // Advance 0.5 seconds into the future
615+ curTime = curTime .Add (time .Millisecond * 500 )
616+
617+ // Value should still exist
618+ _ , ok = c .get ("key2" )
619+ assert .True (t , ok )
620+
621+ // Replace the existing key, this should update the expired time
622+ c .add ("key2" , ByteView {s : "updated value2" , e : curTime .Add (time .Second )})
623+ _ , ok = c .get ("key2" )
624+ assert .True (t , ok )
625+
626+ // Advance 0.6 seconds into the future, which puts us past the initial
627+ // expired time for key2.
628+ curTime = curTime .Add (time .Millisecond * 600 )
629+
630+ // Should still exist
631+ _ , ok = c .get ("key2" )
632+ assert .True (t , ok )
633+
634+ // Advance 1.1 seconds into the future
635+ curTime = curTime .Add (time .Millisecond * 1100 )
636+
637+ // Should not exist
638+ _ , ok = c .get ("key2" )
639+ assert .False (t , ok )
552640}
0 commit comments