github.com/kaydxh/golang@v0.0.131/go/container/workqueue/queue_test.go (about)

     1  /*
     2   *Copyright (c) 2022, kaydxh
     3   *
     4   *Permission is hereby granted, free of charge, to any person obtaining a copy
     5   *of this software and associated documentation files (the "Software"), to deal
     6   *in the Software without restriction, including without limitation the rights
     7   *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   *copies of the Software, and to permit persons to whom the Software is
     9   *furnished to do so, subject to the following conditions:
    10   *
    11   *The above copyright notice and this permission notice shall be included in all
    12   *copies or substantial portions of the Software.
    13   *
    14   *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   *SOFTWARE.
    21   */
    22  package workqueue_test
    23  
    24  import (
    25  	"sync"
    26  	"testing"
    27  	"time"
    28  
    29  	workqueue_ "github.com/kaydxh/golang/go/container/workqueue"
    30  )
    31  
    32  func TestBasic(t *testing.T) {
    33  	testCases := []struct {
    34  		queue         *workqueue_.Type
    35  		queueShutDown func(workqueue_.Interface)
    36  	}{
    37  		{
    38  			queue:         workqueue_.NewQueue(),
    39  			queueShutDown: workqueue_.Interface.ShutDown,
    40  		},
    41  	}
    42  
    43  	for _, testCase := range testCases {
    44  
    45  		// Start producers
    46  		const producers = 10
    47  		producerWG := sync.WaitGroup{}
    48  		producerWG.Add(producers)
    49  		for i := 0; i < producers; i++ {
    50  			go func(i int) {
    51  				defer producerWG.Done()
    52  				for j := 0; j < 2; j++ {
    53  					testCase.queue.Add(i)
    54  					time.Sleep(time.Millisecond)
    55  				}
    56  			}(i)
    57  		}
    58  
    59  		// Start consumers
    60  		const consumers = 10
    61  		consumerWG := sync.WaitGroup{}
    62  		consumerWG.Add(consumers)
    63  		for i := 0; i < consumers; i++ {
    64  			go func(i int) {
    65  				defer consumerWG.Done()
    66  				for {
    67  					item, quit := testCase.queue.Get()
    68  					if quit {
    69  						return
    70  					}
    71  
    72  					t.Logf("Woker %v: begin processing %v", i, item)
    73  					time.Sleep(3 * time.Millisecond)
    74  					t.Logf("Woker %v: done processing %v", i, item)
    75  					testCase.queue.Done(item)
    76  
    77  				}
    78  			}(i)
    79  		}
    80  
    81  		producerWG.Wait()
    82  		testCase.queueShutDown(testCase.queue)
    83  		testCase.queue.Add("add after shutdown!")
    84  		consumerWG.Wait()
    85  
    86  		if testCase.queue.Len() != 0 {
    87  			t.Errorf("Expected the queue to be empty, had: %v items", testCase.queue.Len())
    88  		}
    89  	}
    90  
    91  }
    92  
    93  func TestReinsert(t *testing.T) {
    94  	q := workqueue_.NewQueue()
    95  	q.Add("foo")
    96  
    97  	// Start processing
    98  	i, _ := q.Get()
    99  	if i != "foo" {
   100  		t.Errorf("Expected %v, got %v", "foo", i)
   101  	}
   102  
   103  	// Add it back while processing
   104  	q.Add(i)
   105  
   106  	// Finish it up
   107  	q.Done(i)
   108  
   109  	// It should be back on the queue
   110  	i, _ = q.Get()
   111  	if i != "foo" {
   112  		t.Errorf("Expected %v, got %v", "foo", i)
   113  	}
   114  
   115  	// Finish that one up
   116  	q.Done(i)
   117  
   118  	if a := q.Len(); a != 0 {
   119  		t.Errorf("Expected queue to be empty. Has %v items", a)
   120  	}
   121  }