github.com/richardwilkes/toolbox@v1.121.0/taskqueue/taskqueue_test.go (about)

     1  // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the Mozilla Public
     4  // License, version 2.0. If a copy of the MPL was not distributed with
     5  // this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  //
     7  // This Source Code Form is "Incompatible With Secondary Licenses", as
     8  // defined by the Mozilla Public License, version 2.0.
     9  
    10  package taskqueue_test
    11  
    12  import (
    13  	"sync/atomic"
    14  	"testing"
    15  
    16  	"github.com/richardwilkes/toolbox/check"
    17  	"github.com/richardwilkes/toolbox/taskqueue"
    18  )
    19  
    20  const (
    21  	parallelWorkSubmissions = 10000
    22  	workTotal               = 49995000
    23  )
    24  
    25  var (
    26  	prev    int
    27  	counter int
    28  	total   int32
    29  	count   int32
    30  )
    31  
    32  func TestSerialQueue(t *testing.T) {
    33  	q := taskqueue.New(taskqueue.Depth(100), taskqueue.Workers(1))
    34  	prev = -1
    35  	counter = 0
    36  	for i := 0; i < 200; i++ {
    37  		submitSerial(q, i)
    38  	}
    39  	q.Shutdown()
    40  	check.Equal(t, 199, prev)
    41  	check.Equal(t, 200, counter)
    42  }
    43  
    44  func submitSerial(q *taskqueue.Queue, i int) {
    45  	q.Submit(func() {
    46  		if i-1 == prev {
    47  			prev = i
    48  			counter++
    49  		}
    50  	})
    51  }
    52  
    53  func TestParallelQueue(t *testing.T) {
    54  	q := taskqueue.New(taskqueue.Workers(5))
    55  	total = 0
    56  	count = 0
    57  	for i := 0; i < parallelWorkSubmissions; i++ {
    58  		submitParallel(q, i)
    59  	}
    60  	q.Shutdown()
    61  	check.Equal(t, parallelWorkSubmissions, int(count))
    62  	check.Equal(t, workTotal, int(total))
    63  }
    64  
    65  func submitParallel(q *taskqueue.Queue, i int) {
    66  	q.Submit(func() {
    67  		atomic.AddInt32(&total, int32(i))
    68  		atomic.AddInt32(&count, 1)
    69  	})
    70  }
    71  
    72  func TestRecovery(t *testing.T) {
    73  	check.Panics(t, boom)
    74  	logged := false
    75  	check.NotPanics(t, func() {
    76  		q := taskqueue.New(taskqueue.RecoveryHandler(func(_ error) { logged = true }))
    77  		q.Submit(boom)
    78  		q.Shutdown()
    79  	})
    80  	check.True(t, logged)
    81  }
    82  
    83  func TestRecoveryWithBadLogger(t *testing.T) {
    84  	check.Panics(t, boom)
    85  	check.NotPanics(t, func() {
    86  		q := taskqueue.New(taskqueue.RecoveryHandler(func(_ error) { boom() }))
    87  		q.Submit(boom)
    88  		q.Shutdown()
    89  	})
    90  }
    91  
    92  func boom() {
    93  	var bad *int
    94  	*bad = 1 //nolint:govet // Yes, this is an intentional store to a nil pointer
    95  }