code.gitea.io/gitea@v1.19.3/modules/queue/unique_queue_channel_test.go (about)

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