...

Source file src/k8s.io/utils/cpuset/cpuset_test.go

Documentation: k8s.io/utils/cpuset

     1  /*
     2  Copyright 2017 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 cpuset
    18  
    19  import (
    20  	"reflect"
    21  	"sort"
    22  	"testing"
    23  )
    24  
    25  func TestCPUSetSize(t *testing.T) {
    26  	testCases := []struct {
    27  		cpuset   CPUSet
    28  		expected int
    29  	}{
    30  		{New(), 0},
    31  		{New(5), 1},
    32  		{New(1, 2, 3, 4, 5), 5},
    33  	}
    34  
    35  	for _, c := range testCases {
    36  		actual := c.cpuset.Size()
    37  		if actual != c.expected {
    38  			t.Errorf("expected: %d, actual: %d, cpuset: [%v]", c.expected, actual, c.cpuset)
    39  		}
    40  	}
    41  }
    42  
    43  func TestCPUSetIsEmpty(t *testing.T) {
    44  	testCases := []struct {
    45  		cpuset   CPUSet
    46  		expected bool
    47  	}{
    48  		{New(), true},
    49  		{New(5), false},
    50  		{New(1, 2, 3, 4, 5), false},
    51  	}
    52  
    53  	for _, c := range testCases {
    54  		actual := c.cpuset.IsEmpty()
    55  		if actual != c.expected {
    56  			t.Errorf("expected: %t, IsEmpty() returned: %t, cpuset: [%v]", c.expected, actual, c.cpuset)
    57  		}
    58  	}
    59  }
    60  
    61  func TestCPUSetContains(t *testing.T) {
    62  	testCases := []struct {
    63  		cpuset         CPUSet
    64  		mustContain    []int
    65  		mustNotContain []int
    66  	}{
    67  		{New(), []int{}, []int{1, 2, 3, 4, 5}},
    68  		{New(5), []int{5}, []int{1, 2, 3, 4}},
    69  		{New(1, 2, 4, 5), []int{1, 2, 4, 5}, []int{0, 3, 6}},
    70  	}
    71  
    72  	for _, c := range testCases {
    73  		for _, elem := range c.mustContain {
    74  			if !c.cpuset.Contains(elem) {
    75  				t.Errorf("expected cpuset to contain element %d: [%v]", elem, c.cpuset)
    76  			}
    77  		}
    78  		for _, elem := range c.mustNotContain {
    79  			if c.cpuset.Contains(elem) {
    80  				t.Errorf("expected cpuset not to contain element %d: [%v]", elem, c.cpuset)
    81  			}
    82  		}
    83  	}
    84  }
    85  
    86  func TestCPUSetEqual(t *testing.T) {
    87  	shouldEqual := []struct {
    88  		s1 CPUSet
    89  		s2 CPUSet
    90  	}{
    91  		{New(), New()},
    92  		{New(5), New(5)},
    93  		{New(1, 2, 3, 4, 5), New(1, 2, 3, 4, 5)},
    94  		{New(5, 4, 3, 2, 1), New(1, 2, 3, 4, 5)},
    95  	}
    96  
    97  	shouldNotEqual := []struct {
    98  		s1 CPUSet
    99  		s2 CPUSet
   100  	}{
   101  		{New(), New(5)},
   102  		{New(5), New()},
   103  		{New(), New(1, 2, 3, 4, 5)},
   104  		{New(1, 2, 3, 4, 5), New()},
   105  		{New(5), New(1, 2, 3, 4, 5)},
   106  		{New(1, 2, 3, 4, 5), New(5)},
   107  	}
   108  
   109  	for _, c := range shouldEqual {
   110  		if !c.s1.Equals(c.s2) {
   111  			t.Errorf("expected cpusets to be equal: s1: [%v], s2: [%v]", c.s1, c.s2)
   112  		}
   113  	}
   114  	for _, c := range shouldNotEqual {
   115  		if c.s1.Equals(c.s2) {
   116  			t.Errorf("expected cpusets to not be equal: s1: [%v], s2: [%v]", c.s1, c.s2)
   117  		}
   118  	}
   119  }
   120  
   121  func TestCPUSetIsSubsetOf(t *testing.T) {
   122  	shouldBeSubset := []struct {
   123  		s1 CPUSet
   124  		s2 CPUSet
   125  	}{
   126  		// A set is a subset of itself
   127  		{New(), New()},
   128  		{New(5), New(5)},
   129  		{New(1, 2, 3, 4, 5), New(1, 2, 3, 4, 5)},
   130  
   131  		// Empty set is a subset of every set
   132  		{New(), New(5)},
   133  		{New(), New(1, 2, 3, 4, 5)},
   134  
   135  		{New(5), New(1, 2, 3, 4, 5)},
   136  		{New(1, 2, 3), New(1, 2, 3, 4, 5)},
   137  		{New(4, 5), New(1, 2, 3, 4, 5)},
   138  		{New(2, 3), New(1, 2, 3, 4, 5)},
   139  	}
   140  
   141  	shouldNotBeSubset := []struct {
   142  		s1 CPUSet
   143  		s2 CPUSet
   144  	}{
   145  		// A set with more elements is not a subset.
   146  		{New(5), New()},
   147  
   148  		// Disjoint set is not a subset.
   149  		{New(6), New(5)},
   150  	}
   151  
   152  	for _, c := range shouldBeSubset {
   153  		if !c.s1.IsSubsetOf(c.s2) {
   154  			t.Errorf("expected s1 to be a subset of s2: s1: [%v], s2: [%v]", c.s1, c.s2)
   155  		}
   156  	}
   157  	for _, c := range shouldNotBeSubset {
   158  		if c.s1.IsSubsetOf(c.s2) {
   159  			t.Errorf("expected s1 to not be a subset of s2: s1: [%v], s2: [%v]", c.s1, c.s2)
   160  		}
   161  	}
   162  }
   163  
   164  func TestCPUSetUnion(t *testing.T) {
   165  	testCases := []struct {
   166  		s1       CPUSet
   167  		others   []CPUSet
   168  		expected CPUSet
   169  	}{
   170  		{New(5), []CPUSet{}, New(5)},
   171  
   172  		{New(), []CPUSet{New()}, New()},
   173  
   174  		{New(), []CPUSet{New(5)}, New(5)},
   175  		{New(5), []CPUSet{New()}, New(5)},
   176  		{New(5), []CPUSet{New(5)}, New(5)},
   177  
   178  		{New(), []CPUSet{New(1, 2, 3, 4, 5)}, New(1, 2, 3, 4, 5)},
   179  		{New(1, 2, 3, 4, 5), []CPUSet{New()}, New(1, 2, 3, 4, 5)},
   180  		{New(1, 2, 3, 4, 5), []CPUSet{New(1, 2, 3, 4, 5)}, New(1, 2, 3, 4, 5)},
   181  
   182  		{New(5), []CPUSet{New(1, 2, 3, 4, 5)}, New(1, 2, 3, 4, 5)},
   183  		{New(1, 2, 3, 4, 5), []CPUSet{New(5)}, New(1, 2, 3, 4, 5)},
   184  
   185  		{New(1, 2), []CPUSet{New(3, 4, 5)}, New(1, 2, 3, 4, 5)},
   186  		{New(1, 2, 3), []CPUSet{New(3, 4, 5)}, New(1, 2, 3, 4, 5)},
   187  
   188  		{New(), []CPUSet{New(1, 2, 3, 4, 5), New(4, 5)}, New(1, 2, 3, 4, 5)},
   189  		{New(1, 2, 3, 4, 5), []CPUSet{New(), New(4)}, New(1, 2, 3, 4, 5)},
   190  		{New(1, 2, 3, 4, 5), []CPUSet{New(1, 2, 3, 4, 5), New(1, 5)}, New(1, 2, 3, 4, 5)},
   191  	}
   192  
   193  	for _, c := range testCases {
   194  		result := c.s1.Union(c.others...)
   195  		if !result.Equals(c.expected) {
   196  			t.Errorf("expected the union of s1 and s2 to be [%v] (got [%v]), others: [%v]", c.expected, result, c.others)
   197  		}
   198  	}
   199  }
   200  
   201  func TestCPUSetIntersection(t *testing.T) {
   202  	testCases := []struct {
   203  		s1       CPUSet
   204  		s2       CPUSet
   205  		expected CPUSet
   206  	}{
   207  		{New(), New(), New()},
   208  
   209  		{New(), New(5), New()},
   210  		{New(5), New(), New()},
   211  		{New(5), New(5), New(5)},
   212  
   213  		{New(), New(1, 2, 3, 4, 5), New()},
   214  		{New(1, 2, 3, 4, 5), New(), New()},
   215  		{New(1, 2, 3, 4, 5), New(1, 2, 3, 4, 5), New(1, 2, 3, 4, 5)},
   216  
   217  		{New(5), New(1, 2, 3, 4, 5), New(5)},
   218  		{New(1, 2, 3, 4, 5), New(5), New(5)},
   219  
   220  		{New(1, 2), New(3, 4, 5), New()},
   221  		{New(1, 2, 3), New(3, 4, 5), New(3)},
   222  	}
   223  
   224  	for _, c := range testCases {
   225  		result := c.s1.Intersection(c.s2)
   226  		if !result.Equals(c.expected) {
   227  			t.Errorf("expected the intersection of s1 and s2 to be [%v] (got [%v]), s1: [%v], s2: [%v]", c.expected, result, c.s1, c.s2)
   228  		}
   229  	}
   230  }
   231  
   232  func TestCPUSetDifference(t *testing.T) {
   233  	testCases := []struct {
   234  		s1       CPUSet
   235  		s2       CPUSet
   236  		expected CPUSet
   237  	}{
   238  		{New(), New(), New()},
   239  
   240  		{New(), New(5), New()},
   241  		{New(5), New(), New(5)},
   242  		{New(5), New(5), New()},
   243  
   244  		{New(), New(1, 2, 3, 4, 5), New()},
   245  		{New(1, 2, 3, 4, 5), New(), New(1, 2, 3, 4, 5)},
   246  		{New(1, 2, 3, 4, 5), New(1, 2, 3, 4, 5), New()},
   247  
   248  		{New(5), New(1, 2, 3, 4, 5), New()},
   249  		{New(1, 2, 3, 4, 5), New(5), New(1, 2, 3, 4)},
   250  
   251  		{New(1, 2), New(3, 4, 5), New(1, 2)},
   252  		{New(1, 2, 3), New(3, 4, 5), New(1, 2)},
   253  	}
   254  
   255  	for _, c := range testCases {
   256  		result := c.s1.Difference(c.s2)
   257  		if !result.Equals(c.expected) {
   258  			t.Errorf("expected the difference of s1 and s2 to be [%v] (got [%v]), s1: [%v], s2: [%v]", c.expected, result, c.s1, c.s2)
   259  		}
   260  	}
   261  }
   262  
   263  func TestCPUSetList(t *testing.T) {
   264  	testCases := []struct {
   265  		set      CPUSet
   266  		expected []int // must be sorted
   267  	}{
   268  		{New(), []int{}},
   269  		{New(5), []int{5}},
   270  		{New(1, 2, 3, 4, 5), []int{1, 2, 3, 4, 5}},
   271  		{New(5, 4, 3, 2, 1), []int{1, 2, 3, 4, 5}},
   272  	}
   273  
   274  	for _, c := range testCases {
   275  		result := c.set.List()
   276  		if !reflect.DeepEqual(result, c.expected) {
   277  			t.Errorf("unexpected List() contents. got [%v] want [%v] (set: [%v])", result, c.expected, c.set)
   278  		}
   279  
   280  		// We cannot rely on internal storage order details for a unit test.
   281  		// The best we can do is to sort the output of 'UnsortedList'.
   282  		result = c.set.UnsortedList()
   283  		sort.Ints(result)
   284  		if !reflect.DeepEqual(result, c.expected) {
   285  			t.Errorf("unexpected UnsortedList() contents. got [%v] want [%v] (set: [%v])", result, c.expected, c.set)
   286  		}
   287  	}
   288  }
   289  
   290  func TestCPUSetString(t *testing.T) {
   291  	testCases := []struct {
   292  		set      CPUSet
   293  		expected string
   294  	}{
   295  		{New(), ""},
   296  		{New(5), "5"},
   297  		{New(1, 2, 3, 4, 5), "1-5"},
   298  		{New(1, 2, 3, 5, 6, 8), "1-3,5-6,8"},
   299  	}
   300  
   301  	for _, c := range testCases {
   302  		result := c.set.String()
   303  		if result != c.expected {
   304  			t.Errorf("expected set as string to be %s (got \"%s\"), s: [%v]", c.expected, result, c.set)
   305  		}
   306  	}
   307  }
   308  
   309  func TestParse(t *testing.T) {
   310  	positiveTestCases := []struct {
   311  		cpusetString string
   312  		expected     CPUSet
   313  	}{
   314  		{"", New()},
   315  		{"5", New(5)},
   316  		{"1,2,3,4,5", New(1, 2, 3, 4, 5)},
   317  		{"1-5", New(1, 2, 3, 4, 5)},
   318  		{"1-2,3-5", New(1, 2, 3, 4, 5)},
   319  		{"5,4,3,2,1", New(1, 2, 3, 4, 5)},  // Range ordering
   320  		{"3-6,1-5", New(1, 2, 3, 4, 5, 6)}, // Overlapping ranges
   321  		{"3-3,5-5", New(3, 5)},             // Very short ranges
   322  	}
   323  
   324  	for _, c := range positiveTestCases {
   325  		result, err := Parse(c.cpusetString)
   326  		if err != nil {
   327  			t.Errorf("expected error not to have occurred: %v", err)
   328  		}
   329  		if !result.Equals(c.expected) {
   330  			t.Errorf("expected string \"%s\" to parse as [%v] (got [%v])", c.cpusetString, c.expected, result)
   331  		}
   332  	}
   333  
   334  	negativeTestCases := []string{
   335  		// Non-numeric entries
   336  		"nonnumeric", "non-numeric", "no,numbers", "0-a", "a-0", "0,a", "a,0", "1-2,a,3-5",
   337  		// Incomplete sequences
   338  		"0,", "0,,", ",3", ",,3", "0,,3",
   339  		// Incomplete ranges and/or negative numbers
   340  		"-1", "1-", "1,2-,3", "1,-2,3", "-1--2", "--1", "1--",
   341  		// Reversed ranges
   342  		"3-0", "0--3"}
   343  	for _, c := range negativeTestCases {
   344  		result, err := Parse(c)
   345  		if err == nil {
   346  			t.Errorf("expected parse failure of \"%s\", but it succeeded as \"%s\"", c, result.String())
   347  		}
   348  	}
   349  }
   350  
   351  func TestClone(t *testing.T) {
   352  	original := New(1, 2, 3, 4, 5)
   353  	clone := original.Clone()
   354  
   355  	if !original.Equals(clone) {
   356  		t.Errorf("expected clone [%v] to equal original [%v]", clone, original)
   357  	}
   358  }
   359  

View as plain text