code.gitea.io/gitea@v1.22.3/modules/queue/base_test.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package queue 5 6 import ( 7 "context" 8 "fmt" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/assert" 13 ) 14 15 func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error), cfg *BaseConfig, isUnique bool) { 16 t.Run(fmt.Sprintf("testQueueBasic-%s-unique:%v", cfg.ManagedName, isUnique), func(t *testing.T) { 17 q, err := newFn(cfg) 18 assert.NoError(t, err) 19 20 ctx := context.Background() 21 _ = q.RemoveAll(ctx) 22 cnt, err := q.Len(ctx) 23 assert.NoError(t, err) 24 assert.EqualValues(t, 0, cnt) 25 26 // push the first item 27 err = q.PushItem(ctx, []byte("foo")) 28 assert.NoError(t, err) 29 30 cnt, err = q.Len(ctx) 31 assert.NoError(t, err) 32 assert.EqualValues(t, 1, cnt) 33 34 // push a duplicate item 35 err = q.PushItem(ctx, []byte("foo")) 36 if !isUnique { 37 assert.NoError(t, err) 38 } else { 39 assert.ErrorIs(t, err, ErrAlreadyInQueue) 40 } 41 42 // check the duplicate item 43 cnt, err = q.Len(ctx) 44 assert.NoError(t, err) 45 has, err := q.HasItem(ctx, []byte("foo")) 46 assert.NoError(t, err) 47 if !isUnique { 48 assert.EqualValues(t, 2, cnt) 49 assert.EqualValues(t, false, has) // non-unique queues don't check for duplicates 50 } else { 51 assert.EqualValues(t, 1, cnt) 52 assert.EqualValues(t, true, has) 53 } 54 55 // push another item 56 err = q.PushItem(ctx, []byte("bar")) 57 assert.NoError(t, err) 58 59 // pop the first item (and the duplicate if non-unique) 60 it, err := q.PopItem(ctx) 61 assert.NoError(t, err) 62 assert.EqualValues(t, "foo", string(it)) 63 64 if !isUnique { 65 it, err = q.PopItem(ctx) 66 assert.NoError(t, err) 67 assert.EqualValues(t, "foo", string(it)) 68 } 69 70 // pop another item 71 it, err = q.PopItem(ctx) 72 assert.NoError(t, err) 73 assert.EqualValues(t, "bar", string(it)) 74 75 // pop an empty queue (timeout, cancel) 76 ctxTimed, cancel := context.WithTimeout(ctx, 10*time.Millisecond) 77 it, err = q.PopItem(ctxTimed) 78 assert.ErrorIs(t, err, context.DeadlineExceeded) 79 assert.Nil(t, it) 80 cancel() 81 82 ctxTimed, cancel = context.WithTimeout(ctx, 10*time.Millisecond) 83 cancel() 84 it, err = q.PopItem(ctxTimed) 85 assert.ErrorIs(t, err, context.Canceled) 86 assert.Nil(t, it) 87 88 // test blocking push if queue is full 89 for i := 0; i < cfg.Length; i++ { 90 err = q.PushItem(ctx, []byte(fmt.Sprintf("item-%d", i))) 91 assert.NoError(t, err) 92 } 93 ctxTimed, cancel = context.WithTimeout(ctx, 10*time.Millisecond) 94 err = q.PushItem(ctxTimed, []byte("item-full")) 95 assert.ErrorIs(t, err, context.DeadlineExceeded) 96 cancel() 97 98 // test blocking push if queue is full (with custom pushBlockTime) 99 oldPushBlockTime := pushBlockTime 100 timeStart := time.Now() 101 pushBlockTime = 30 * time.Millisecond 102 err = q.PushItem(ctx, []byte("item-full")) 103 assert.ErrorIs(t, err, context.DeadlineExceeded) 104 assert.True(t, time.Since(timeStart) >= pushBlockTime*2/3) 105 pushBlockTime = oldPushBlockTime 106 107 // remove all 108 cnt, err = q.Len(ctx) 109 assert.NoError(t, err) 110 assert.EqualValues(t, cfg.Length, cnt) 111 112 _ = q.RemoveAll(ctx) 113 114 cnt, err = q.Len(ctx) 115 assert.NoError(t, err) 116 assert.EqualValues(t, 0, cnt) 117 }) 118 } 119 120 func TestBaseDummy(t *testing.T) { 121 q, err := newBaseDummy(&BaseConfig{}, true) 122 assert.NoError(t, err) 123 124 ctx := context.Background() 125 assert.NoError(t, q.PushItem(ctx, []byte("foo"))) 126 127 cnt, err := q.Len(ctx) 128 assert.NoError(t, err) 129 assert.EqualValues(t, 0, cnt) 130 131 has, err := q.HasItem(ctx, []byte("foo")) 132 assert.NoError(t, err) 133 assert.False(t, has) 134 135 it, err := q.PopItem(ctx) 136 assert.NoError(t, err) 137 assert.Nil(t, it) 138 139 assert.NoError(t, q.RemoveAll(ctx)) 140 }