go.ligato.io/vpp-agent/v3@v3.5.0/plugins/kvscheduler/internal/utils/keyset_test.go (about)

     1  // Copyright (c) 2018 Cisco and/or its affiliates.
     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 utils
    16  
    17  import (
    18  	"reflect"
    19  	"strings"
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  )
    24  
    25  func TestSingleton(t *testing.T) {
    26  	RegisterTestingT(t)
    27  
    28  	// constructor
    29  	s := NewSingletonKeySet("key1")
    30  	Expect(s.String()).To(BeEquivalentTo("{key1}"))
    31  	Expect(s.Has("key1")).To(BeTrue())
    32  	Expect(s.Has("key2")).To(BeFalse())
    33  	Expect(s.String()).To(BeEquivalentTo("{key1}"))
    34  	Expect(s.Length()).To(BeEquivalentTo(1))
    35  	Expect(s.Iterate()).To(BeEquivalentTo([]string{"key1"}))
    36  
    37  	// delete
    38  	Expect(s.Del("key2")).To(BeFalse())
    39  	Expect(s.Del("key1")).To(BeTrue())
    40  	Expect(s.Has("key1")).To(BeFalse())
    41  	Expect(s.String()).To(BeEquivalentTo("{}"))
    42  	Expect(s.Length()).To(BeEquivalentTo(0))
    43  	Expect(s.Iterate()).To(BeEquivalentTo([]string{}))
    44  
    45  	// add
    46  	Expect(s.Add("key1")).To(BeTrue())
    47  	Expect(s.Add("key1")).To(BeFalse())
    48  	Expect(s.Add("key2")).To(BeTrue())
    49  	Expect(s.Has("key1")).To(BeFalse())
    50  	Expect(s.Has("key2")).To(BeTrue())
    51  	Expect(s.String()).To(BeEquivalentTo("{key2}"))
    52  	Expect(s.Length()).To(BeEquivalentTo(1))
    53  	Expect(s.Iterate()).To(BeEquivalentTo([]string{"key2"}))
    54  
    55  	// copy-on-write
    56  	s2 := s.CopyOnWrite()
    57  	Expect(s2.Has("key1")).To(BeFalse())
    58  	Expect(s2.Has("key2")).To(BeTrue())
    59  	Expect(s2.String()).To(BeEquivalentTo("{key2}"))
    60  	Expect(s2.Length()).To(BeEquivalentTo(1))
    61  	Expect(s2.Iterate()).To(BeEquivalentTo([]string{"key2"}))
    62  	Expect(s2.Del("key2")).To(BeTrue())
    63  	Expect(s2.String()).To(BeEquivalentTo("{}"))
    64  	Expect(s.String()).To(BeEquivalentTo("{key2}"))
    65  	Expect(s.Length()).To(BeEquivalentTo(1))
    66  	Expect(s2.Length()).To(BeEquivalentTo(0))
    67  
    68  	// subtract
    69  	Expect(s.Subtract(s2)).To(BeFalse())
    70  	s2.Add("key2")
    71  	Expect(s.Subtract(s2)).To(BeTrue())
    72  	Expect(s.String()).To(BeEquivalentTo("{}"))
    73  	s.Add("key1")
    74  	Expect(s.Subtract(s2)).To(BeFalse())
    75  
    76  	// intersect
    77  	Expect(s.Intersect(s2)).To(BeTrue())
    78  	Expect(s.String()).To(BeEquivalentTo("{}"))
    79  	s.Add("key2")
    80  	Expect(s.Intersect(s2)).To(BeFalse())
    81  	Expect(s.String()).To(BeEquivalentTo("{key2}"))
    82  }
    83  
    84  func permutations(arr []string) [][]string {
    85  	var helper func([]string, int)
    86  	res := [][]string{}
    87  
    88  	helper = func(arr []string, n int) {
    89  		if n == 1 {
    90  			tmp := make([]string, len(arr))
    91  			copy(tmp, arr)
    92  			res = append(res, tmp)
    93  		} else {
    94  			for i := 0; i < n; i++ {
    95  				helper(arr, n-1)
    96  				if n%2 == 1 {
    97  					tmp := arr[i]
    98  					arr[i] = arr[n-1]
    99  					arr[n-1] = tmp
   100  				} else {
   101  					tmp := arr[0]
   102  					arr[0] = arr[n-1]
   103  					arr[n-1] = tmp
   104  				}
   105  			}
   106  		}
   107  	}
   108  	helper(arr, len(arr))
   109  	return res
   110  }
   111  
   112  func testKeySetToString(s KeySet, keys ...string) {
   113  	str := s.String()
   114  	validStr := false
   115  	for _, permutation := range permutations(keys) {
   116  		permStr := "{" + strings.Join(permutation, ", ") + "}"
   117  		if permStr == str {
   118  			validStr = true
   119  			break
   120  		}
   121  	}
   122  	Expect(validStr).To(BeTrue())
   123  }
   124  
   125  func testKeySetIterator(s KeySet, keys ...string) {
   126  	iter := s.Iterate()
   127  	validIter := false
   128  	for _, permutation := range permutations(keys) {
   129  		if reflect.DeepEqual(permutation, iter) {
   130  			validIter = true
   131  			break
   132  		}
   133  	}
   134  	Expect(validIter).To(BeTrue())
   135  }
   136  
   137  func testKeySet(factory1, factory2 func(keys ...string) KeySet) {
   138  	// constructor
   139  	s1 := factory1()
   140  	Expect(s1.Has("key1")).To(BeFalse())
   141  	Expect(s1.Has("key2")).To(BeFalse())
   142  	Expect(s1.String()).To(BeEquivalentTo("{}"))
   143  	Expect(s1.Length()).To(BeEquivalentTo(0))
   144  	Expect(s1.Iterate()).To(BeEquivalentTo([]string{}))
   145  	s1 = factory1("key1", "key2", "key3")
   146  	Expect(s1.Has("key1")).To(BeTrue())
   147  	Expect(s1.Has("key2")).To(BeTrue())
   148  	testKeySetToString(s1, "key1", "key2", "key3")
   149  	Expect(s1.Length()).To(BeEquivalentTo(3))
   150  	testKeySetIterator(s1, "key1", "key2", "key3")
   151  
   152  	// delete
   153  	Expect(s1.Del("key4")).To(BeFalse())
   154  	Expect(s1.Del("key2")).To(BeTrue())
   155  	Expect(s1.Has("key2")).To(BeFalse())
   156  	Expect(s1.Has("key1")).To(BeTrue())
   157  	Expect(s1.Has("key3")).To(BeTrue())
   158  	Expect(s1.Length()).To(BeEquivalentTo(2))
   159  	testKeySetToString(s1, "key1", "key3")
   160  	testKeySetIterator(s1, "key1", "key3")
   161  	Expect(s1.Del("key1")).To(BeTrue())
   162  	Expect(s1.Del("key3")).To(BeTrue())
   163  	Expect(s1.Del("key3")).To(BeFalse())
   164  	Expect(s1.String()).To(BeEquivalentTo("{}"))
   165  	Expect(s1.Length()).To(BeEquivalentTo(0))
   166  	Expect(s1.Iterate()).To(BeEquivalentTo([]string{}))
   167  
   168  	// add
   169  	Expect(s1.Add("key2")).To(BeTrue())
   170  	Expect(s1.Add("key2")).To(BeFalse())
   171  	Expect(s1.Add("key1")).To(BeTrue())
   172  	Expect(s1.Add("key3")).To(BeTrue())
   173  	Expect(s1.Has("key1")).To(BeTrue())
   174  	Expect(s1.Has("key2")).To(BeTrue())
   175  	Expect(s1.Has("key3")).To(BeTrue())
   176  	Expect(s1.Has("key4")).To(BeFalse())
   177  	Expect(s1.Length()).To(BeEquivalentTo(3))
   178  	testKeySetToString(s1, "key1", "key2", "key3")
   179  	testKeySetIterator(s1, "key1", "key2", "key3")
   180  
   181  	// copy-on-write
   182  	s2 := s1.CopyOnWrite()
   183  	Expect(s2.Has("key1")).To(BeTrue())
   184  	Expect(s2.Has("key2")).To(BeTrue())
   185  	Expect(s2.Has("key3")).To(BeTrue())
   186  	Expect(s2.Has("key4")).To(BeFalse())
   187  	Expect(s2.Length()).To(BeEquivalentTo(3))
   188  	testKeySetToString(s2, "key1", "key2", "key3")
   189  	testKeySetIterator(s2, "key1", "key2", "key3")
   190  	Expect(s2.Add("key4")).To(BeTrue())
   191  	Expect(s2.Has("key4")).To(BeTrue())
   192  	Expect(s1.Has("key4")).To(BeFalse())
   193  	Expect(s2.Del("key1")).To(BeTrue())
   194  	Expect(s2.Has("key1")).To(BeFalse())
   195  	Expect(s1.Has("key1")).To(BeTrue())
   196  	Expect(s2.Length()).To(BeEquivalentTo(3))
   197  	testKeySetToString(s2, "key2", "key3", "key4")
   198  	testKeySetIterator(s2, "key2", "key3", "key4")
   199  	Expect(s1.Length()).To(BeEquivalentTo(3))
   200  	testKeySetToString(s1, "key1", "key2", "key3")
   201  	testKeySetIterator(s1, "key1", "key2", "key3")
   202  
   203  	// subtract
   204  	s3 := factory2("key1", "key3")
   205  	Expect(s1.Subtract(s3)).To(BeTrue())
   206  	Expect(s1.Length()).To(BeEquivalentTo(1))
   207  	testKeySetToString(s1, "key2")
   208  	testKeySetIterator(s1, "key2")
   209  	Expect(s1.Subtract(s3)).To(BeFalse())
   210  	Expect(s1.Length()).To(BeEquivalentTo(1))
   211  	testKeySetToString(s1, "key2")
   212  	testKeySetIterator(s1, "key2")
   213  	Expect(s2.Subtract(s3)).To(BeTrue())
   214  	Expect(s2.Length()).To(BeEquivalentTo(2))
   215  	testKeySetToString(s2, "key2", "key4")
   216  	testKeySetIterator(s2, "key2", "key4")
   217  	Expect(s2.Subtract(s3)).To(BeFalse())
   218  	Expect(s2.Length()).To(BeEquivalentTo(2))
   219  	testKeySetToString(s2, "key2", "key4")
   220  	testKeySetIterator(s2, "key2", "key4")
   221  
   222  	// intersect
   223  	Expect(s1.Intersect(s2)).To(BeFalse())
   224  	Expect(s1.Length()).To(BeEquivalentTo(1))
   225  	testKeySetToString(s1, "key2")
   226  	testKeySetIterator(s1, "key2")
   227  	Expect(s2.Intersect(s1)).To(BeTrue())
   228  	Expect(s2.Length()).To(BeEquivalentTo(1))
   229  	testKeySetToString(s2, "key2")
   230  	testKeySetIterator(s2, "key2")
   231  }
   232  
   233  func TestMapBasedKeySet(t *testing.T) {
   234  	RegisterTestingT(t)
   235  
   236  	testKeySet(NewMapBasedKeySet, NewMapBasedKeySet)
   237  	testKeySet(NewMapBasedKeySet, NewSliceBasedKeySet)
   238  }
   239  
   240  func TestSliceBasedKeySet(t *testing.T) {
   241  	RegisterTestingT(t)
   242  
   243  	testKeySet(NewSliceBasedKeySet, NewSliceBasedKeySet)
   244  	testKeySet(NewSliceBasedKeySet, NewMapBasedKeySet)
   245  }