k8s.io/client-go@v0.22.2/util/workqueue/queue_test.go (about)

     1  /*
     2  Copyright 2015 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package workqueue_test
    18  
    19  import (
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	"k8s.io/client-go/util/workqueue"
    25  )
    26  
    27  func TestBasic(t *testing.T) {
    28  	// If something is seriously wrong this test will never complete.
    29  	q := workqueue.New()
    30  
    31  	// Start producers
    32  	const producers = 50
    33  	producerWG := sync.WaitGroup{}
    34  	producerWG.Add(producers)
    35  	for i := 0; i < producers; i++ {
    36  		go func(i int) {
    37  			defer producerWG.Done()
    38  			for j := 0; j < 50; j++ {
    39  				q.Add(i)
    40  				time.Sleep(time.Millisecond)
    41  			}
    42  		}(i)
    43  	}
    44  
    45  	// Start consumers
    46  	const consumers = 10
    47  	consumerWG := sync.WaitGroup{}
    48  	consumerWG.Add(consumers)
    49  	for i := 0; i < consumers; i++ {
    50  		go func(i int) {
    51  			defer consumerWG.Done()
    52  			for {
    53  				item, quit := q.Get()
    54  				if item == "added after shutdown!" {
    55  					t.Errorf("Got an item added after shutdown.")
    56  				}
    57  				if quit {
    58  					return
    59  				}
    60  				t.Logf("Worker %v: begin processing %v", i, item)
    61  				time.Sleep(3 * time.Millisecond)
    62  				t.Logf("Worker %v: done processing %v", i, item)
    63  				q.Done(item)
    64  			}
    65  		}(i)
    66  	}
    67  
    68  	producerWG.Wait()
    69  	q.ShutDown()
    70  	q.Add("added after shutdown!")
    71  	consumerWG.Wait()
    72  }
    73  
    74  func TestAddWhileProcessing(t *testing.T) {
    75  	q := workqueue.New()
    76  
    77  	// Start producers
    78  	const producers = 50
    79  	producerWG := sync.WaitGroup{}
    80  	producerWG.Add(producers)
    81  	for i := 0; i < producers; i++ {
    82  		go func(i int) {
    83  			defer producerWG.Done()
    84  			q.Add(i)
    85  		}(i)
    86  	}
    87  
    88  	// Start consumers
    89  	const consumers = 10
    90  	consumerWG := sync.WaitGroup{}
    91  	consumerWG.Add(consumers)
    92  	for i := 0; i < consumers; i++ {
    93  		go func(i int) {
    94  			defer consumerWG.Done()
    95  			// Every worker will re-add every item up to two times.
    96  			// This tests the dirty-while-processing case.
    97  			counters := map[interface{}]int{}
    98  			for {
    99  				item, quit := q.Get()
   100  				if quit {
   101  					return
   102  				}
   103  				counters[item]++
   104  				if counters[item] < 2 {
   105  					q.Add(item)
   106  				}
   107  				q.Done(item)
   108  			}
   109  		}(i)
   110  	}
   111  
   112  	producerWG.Wait()
   113  	q.ShutDown()
   114  	consumerWG.Wait()
   115  }
   116  
   117  func TestLen(t *testing.T) {
   118  	q := workqueue.New()
   119  	q.Add("foo")
   120  	if e, a := 1, q.Len(); e != a {
   121  		t.Errorf("Expected %v, got %v", e, a)
   122  	}
   123  	q.Add("bar")
   124  	if e, a := 2, q.Len(); e != a {
   125  		t.Errorf("Expected %v, got %v", e, a)
   126  	}
   127  	q.Add("foo") // should not increase the queue length.
   128  	if e, a := 2, q.Len(); e != a {
   129  		t.Errorf("Expected %v, got %v", e, a)
   130  	}
   131  }
   132  
   133  func TestReinsert(t *testing.T) {
   134  	q := workqueue.New()
   135  	q.Add("foo")
   136  
   137  	// Start processing
   138  	i, _ := q.Get()
   139  	if i != "foo" {
   140  		t.Errorf("Expected %v, got %v", "foo", i)
   141  	}
   142  
   143  	// Add it back while processing
   144  	q.Add(i)
   145  
   146  	// Finish it up
   147  	q.Done(i)
   148  
   149  	// It should be back on the queue
   150  	i, _ = q.Get()
   151  	if i != "foo" {
   152  		t.Errorf("Expected %v, got %v", "foo", i)
   153  	}
   154  
   155  	// Finish that one up
   156  	q.Done(i)
   157  
   158  	if a := q.Len(); a != 0 {
   159  		t.Errorf("Expected queue to be empty. Has %v items", a)
   160  	}
   161  }