github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/queue/unique_queue_channel_test.go (about)

     1  // Copyright 2023 The GitBundle Inc. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // Use of this source code is governed by a MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package queue
     7  
     8  import (
     9  	"sync"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestChannelUniqueQueue(t *testing.T) {
    17  	handleChan := make(chan *testData)
    18  	handle := func(data ...Data) []Data {
    19  		for _, datum := range data {
    20  			testDatum := datum.(*testData)
    21  			handleChan <- testDatum
    22  		}
    23  		return nil
    24  	}
    25  
    26  	nilFn := func(_ func()) {}
    27  
    28  	queue, err := NewChannelUniqueQueue(handle,
    29  		ChannelQueueConfiguration{
    30  			WorkerPoolConfiguration: WorkerPoolConfiguration{
    31  				QueueLength:  0,
    32  				MaxWorkers:   10,
    33  				BlockTimeout: 1 * time.Second,
    34  				BoostTimeout: 5 * time.Minute,
    35  				BoostWorkers: 5,
    36  				Name:         "TestChannelQueue",
    37  			},
    38  			Workers: 0,
    39  		}, &testData{})
    40  	assert.NoError(t, err)
    41  
    42  	assert.Equal(t, queue.(*ChannelUniqueQueue).WorkerPool.boostWorkers, 5)
    43  
    44  	go queue.Run(nilFn, nilFn)
    45  
    46  	test1 := testData{"A", 1}
    47  	go queue.Push(&test1)
    48  	result1 := <-handleChan
    49  	assert.Equal(t, test1.TestString, result1.TestString)
    50  	assert.Equal(t, test1.TestInt, result1.TestInt)
    51  
    52  	err = queue.Push(test1)
    53  	assert.Error(t, err)
    54  }
    55  
    56  func TestChannelUniqueQueue_Batch(t *testing.T) {
    57  	handleChan := make(chan *testData)
    58  	handle := func(data ...Data) []Data {
    59  		for _, datum := range data {
    60  			testDatum := datum.(*testData)
    61  			handleChan <- testDatum
    62  		}
    63  		return nil
    64  	}
    65  
    66  	nilFn := func(_ func()) {}
    67  
    68  	queue, err := NewChannelUniqueQueue(handle,
    69  		ChannelQueueConfiguration{
    70  			WorkerPoolConfiguration: WorkerPoolConfiguration{
    71  				QueueLength:  20,
    72  				BatchLength:  2,
    73  				BlockTimeout: 0,
    74  				BoostTimeout: 0,
    75  				BoostWorkers: 0,
    76  				MaxWorkers:   10,
    77  			},
    78  			Workers: 1,
    79  		}, &testData{})
    80  	assert.NoError(t, err)
    81  
    82  	go queue.Run(nilFn, nilFn)
    83  
    84  	test1 := testData{"A", 1}
    85  	test2 := testData{"B", 2}
    86  
    87  	queue.Push(&test1)
    88  	go queue.Push(&test2)
    89  
    90  	result1 := <-handleChan
    91  	assert.Equal(t, test1.TestString, result1.TestString)
    92  	assert.Equal(t, test1.TestInt, result1.TestInt)
    93  
    94  	result2 := <-handleChan
    95  	assert.Equal(t, test2.TestString, result2.TestString)
    96  	assert.Equal(t, test2.TestInt, result2.TestInt)
    97  
    98  	err = queue.Push(test1)
    99  	assert.Error(t, err)
   100  }
   101  
   102  func TestChannelUniqueQueue_Pause(t *testing.T) {
   103  	lock := sync.Mutex{}
   104  	var queue Queue
   105  	var err error
   106  	pushBack := false
   107  	handleChan := make(chan *testData)
   108  	handle := func(data ...Data) []Data {
   109  		lock.Lock()
   110  		if pushBack {
   111  			if pausable, ok := queue.(Pausable); ok {
   112  				pausable.Pause()
   113  			}
   114  			pushBack = false
   115  			lock.Unlock()
   116  			return data
   117  		}
   118  		lock.Unlock()
   119  
   120  		for _, datum := range data {
   121  			testDatum := datum.(*testData)
   122  			handleChan <- testDatum
   123  		}
   124  		return nil
   125  	}
   126  	nilFn := func(_ func()) {}
   127  
   128  	queue, err = NewChannelUniqueQueue(handle,
   129  		ChannelQueueConfiguration{
   130  			WorkerPoolConfiguration: WorkerPoolConfiguration{
   131  				QueueLength:  20,
   132  				BatchLength:  1,
   133  				BlockTimeout: 0,
   134  				BoostTimeout: 0,
   135  				BoostWorkers: 0,
   136  				MaxWorkers:   10,
   137  			},
   138  			Workers: 1,
   139  		}, &testData{})
   140  	assert.NoError(t, err)
   141  
   142  	go queue.Run(nilFn, nilFn)
   143  
   144  	test1 := testData{"A", 1}
   145  	test2 := testData{"B", 2}
   146  	queue.Push(&test1)
   147  
   148  	pausable, ok := queue.(Pausable)
   149  	if !assert.True(t, ok) {
   150  		return
   151  	}
   152  	result1 := <-handleChan
   153  	assert.Equal(t, test1.TestString, result1.TestString)
   154  	assert.Equal(t, test1.TestInt, result1.TestInt)
   155  
   156  	pausable.Pause()
   157  
   158  	paused, resumed := pausable.IsPausedIsResumed()
   159  
   160  	select {
   161  	case <-paused:
   162  	case <-resumed:
   163  		assert.Fail(t, "Queue should not be resumed")
   164  		return
   165  	default:
   166  		assert.Fail(t, "Queue is not paused")
   167  		return
   168  	}
   169  
   170  	queue.Push(&test2)
   171  
   172  	var result2 *testData
   173  	select {
   174  	case result2 = <-handleChan:
   175  		assert.Fail(t, "handler chan should be empty")
   176  	case <-time.After(100 * time.Millisecond):
   177  	}
   178  
   179  	assert.Nil(t, result2)
   180  
   181  	pausable.Resume()
   182  
   183  	select {
   184  	case <-resumed:
   185  	default:
   186  		assert.Fail(t, "Queue should be resumed")
   187  	}
   188  
   189  	select {
   190  	case result2 = <-handleChan:
   191  	case <-time.After(500 * time.Millisecond):
   192  		assert.Fail(t, "handler chan should contain test2")
   193  	}
   194  
   195  	assert.Equal(t, test2.TestString, result2.TestString)
   196  	assert.Equal(t, test2.TestInt, result2.TestInt)
   197  
   198  	lock.Lock()
   199  	pushBack = true
   200  	lock.Unlock()
   201  
   202  	paused, resumed = pausable.IsPausedIsResumed()
   203  
   204  	select {
   205  	case <-paused:
   206  		assert.Fail(t, "Queue should not be paused")
   207  		return
   208  	case <-resumed:
   209  	default:
   210  		assert.Fail(t, "Queue is not resumed")
   211  		return
   212  	}
   213  
   214  	queue.Push(&test1)
   215  
   216  	select {
   217  	case <-paused:
   218  	case <-handleChan:
   219  		assert.Fail(t, "handler chan should not contain test1")
   220  		return
   221  	case <-time.After(500 * time.Millisecond):
   222  		assert.Fail(t, "queue should be paused")
   223  		return
   224  	}
   225  
   226  	paused, resumed = pausable.IsPausedIsResumed()
   227  
   228  	select {
   229  	case <-paused:
   230  	case <-resumed:
   231  		assert.Fail(t, "Queue should not be resumed")
   232  		return
   233  	default:
   234  		assert.Fail(t, "Queue is not paused")
   235  		return
   236  	}
   237  
   238  	pausable.Resume()
   239  
   240  	select {
   241  	case <-resumed:
   242  	default:
   243  		assert.Fail(t, "Queue should be resumed")
   244  	}
   245  
   246  	select {
   247  	case result1 = <-handleChan:
   248  	case <-time.After(500 * time.Millisecond):
   249  		assert.Fail(t, "handler chan should contain test1")
   250  	}
   251  	assert.Equal(t, test1.TestString, result1.TestString)
   252  	assert.Equal(t, test1.TestInt, result1.TestInt)
   253  }