From 01eba8ee64a8da974fe1b9e9d5eb9deb46a1f5e7 Mon Sep 17 00:00:00 2001 From: "marco.ferrer" Date: Fri, 29 Oct 2021 14:42:17 -0400 Subject: [PATCH 1/2] bugfix for lifo queue nil pointer --- limiter/lifo_blocking.go | 7 +++--- limiter/lifo_blocking_test.go | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/limiter/lifo_blocking.go b/limiter/lifo_blocking.go index 320148f..5a5ed67 100644 --- a/limiter/lifo_blocking.go +++ b/limiter/lifo_blocking.go @@ -106,12 +106,13 @@ func (q *lifoQueue) remove(id uint64) { q.top.next = nil q.top.prev = nil q.top = next - q.top.id-- q.size-- return } - next.prev = prev - prev.next = cur.next + if next != nil { + next.prev = nil + } + prev.next = next q.size-- return diff --git a/limiter/lifo_blocking_test.go b/limiter/lifo_blocking_test.go index 4c6bae0..d790c86 100644 --- a/limiter/lifo_blocking_test.go +++ b/limiter/lifo_blocking_test.go @@ -82,6 +82,49 @@ func TestLifoQueue(t *testing.T) { } } +func TestLifoQueue_Remove(t *testing.T) { + t.Parallel() + asrt := assert.New(t) + q := lifoQueue{} + + asrt.Equal(uint64(0), q.len()) + size, ctx := q.peek() + asrt.Equal(uint64(0), size) + asrt.Nil(ctx) + asrt.Nil(q.pop()) + + for i := 1; i <= 10; i++ { + ctx := context.WithValue(context.Background(), testLifoQueueContextKey(i), i) + q.push(ctx) + } + + // remove last + q.remove(1) + asrt.Equal(uint64(9), q.len()) + + // remove first + q.remove(q.len()) + asrt.Equal(uint64(8), q.len()) + + // remove middle + q.remove(q.len() / 2) + asrt.Equal(uint64(7), q.len()) + + seenElements := make(map[uint64]struct{}, q.len()) + var element *lifoElement + for { + element = q.pop() + if element == nil { + break + } + _, seen := seenElements[element.id] + asrt.False(seen, "no duplicate element ids allowed") + seenElements[element.id] = struct{}{} + } + asrt.Equal(uint64(0), q.len()) + asrt.Equal(7, len(seenElements)) +} + func TestLifoBlockingListener(t *testing.T) { t.Parallel() delegateLimiter, _ := NewDefaultLimiterWithDefaults( From 13f3d7f424dae4c59f2fcb278c055ee8f882b015 Mon Sep 17 00:00:00 2001 From: "marco.ferrer" Date: Fri, 29 Oct 2021 14:51:14 -0400 Subject: [PATCH 2/2] add test for last item in queue --- limiter/lifo_blocking_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/limiter/lifo_blocking_test.go b/limiter/lifo_blocking_test.go index d790c86..527d941 100644 --- a/limiter/lifo_blocking_test.go +++ b/limiter/lifo_blocking_test.go @@ -123,6 +123,14 @@ func TestLifoQueue_Remove(t *testing.T) { } asrt.Equal(uint64(0), q.len()) asrt.Equal(7, len(seenElements)) + + q = lifoQueue{} + ctx = context.WithValue(context.Background(), testLifoQueueContextKey(1), 1) + q.push(ctx) + + // Remove very last item leaving queue empty + q.remove(1) + asrt.Equal(uint64(0), q.len()) } func TestLifoBlockingListener(t *testing.T) {