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  }