istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/channels/unbounded_test.go (about)

     1  /*
     2   * Copyright 2019 gRPC 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  
    18  package channels
    19  
    20  import (
    21  	"reflect"
    22  	"sort"
    23  	"sync"
    24  	"testing"
    25  )
    26  
    27  const (
    28  	numWriters = 10
    29  	numWrites  = 10
    30  )
    31  
    32  // wantReads contains the set of values expected to be read by the reader
    33  // goroutine in the tests.
    34  var wantReads []int
    35  
    36  func init() {
    37  	for i := 0; i < numWriters; i++ {
    38  		for j := 0; j < numWrites; j++ {
    39  			wantReads = append(wantReads, i)
    40  		}
    41  	}
    42  }
    43  
    44  // TestSingleWriter starts one reader and one writer goroutine and makes sure
    45  // that the reader gets all the value added to the buffer by the writer.
    46  func TestSingleWriter(t *testing.T) {
    47  	ub := NewUnbounded[int]()
    48  	reads := []int{}
    49  
    50  	var wg sync.WaitGroup
    51  	wg.Add(1)
    52  	go func() {
    53  		defer wg.Done()
    54  		ch := ub.Get()
    55  		for i := 0; i < numWriters*numWrites; i++ {
    56  			r := <-ch
    57  			reads = append(reads, r)
    58  			ub.Load()
    59  		}
    60  	}()
    61  
    62  	wg.Add(1)
    63  	go func() {
    64  		defer wg.Done()
    65  		for i := 0; i < numWriters; i++ {
    66  			for j := 0; j < numWrites; j++ {
    67  				ub.Put(i)
    68  			}
    69  		}
    70  	}()
    71  
    72  	wg.Wait()
    73  	if !reflect.DeepEqual(reads, wantReads) {
    74  		t.Errorf("reads: %#v, wantReads: %#v", reads, wantReads)
    75  	}
    76  }
    77  
    78  // TestMultipleWriters starts multiple writers and one reader goroutine and
    79  // makes sure that the reader gets all the data written by all writers.
    80  func TestMultipleWriters(t *testing.T) {
    81  	ub := NewUnbounded[int]()
    82  	reads := []int{}
    83  
    84  	var wg sync.WaitGroup
    85  	wg.Add(1)
    86  	go func() {
    87  		defer wg.Done()
    88  		ch := ub.Get()
    89  		for i := 0; i < numWriters*numWrites; i++ {
    90  			r := <-ch
    91  			reads = append(reads, r)
    92  			ub.Load()
    93  		}
    94  	}()
    95  
    96  	wg.Add(numWriters)
    97  	for i := 0; i < numWriters; i++ {
    98  		go func(index int) {
    99  			defer wg.Done()
   100  			for j := 0; j < numWrites; j++ {
   101  				ub.Put(index)
   102  			}
   103  		}(i)
   104  	}
   105  
   106  	wg.Wait()
   107  	sort.Ints(reads)
   108  	if !reflect.DeepEqual(reads, wantReads) {
   109  		t.Errorf("reads: %#v, wantReads: %#v", reads, wantReads)
   110  	}
   111  }