go.etcd.io/etcd@v3.3.27+incompatible/pkg/types/set_test.go (about)

     1  // Copyright 2015 The etcd Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package types
    16  
    17  import (
    18  	"reflect"
    19  	"sort"
    20  	"testing"
    21  )
    22  
    23  func TestUnsafeSet(t *testing.T) {
    24  	driveSetTests(t, NewUnsafeSet())
    25  }
    26  
    27  func TestThreadsafeSet(t *testing.T) {
    28  	driveSetTests(t, NewThreadsafeSet())
    29  }
    30  
    31  // Check that two slices contents are equal; order is irrelevant
    32  func equal(a, b []string) bool {
    33  	as := sort.StringSlice(a)
    34  	bs := sort.StringSlice(b)
    35  	as.Sort()
    36  	bs.Sort()
    37  	return reflect.DeepEqual(as, bs)
    38  }
    39  
    40  func driveSetTests(t *testing.T, s Set) {
    41  	// Verify operations on an empty set
    42  	eValues := []string{}
    43  	values := s.Values()
    44  	if !reflect.DeepEqual(values, eValues) {
    45  		t.Fatalf("Expect values=%v got %v", eValues, values)
    46  	}
    47  	if l := s.Length(); l != 0 {
    48  		t.Fatalf("Expected length=0, got %d", l)
    49  	}
    50  	for _, v := range []string{"foo", "bar", "baz"} {
    51  		if s.Contains(v) {
    52  			t.Fatalf("Expect s.Contains(%q) to be fale, got true", v)
    53  		}
    54  	}
    55  
    56  	// Add three items, ensure they show up
    57  	s.Add("foo")
    58  	s.Add("bar")
    59  	s.Add("baz")
    60  
    61  	eValues = []string{"foo", "bar", "baz"}
    62  	values = s.Values()
    63  	if !equal(values, eValues) {
    64  		t.Fatalf("Expect values=%v got %v", eValues, values)
    65  	}
    66  
    67  	for _, v := range eValues {
    68  		if !s.Contains(v) {
    69  			t.Fatalf("Expect s.Contains(%q) to be true, got false", v)
    70  		}
    71  	}
    72  
    73  	if l := s.Length(); l != 3 {
    74  		t.Fatalf("Expected length=3, got %d", l)
    75  	}
    76  
    77  	// Add the same item a second time, ensuring it is not duplicated
    78  	s.Add("foo")
    79  
    80  	values = s.Values()
    81  	if !equal(values, eValues) {
    82  		t.Fatalf("Expect values=%v got %v", eValues, values)
    83  	}
    84  	if l := s.Length(); l != 3 {
    85  		t.Fatalf("Expected length=3, got %d", l)
    86  	}
    87  
    88  	// Remove all items, ensure they are gone
    89  	s.Remove("foo")
    90  	s.Remove("bar")
    91  	s.Remove("baz")
    92  
    93  	eValues = []string{}
    94  	values = s.Values()
    95  	if !equal(values, eValues) {
    96  		t.Fatalf("Expect values=%v got %v", eValues, values)
    97  	}
    98  
    99  	if l := s.Length(); l != 0 {
   100  		t.Fatalf("Expected length=0, got %d", l)
   101  	}
   102  
   103  	// Create new copies of the set, and ensure they are unlinked to the
   104  	// original Set by making modifications
   105  	s.Add("foo")
   106  	s.Add("bar")
   107  	cp1 := s.Copy()
   108  	cp2 := s.Copy()
   109  	s.Remove("foo")
   110  	cp3 := s.Copy()
   111  	cp1.Add("baz")
   112  
   113  	for i, tt := range []struct {
   114  		want []string
   115  		got  []string
   116  	}{
   117  		{[]string{"bar"}, s.Values()},
   118  		{[]string{"foo", "bar", "baz"}, cp1.Values()},
   119  		{[]string{"foo", "bar"}, cp2.Values()},
   120  		{[]string{"bar"}, cp3.Values()},
   121  	} {
   122  		if !equal(tt.want, tt.got) {
   123  			t.Fatalf("case %d: expect values=%v got %v", i, tt.want, tt.got)
   124  		}
   125  	}
   126  
   127  	for i, tt := range []struct {
   128  		want bool
   129  		got  bool
   130  	}{
   131  		{true, s.Equals(cp3)},
   132  		{true, cp3.Equals(s)},
   133  		{false, s.Equals(cp2)},
   134  		{false, s.Equals(cp1)},
   135  		{false, cp1.Equals(s)},
   136  		{false, cp2.Equals(s)},
   137  		{false, cp2.Equals(cp1)},
   138  	} {
   139  		if tt.got != tt.want {
   140  			t.Fatalf("case %d: want %t, got %t", i, tt.want, tt.got)
   141  
   142  		}
   143  	}
   144  
   145  	// Subtract values from a Set, ensuring a new Set is created and
   146  	// the original Sets are unmodified
   147  	sub1 := cp1.Sub(s)
   148  	sub2 := cp2.Sub(cp1)
   149  
   150  	for i, tt := range []struct {
   151  		want []string
   152  		got  []string
   153  	}{
   154  		{[]string{"foo", "bar", "baz"}, cp1.Values()},
   155  		{[]string{"foo", "bar"}, cp2.Values()},
   156  		{[]string{"bar"}, s.Values()},
   157  		{[]string{"foo", "baz"}, sub1.Values()},
   158  		{[]string{}, sub2.Values()},
   159  	} {
   160  		if !equal(tt.want, tt.got) {
   161  			t.Fatalf("case %d: expect values=%v got %v", i, tt.want, tt.got)
   162  		}
   163  	}
   164  }
   165  
   166  func TestUnsafeSetContainsAll(t *testing.T) {
   167  	vals := []string{"foo", "bar", "baz"}
   168  	s := NewUnsafeSet(vals...)
   169  
   170  	tests := []struct {
   171  		strs     []string
   172  		wcontain bool
   173  	}{
   174  		{[]string{}, true},
   175  		{vals[:1], true},
   176  		{vals[:2], true},
   177  		{vals, true},
   178  		{[]string{"cuz"}, false},
   179  		{[]string{vals[0], "cuz"}, false},
   180  	}
   181  	for i, tt := range tests {
   182  		if g := s.ContainsAll(tt.strs); g != tt.wcontain {
   183  			t.Errorf("#%d: ok = %v, want %v", i, g, tt.wcontain)
   184  		}
   185  	}
   186  }