github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/libnetwork/internal/setmatrix/setmatrix_test.go (about)

     1  package setmatrix
     2  
     3  import (
     4  	"context"
     5  	"strconv"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	_ "github.com/docker/libnetwork/testutils"
    11  )
    12  
    13  func TestSetSerialInsertDelete(t *testing.T) {
    14  	s := NewSetMatrix()
    15  
    16  	b, i := s.Insert("a", "1")
    17  	if !b || i != 1 {
    18  		t.Fatalf("error in insert %t %d", b, i)
    19  	}
    20  	b, i = s.Insert("a", "1")
    21  	if b || i != 1 {
    22  		t.Fatalf("error in insert %t %d", b, i)
    23  	}
    24  	b, i = s.Insert("a", "2")
    25  	if !b || i != 2 {
    26  		t.Fatalf("error in insert %t %d", b, i)
    27  	}
    28  	b, i = s.Insert("a", "1")
    29  	if b || i != 2 {
    30  		t.Fatalf("error in insert %t %d", b, i)
    31  	}
    32  	b, i = s.Insert("a", "3")
    33  	if !b || i != 3 {
    34  		t.Fatalf("error in insert %t %d", b, i)
    35  	}
    36  	b, i = s.Insert("a", "2")
    37  	if b || i != 3 {
    38  		t.Fatalf("error in insert %t %d", b, i)
    39  	}
    40  	b, i = s.Insert("a", "3")
    41  	if b || i != 3 {
    42  		t.Fatalf("error in insert %t %d", b, i)
    43  	}
    44  	b, i = s.Insert("a", "4")
    45  	if !b || i != 4 {
    46  		t.Fatalf("error in insert %t %d", b, i)
    47  	}
    48  
    49  	b, p := s.Contains("a", "1")
    50  	if !b || !p {
    51  		t.Fatalf("error in contains %t %t", b, p)
    52  	}
    53  	b, p = s.Contains("a", "2")
    54  	if !b || !p {
    55  		t.Fatalf("error in contains %t %t", b, p)
    56  	}
    57  	b, p = s.Contains("a", "3")
    58  	if !b || !p {
    59  		t.Fatalf("error in contains %t %t", b, p)
    60  	}
    61  	b, p = s.Contains("a", "4")
    62  	if !b || !p {
    63  		t.Fatalf("error in contains %t %t", b, p)
    64  	}
    65  
    66  	i, b = s.Cardinality("a")
    67  	if !b || i != 4 {
    68  		t.Fatalf("error in cardinality count %t %d", b, i)
    69  	}
    70  	keys := s.Keys()
    71  	if len(keys) != 1 {
    72  		t.Fatalf("error in keys %v", keys)
    73  	}
    74  	str, b := s.String("a")
    75  	if !b ||
    76  		!strings.Contains(str, "1") ||
    77  		!strings.Contains(str, "2") ||
    78  		!strings.Contains(str, "3") ||
    79  		!strings.Contains(str, "4") {
    80  		t.Fatalf("error in string %t %s", b, str)
    81  	}
    82  
    83  	_, b = s.Get("a")
    84  	if !b {
    85  		t.Fatalf("error in get %t", b)
    86  	}
    87  
    88  	b, i = s.Remove("a", "1")
    89  	if !b || i != 3 {
    90  		t.Fatalf("error in remove %t %d", b, i)
    91  	}
    92  	b, i = s.Remove("a", "3")
    93  	if !b || i != 2 {
    94  		t.Fatalf("error in remove %t %d", b, i)
    95  	}
    96  	b, i = s.Remove("a", "1")
    97  	if b || i != 2 {
    98  		t.Fatalf("error in remove %t %d", b, i)
    99  	}
   100  	b, i = s.Remove("a", "4")
   101  	if !b || i != 1 {
   102  		t.Fatalf("error in remove %t %d", b, i)
   103  	}
   104  	b, i = s.Remove("a", "2")
   105  	if !b || i != 0 {
   106  		t.Fatalf("error in remove %t %d", b, i)
   107  	}
   108  	b, i = s.Remove("a", "2")
   109  	if b || i != 0 {
   110  		t.Fatalf("error in remove %t %d", b, i)
   111  	}
   112  
   113  	i, b = s.Cardinality("a")
   114  	if b || i != 0 {
   115  		t.Fatalf("error in cardinality count %t %d", b, i)
   116  	}
   117  
   118  	str, b = s.String("a")
   119  	if b || str != "" {
   120  		t.Fatalf("error in string %t %s", b, str)
   121  	}
   122  
   123  	keys = s.Keys()
   124  	if len(keys) > 0 {
   125  		t.Fatalf("error in keys %v", keys)
   126  	}
   127  
   128  	// Negative tests
   129  	_, b = s.Get("not exists")
   130  	if b {
   131  		t.Fatalf("error should not happen %t", b)
   132  	}
   133  
   134  	b1, b := s.Contains("not exists", "a")
   135  	if b1 || b {
   136  		t.Fatalf("error should not happen %t %t", b1, b)
   137  	}
   138  }
   139  
   140  func insertDeleteRotuine(ctx context.Context, endCh chan int, s SetMatrix, key, value string) {
   141  	for {
   142  		select {
   143  		case <-ctx.Done():
   144  			endCh <- 0
   145  			return
   146  		default:
   147  			b, _ := s.Insert(key, value)
   148  			if !b {
   149  				endCh <- 1
   150  				return
   151  			}
   152  
   153  			b, _ = s.Remove(key, value)
   154  			if !b {
   155  				endCh <- 2
   156  				return
   157  			}
   158  		}
   159  	}
   160  }
   161  
   162  func TestSetParallelInsertDelete(t *testing.T) {
   163  	s := NewSetMatrix()
   164  	parallelRoutines := 6
   165  	endCh := make(chan int)
   166  	// Let the routines running and competing for 10s
   167  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   168  	defer cancel()
   169  	for i := 0; i < parallelRoutines; i++ {
   170  		go insertDeleteRotuine(ctx, endCh, s, "key-"+strconv.Itoa(i%3), strconv.Itoa(i))
   171  	}
   172  	for parallelRoutines > 0 {
   173  		v := <-endCh
   174  		if v == 1 {
   175  			t.Fatalf("error one goroutine failed on the insert")
   176  		}
   177  		if v == 2 {
   178  			t.Fatalf("error one goroutine failed on the remove")
   179  		}
   180  		parallelRoutines--
   181  	}
   182  	if i, b := s.Cardinality("key"); b || i > 0 {
   183  		t.Fatalf("error the set should be empty %t %d", b, i)
   184  	}
   185  }