func TestHandleIncrHitBucket(t *testing.T) { namespace = randomNamespace() listener.HandleEvent(events.NewTokensServedEvent(namespace, "incr-hit", true, 1, 0)) listener.HandleEvent(events.NewTokensServedEvent(namespace, "incr-hit", true, 3, 0)) listener.HandleEvent(events.NewTokensServedEvent(namespace, "incr-hit", true, 1, 0)) scores := listener.Get(namespace, "incr-hit") if scores.Hits != 5 || scores.Misses != 0 { t.Fatalf("Bucket score was not accurate: %+v != [Hits=5, Misses=0]", scores) } }
func TestHandleIncrHitBucket(t *testing.T) { listener = stats.NewMemoryStatsListener() listener.HandleEvent(events.NewTokensServedEvent("test", "dyn", true, 1, 0)) listener.HandleEvent(events.NewTokensServedEvent("test", "dyn", true, 3, 0)) listener.HandleEvent(events.NewTokensServedEvent("test", "dyn", true, 1, 0)) scores := listener.Get("test", "dyn") if scores.Hits != 5 || scores.Misses != 0 { t.Fatalf("Bucket score was not accurate: %+v != [Hits=5, Misses=0]", scores) } }
func TestTop10Hits(t *testing.T) { namespace = randomNamespace() listener.HandleEvent(events.NewTokensServedEvent(namespace, "hits-dyn-1", true, 3, 0)) listener.HandleEvent(events.NewTokensServedEvent(namespace, "hits-dyn-2", true, 10, 0)) listener.HandleEvent(events.NewTokensServedEvent(namespace, "hits-dyn-3", true, 1, 0)) hits := listener.TopHits(namespace) correctHits := []*stats.BucketScore{ &stats.BucketScore{"hits-dyn-2", 10}, &stats.BucketScore{"hits-dyn-1", 3}, &stats.BucketScore{"hits-dyn-3", 1}} if !reflect.DeepEqual(hits, correctHits) { t.Fatalf("Hits top10 is not correct %+v", hits) } }
func TestTop10Hits(t *testing.T) { listener = stats.NewMemoryStatsListener() listener.HandleEvent(events.NewTokensServedEvent("test", "dyn-1", true, 3, 0)) listener.HandleEvent(events.NewTokensServedEvent("test", "dyn-2", true, 10, 0)) listener.HandleEvent(events.NewTokensServedEvent("test", "dyn-3", true, 1, 0)) hits := listener.TopHits("test") correctHits := []*stats.BucketScore{ &stats.BucketScore{"dyn-2", 10}, &stats.BucketScore{"dyn-1", 3}, &stats.BucketScore{"dyn-3", 1}} if !reflect.DeepEqual(hits, correctHits) { t.Fatalf("Hits top10 is not correct %+v", hits) } }
func TestHandleNewHitBucket(t *testing.T) { namespace = randomNamespace() ev := events.NewTokensServedEvent(namespace, "new-hit-dyn", true, 1, 0) listener.HandleEvent(ev) scores := listener.Get(namespace, "new-hit-dyn") if scores.Hits != 1 || scores.Misses != 0 { t.Fatalf("Bucket score was not accurate: %+v != [Hits=1, Misses=0]", scores) } ev = events.NewTokensServedEvent(namespace, "nondyn", false, 1, 0) listener.HandleEvent(ev) scores = listener.Get(namespace, "nondyn") if scores.Hits != 0 || scores.Misses != 0 { t.Fatalf("Non-dynamic bucket score was not accurate: %+v != [Hits=0, Misses=0]", scores) } scores = listener.Get(namespace, "nondyn") if scores.Hits != 0 || scores.Misses != 0 { t.Fatalf("Nonexisting namespace was not accurate: %+v != [Hits=0, Misses=0]", scores) } }
func (s *server) Allow(namespace, name string, tokensRequested int64, maxWaitMillisOverride int64, maxWaitTimeOverride bool) (time.Duration, error) { s.RLock() b, e := s.bucketContainer.FindBucket(namespace, name) s.RUnlock() if e != nil { // Attempted to create a dynamic bucket and failed. s.Emit(events.NewBucketMissedEvent(namespace, name, true)) return 0, newError("Cannot create dynamic bucket "+config.FullyQualifiedName(namespace, name), ER_TOO_MANY_BUCKETS) } if b == nil { s.Emit(events.NewBucketMissedEvent(namespace, name, false)) return 0, newError("No such bucket "+config.FullyQualifiedName(namespace, name), ER_NO_BUCKET) } if b.Config().MaxTokensPerRequest < tokensRequested && b.Config().MaxTokensPerRequest > 0 { s.Emit(events.NewTooManyTokensRequestedEvent(namespace, name, b.Dynamic(), tokensRequested)) return 0, newError(fmt.Sprintf("Too many tokens requested. Bucket %v:%v, tokensRequested=%v, maxTokensPerRequest=%v", namespace, name, tokensRequested, b.Config().MaxTokensPerRequest), ER_TOO_MANY_TOKENS_REQUESTED) } maxWaitTime := time.Millisecond if maxWaitTimeOverride && maxWaitMillisOverride < b.Config().WaitTimeoutMillis { // Use the max wait time override from the request. maxWaitTime *= time.Duration(maxWaitMillisOverride) } else { // Fall back to the max wait time configured on the bucket. maxWaitTime *= time.Duration(b.Config().WaitTimeoutMillis) } w, success := b.Take(tokensRequested, maxWaitTime) if !success { // Could not claim tokens within the given max wait time s.Emit(events.NewTimedOutEvent(namespace, name, b.Dynamic(), tokensRequested)) return 0, newError(fmt.Sprintf("Timed out waiting on %v:%v", namespace, name), ER_TIMEOUT) } // The only positive result s.Emit(events.NewTokensServedEvent(namespace, name, b.Dynamic(), tokensRequested, w)) return w, nil }