...

Source file src/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask_test.go

Documentation: k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask

     1  /*
     2  Copyright 2019 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 bitmask
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  )
    23  
    24  func TestNewEmptyiBitMask(t *testing.T) {
    25  	tcases := []struct {
    26  		name         string
    27  		expectedMask string
    28  	}{
    29  		{
    30  			name:         "New empty BitMask",
    31  			expectedMask: "00",
    32  		},
    33  	}
    34  	for _, tc := range tcases {
    35  		bm := NewEmptyBitMask()
    36  		if bm.String() != tc.expectedMask {
    37  			t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, bm)
    38  		}
    39  	}
    40  }
    41  
    42  func TestNewBitMask(t *testing.T) {
    43  	tcases := []struct {
    44  		name         string
    45  		bits         []int
    46  		expectedMask string
    47  	}{
    48  		{
    49  			name:         "New BitMask with bit 0 set",
    50  			bits:         []int{0},
    51  			expectedMask: "01",
    52  		},
    53  		{
    54  			name:         "New BitMask with bit 1 set",
    55  			bits:         []int{1},
    56  			expectedMask: "10",
    57  		},
    58  		{
    59  			name:         "New BitMask with bit 0 and bit 1 set",
    60  			bits:         []int{0, 1},
    61  			expectedMask: "11",
    62  		},
    63  	}
    64  	for _, tc := range tcases {
    65  		mask, _ := NewBitMask(tc.bits...)
    66  		if mask.String() != tc.expectedMask {
    67  			t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, mask)
    68  		}
    69  	}
    70  }
    71  
    72  func TestAdd(t *testing.T) {
    73  	tcases := []struct {
    74  		name         string
    75  		bits         []int
    76  		expectedMask string
    77  	}{
    78  		{
    79  			name:         "Add BitMask with bit 0 set",
    80  			bits:         []int{0},
    81  			expectedMask: "01",
    82  		},
    83  		{
    84  			name:         "Add BitMask with bit 1 set",
    85  			bits:         []int{1},
    86  			expectedMask: "10",
    87  		},
    88  		{
    89  			name:         "Add BitMask with bits 0 and 1 set",
    90  			bits:         []int{0, 1},
    91  			expectedMask: "11",
    92  		},
    93  		{
    94  			name:         "Add BitMask with bits outside range 0-63",
    95  			bits:         []int{-1, 64},
    96  			expectedMask: "00",
    97  		},
    98  	}
    99  	for _, tc := range tcases {
   100  		mask, _ := NewBitMask()
   101  		mask.Add(tc.bits...)
   102  		if mask.String() != tc.expectedMask {
   103  			t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, mask)
   104  		}
   105  	}
   106  }
   107  
   108  func TestRemove(t *testing.T) {
   109  	tcases := []struct {
   110  		name         string
   111  		bitsSet      []int
   112  		bitsRemove   []int
   113  		expectedMask string
   114  	}{
   115  		{
   116  			name:         "Set bit 0. Remove bit 0",
   117  			bitsSet:      []int{0},
   118  			bitsRemove:   []int{0},
   119  			expectedMask: "00",
   120  		},
   121  		{
   122  			name:         "Set bits 0 and 1. Remove bit 1",
   123  			bitsSet:      []int{0, 1},
   124  			bitsRemove:   []int{1},
   125  			expectedMask: "01",
   126  		},
   127  		{
   128  			name:         "Set bits 0 and 1. Remove bits 0 and 1",
   129  			bitsSet:      []int{0, 1},
   130  			bitsRemove:   []int{0, 1},
   131  			expectedMask: "00",
   132  		},
   133  		{
   134  			name:         "Set bit 0. Attempt to remove bits outside range 0-63",
   135  			bitsSet:      []int{0},
   136  			bitsRemove:   []int{-1, 64},
   137  			expectedMask: "01",
   138  		},
   139  	}
   140  	for _, tc := range tcases {
   141  		mask, _ := NewBitMask(tc.bitsSet...)
   142  		mask.Remove(tc.bitsRemove...)
   143  		if mask.String() != tc.expectedMask {
   144  			t.Errorf("Expected mask to be %v, got %v", tc.expectedMask, mask)
   145  		}
   146  	}
   147  }
   148  
   149  func TestAnd(t *testing.T) {
   150  	tcases := []struct {
   151  		name    string
   152  		masks   [][]int
   153  		andMask string
   154  	}{
   155  		{
   156  			name:    "Mask 11 AND mask 11",
   157  			masks:   [][]int{{0, 1}, {0, 1}},
   158  			andMask: "11",
   159  		},
   160  		{
   161  			name:    "Mask 11 AND mask 10",
   162  			masks:   [][]int{{0, 1}, {1}},
   163  			andMask: "10",
   164  		},
   165  		{
   166  			name:    "Mask 01 AND mask 11",
   167  			masks:   [][]int{{0}, {0, 1}},
   168  			andMask: "01",
   169  		},
   170  		{
   171  			name:    "Mask 11 AND mask 11 AND mask 10",
   172  			masks:   [][]int{{0, 1}, {0, 1}, {1}},
   173  			andMask: "10",
   174  		},
   175  		{
   176  			name:    "Mask 01 AND mask 01 AND mask 10 AND mask 11",
   177  			masks:   [][]int{{0}, {0}, {1}, {0, 1}},
   178  			andMask: "00",
   179  		},
   180  		{
   181  			name:    "Mask 1111 AND mask 1110 AND mask 1100 AND mask 1000",
   182  			masks:   [][]int{{0, 1, 2, 3}, {1, 2, 3}, {2, 3}, {3}},
   183  			andMask: "1000",
   184  		},
   185  	}
   186  	for _, tc := range tcases {
   187  		var bitMasks []BitMask
   188  		for i := range tc.masks {
   189  			bitMask, _ := NewBitMask(tc.masks[i]...)
   190  			bitMasks = append(bitMasks, bitMask)
   191  		}
   192  		resultMask := And(bitMasks[0], bitMasks...)
   193  		if resultMask.String() != string(tc.andMask) {
   194  			t.Errorf("Expected mask to be %v, got %v", tc.andMask, resultMask)
   195  		}
   196  
   197  	}
   198  }
   199  
   200  func TestOr(t *testing.T) {
   201  	tcases := []struct {
   202  		name   string
   203  		masks  [][]int
   204  		orMask string
   205  	}{
   206  		{
   207  			name:   "Mask 01 OR mask 00",
   208  			masks:  [][]int{{0}, {}},
   209  			orMask: "01",
   210  		},
   211  		{
   212  			name:   "Mask 10 OR mask 10",
   213  			masks:  [][]int{{1}, {1}},
   214  			orMask: "10",
   215  		},
   216  		{
   217  			name:   "Mask 01 OR mask 10",
   218  			masks:  [][]int{{0}, {1}},
   219  			orMask: "11",
   220  		},
   221  		{
   222  			name:   "Mask 11 OR mask 11",
   223  			masks:  [][]int{{0, 1}, {0, 1}},
   224  			orMask: "11",
   225  		},
   226  		{
   227  			name:   "Mask 01 OR mask 10 OR mask 11",
   228  			masks:  [][]int{{0}, {1}, {0, 1}},
   229  			orMask: "11",
   230  		},
   231  		{
   232  			name:   "Mask 1000 OR mask 0100 OR mask 0010 OR mask 0001",
   233  			masks:  [][]int{{3}, {2}, {1}, {0}},
   234  			orMask: "1111",
   235  		},
   236  	}
   237  	for _, tc := range tcases {
   238  		var bitMasks []BitMask
   239  		for i := range tc.masks {
   240  			bitMask, _ := NewBitMask(tc.masks[i]...)
   241  			bitMasks = append(bitMasks, bitMask)
   242  		}
   243  		resultMask := Or(bitMasks[0], bitMasks...)
   244  		if resultMask.String() != string(tc.orMask) {
   245  			t.Errorf("Expected mask to be %v, got %v", tc.orMask, resultMask)
   246  		}
   247  	}
   248  }
   249  
   250  func TestClear(t *testing.T) {
   251  	tcases := []struct {
   252  		name        string
   253  		mask        []int
   254  		clearedMask string
   255  	}{
   256  		{
   257  			name:        "Clear mask 01",
   258  			mask:        []int{0},
   259  			clearedMask: "00",
   260  		},
   261  		{
   262  			name:        "Clear mask 10",
   263  			mask:        []int{1},
   264  			clearedMask: "00",
   265  		},
   266  		{
   267  			name:        "Clear mask 11",
   268  			mask:        []int{0, 1},
   269  			clearedMask: "00",
   270  		},
   271  	}
   272  	for _, tc := range tcases {
   273  		mask, _ := NewBitMask(tc.mask...)
   274  		mask.Clear()
   275  		if mask.String() != string(tc.clearedMask) {
   276  			t.Errorf("Expected mask to be %v, got %v", tc.clearedMask, mask)
   277  		}
   278  	}
   279  }
   280  
   281  func TestFill(t *testing.T) {
   282  	tcases := []struct {
   283  		name       string
   284  		mask       []int
   285  		filledMask string
   286  	}{
   287  		{
   288  			name:       "Fill empty mask",
   289  			mask:       nil,
   290  			filledMask: "1111111111111111111111111111111111111111111111111111111111111111",
   291  		},
   292  		{
   293  			name:       "Fill mask 10",
   294  			mask:       []int{0},
   295  			filledMask: "1111111111111111111111111111111111111111111111111111111111111111",
   296  		},
   297  		{
   298  			name:       "Fill mask 11",
   299  			mask:       []int{0, 1},
   300  			filledMask: "1111111111111111111111111111111111111111111111111111111111111111",
   301  		},
   302  	}
   303  	for _, tc := range tcases {
   304  		mask, _ := NewBitMask(tc.mask...)
   305  		mask.Fill()
   306  		if mask.String() != string(tc.filledMask) {
   307  			t.Errorf("Expected mask to be %v, got %v", tc.filledMask, mask)
   308  		}
   309  	}
   310  }
   311  
   312  func TestIsEmpty(t *testing.T) {
   313  	tcases := []struct {
   314  		name          string
   315  		mask          []int
   316  		expectedEmpty bool
   317  	}{
   318  		{
   319  			name:          "Check if mask 00 is empty",
   320  			mask:          nil,
   321  			expectedEmpty: true,
   322  		},
   323  		{
   324  			name:          "Check if mask 01 is empty",
   325  			mask:          []int{0},
   326  			expectedEmpty: false,
   327  		},
   328  		{
   329  			name:          "Check if mask 11 is empty",
   330  			mask:          []int{0, 1},
   331  			expectedEmpty: false,
   332  		},
   333  	}
   334  	for _, tc := range tcases {
   335  		mask, _ := NewBitMask(tc.mask...)
   336  		empty := mask.IsEmpty()
   337  		if empty != tc.expectedEmpty {
   338  			t.Errorf("Expected value to be %v, got %v", tc.expectedEmpty, empty)
   339  		}
   340  	}
   341  }
   342  
   343  func TestIsSet(t *testing.T) {
   344  	tcases := []struct {
   345  		name        string
   346  		mask        []int
   347  		checkBit    int
   348  		expectedSet bool
   349  	}{
   350  		{
   351  			name:        "Check if bit 0 in mask 00 is set",
   352  			mask:        nil,
   353  			checkBit:    0,
   354  			expectedSet: false,
   355  		},
   356  		{
   357  			name:        "Check if bit 0 in mask 01 is set",
   358  			mask:        []int{0},
   359  			checkBit:    0,
   360  			expectedSet: true,
   361  		},
   362  		{
   363  			name:        "Check if bit 1 in mask 11 is set",
   364  			mask:        []int{0, 1},
   365  			checkBit:    1,
   366  			expectedSet: true,
   367  		},
   368  		{
   369  			name:        "Check if bit outside range 0-63 is set",
   370  			mask:        []int{0, 1},
   371  			checkBit:    64,
   372  			expectedSet: false,
   373  		},
   374  	}
   375  	for _, tc := range tcases {
   376  		mask, _ := NewBitMask(tc.mask...)
   377  		set := mask.IsSet(tc.checkBit)
   378  		if set != tc.expectedSet {
   379  			t.Errorf("Expected value to be %v, got %v", tc.expectedSet, set)
   380  		}
   381  	}
   382  }
   383  
   384  func TestAnySet(t *testing.T) {
   385  	tcases := []struct {
   386  		name        string
   387  		mask        []int
   388  		checkBits   []int
   389  		expectedSet bool
   390  	}{
   391  		{
   392  			name:        "Check if any bits from 11 in mask 00 is set",
   393  			mask:        nil,
   394  			checkBits:   []int{0, 1},
   395  			expectedSet: false,
   396  		},
   397  		{
   398  			name:        "Check if any bits from 11 in mask 01 is set",
   399  			mask:        []int{0},
   400  			checkBits:   []int{0, 1},
   401  			expectedSet: true,
   402  		},
   403  		{
   404  			name:        "Check if any bits from 11 in mask 11 is set",
   405  			mask:        []int{0, 1},
   406  			checkBits:   []int{0, 1},
   407  			expectedSet: true,
   408  		},
   409  		{
   410  			name:        "Check if any bit outside range 0-63 is set",
   411  			mask:        []int{0, 1},
   412  			checkBits:   []int{64, 65},
   413  			expectedSet: false,
   414  		},
   415  		{
   416  			name:        "Check if any bits from 1001 in mask 0110 is set",
   417  			mask:        []int{1, 2},
   418  			checkBits:   []int{0, 3},
   419  			expectedSet: false,
   420  		},
   421  	}
   422  	for _, tc := range tcases {
   423  		mask, _ := NewBitMask(tc.mask...)
   424  		set := mask.AnySet(tc.checkBits)
   425  		if set != tc.expectedSet {
   426  			t.Errorf("Expected value to be %v, got %v", tc.expectedSet, set)
   427  		}
   428  	}
   429  }
   430  
   431  func TestIsEqual(t *testing.T) {
   432  	tcases := []struct {
   433  		name          string
   434  		firstMask     []int
   435  		secondMask    []int
   436  		expectedEqual bool
   437  	}{
   438  		{
   439  			name:          "Check if mask 00 equals mask 00",
   440  			firstMask:     nil,
   441  			secondMask:    nil,
   442  			expectedEqual: true,
   443  		},
   444  		{
   445  			name:          "Check if mask 00 equals mask 01",
   446  			firstMask:     nil,
   447  			secondMask:    []int{0},
   448  			expectedEqual: false,
   449  		},
   450  		{
   451  			name:          "Check if mask 01 equals mask 01",
   452  			firstMask:     []int{0},
   453  			secondMask:    []int{0},
   454  			expectedEqual: true,
   455  		},
   456  		{
   457  			name:          "Check if mask 01 equals mask 10",
   458  			firstMask:     []int{0},
   459  			secondMask:    []int{1},
   460  			expectedEqual: false,
   461  		},
   462  		{
   463  			name:          "Check if mask 11 equals mask 11",
   464  			firstMask:     []int{0, 1},
   465  			secondMask:    []int{0, 1},
   466  			expectedEqual: true,
   467  		},
   468  	}
   469  	for _, tc := range tcases {
   470  		firstMask, _ := NewBitMask(tc.firstMask...)
   471  		secondMask, _ := NewBitMask(tc.secondMask...)
   472  		isEqual := firstMask.IsEqual(secondMask)
   473  		if isEqual != tc.expectedEqual {
   474  			t.Errorf("Expected mask to be %v, got %v", tc.expectedEqual, isEqual)
   475  		}
   476  	}
   477  }
   478  
   479  func TestCount(t *testing.T) {
   480  	tcases := []struct {
   481  		name          string
   482  		bits          []int
   483  		expectedCount int
   484  	}{
   485  		{
   486  			name:          "Count number of bits set in mask 00",
   487  			bits:          nil,
   488  			expectedCount: 0,
   489  		},
   490  		{
   491  			name:          "Count number of bits set in mask 01",
   492  			bits:          []int{0},
   493  			expectedCount: 1,
   494  		},
   495  		{
   496  			name:          "Count number of bits set in mask 11",
   497  			bits:          []int{0, 1},
   498  			expectedCount: 2,
   499  		},
   500  	}
   501  	for _, tc := range tcases {
   502  		mask, _ := NewBitMask(tc.bits...)
   503  		count := mask.Count()
   504  		if count != tc.expectedCount {
   505  			t.Errorf("Expected value to be %v, got %v", tc.expectedCount, count)
   506  		}
   507  	}
   508  }
   509  
   510  func TestGetBits(t *testing.T) {
   511  	tcases := []struct {
   512  		name         string
   513  		bits         []int
   514  		expectedBits []int
   515  	}{
   516  		{
   517  			name:         "Get bits of mask 00",
   518  			bits:         nil,
   519  			expectedBits: nil,
   520  		},
   521  		{
   522  			name:         "Get bits of mask 01",
   523  			bits:         []int{0},
   524  			expectedBits: []int{0},
   525  		},
   526  		{
   527  			name:         "Get bits of mask 11",
   528  			bits:         []int{0, 1},
   529  			expectedBits: []int{0, 1},
   530  		},
   531  	}
   532  	for _, tc := range tcases {
   533  		mask, _ := NewBitMask(tc.bits...)
   534  		bits := mask.GetBits()
   535  		if !reflect.DeepEqual(bits, tc.expectedBits) {
   536  			t.Errorf("Expected value to be %v, got %v", tc.expectedBits, bits)
   537  		}
   538  	}
   539  }
   540  
   541  func TestIsNarrowerThan(t *testing.T) {
   542  	tcases := []struct {
   543  		name                  string
   544  		firstMask             []int
   545  		secondMask            []int
   546  		expectedFirstNarrower bool
   547  	}{
   548  		{
   549  			name:                  "Check narrowness of masks with unequal bits set 1/2",
   550  			firstMask:             []int{0},
   551  			secondMask:            []int{0, 1},
   552  			expectedFirstNarrower: true,
   553  		},
   554  		{
   555  			name:                  "Check narrowness of masks with unequal bits set 2/2",
   556  			firstMask:             []int{0, 1},
   557  			secondMask:            []int{0},
   558  			expectedFirstNarrower: false,
   559  		},
   560  		{
   561  			name:                  "Check narrowness of masks with equal bits set 1/2",
   562  			firstMask:             []int{0},
   563  			secondMask:            []int{1},
   564  			expectedFirstNarrower: true,
   565  		},
   566  		{
   567  			name:                  "Check narrowness of masks with equal bits set 2/2",
   568  			firstMask:             []int{1},
   569  			secondMask:            []int{0},
   570  			expectedFirstNarrower: false,
   571  		},
   572  	}
   573  	for _, tc := range tcases {
   574  		firstMask, _ := NewBitMask(tc.firstMask...)
   575  		secondMask, _ := NewBitMask(tc.secondMask...)
   576  		expectedFirstNarrower := firstMask.IsNarrowerThan(secondMask)
   577  		if expectedFirstNarrower != tc.expectedFirstNarrower {
   578  			t.Errorf("Expected value to be %v, got %v", tc.expectedFirstNarrower, expectedFirstNarrower)
   579  		}
   580  	}
   581  }
   582  
   583  func TestIterateBitMasks(t *testing.T) {
   584  	tcases := []struct {
   585  		name    string
   586  		numbits int
   587  	}{
   588  		{
   589  			name:    "1 bit",
   590  			numbits: 1,
   591  		},
   592  		{
   593  			name:    "2 bits",
   594  			numbits: 2,
   595  		},
   596  		{
   597  			name:    "4 bits",
   598  			numbits: 4,
   599  		},
   600  		{
   601  			name:    "8 bits",
   602  			numbits: 8,
   603  		},
   604  		{
   605  			name:    "16 bits",
   606  			numbits: 16,
   607  		},
   608  	}
   609  	for _, tc := range tcases {
   610  		// Generate a list of bits from tc.numbits.
   611  		var bits []int
   612  		for i := 0; i < tc.numbits; i++ {
   613  			bits = append(bits, i)
   614  		}
   615  
   616  		// Calculate the expected number of masks. Since we always have masks
   617  		// with bits from 0..n, this is just (2^n - 1) since we want 1 mask
   618  		// represented by each integer between 1 and 2^n-1.
   619  		expectedNumMasks := (1 << uint(tc.numbits)) - 1
   620  
   621  		// Iterate all masks and count them.
   622  		numMasks := 0
   623  		IterateBitMasks(bits, func(BitMask) {
   624  			numMasks++
   625  		})
   626  
   627  		// Compare the number of masks generated to the expected amount.
   628  		if expectedNumMasks != numMasks {
   629  			t.Errorf("Expected to iterate %v masks, got %v", expectedNumMasks, numMasks)
   630  		}
   631  	}
   632  }
   633  
   634  func TestIsLessThan(t *testing.T) {
   635  	tcases := []struct {
   636  		name               string
   637  		firstMask          []int
   638  		secondMask         []int
   639  		expectedFirstLower bool
   640  	}{
   641  		{
   642  			name:               "Check which value is lower of masks with equal bits set 1/1",
   643  			firstMask:          []int{0},
   644  			secondMask:         []int{0},
   645  			expectedFirstLower: false,
   646  		},
   647  		{
   648  			name:               "Check which value is lower of masks with unequal bits set 2/1",
   649  			firstMask:          []int{1},
   650  			secondMask:         []int{0},
   651  			expectedFirstLower: false,
   652  		},
   653  		{
   654  			name:               "Check which value is lower of masks with unequal bits set 1/2",
   655  			firstMask:          []int{0},
   656  			secondMask:         []int{1},
   657  			expectedFirstLower: true,
   658  		},
   659  	}
   660  	for _, tc := range tcases {
   661  		firstMask, _ := NewBitMask(tc.firstMask...)
   662  		secondMask, _ := NewBitMask(tc.secondMask...)
   663  		expectedFirstLower := firstMask.IsLessThan(secondMask)
   664  		if expectedFirstLower != tc.expectedFirstLower {
   665  			t.Errorf("Expected value to be %v, got %v", tc.expectedFirstLower, expectedFirstLower)
   666  		}
   667  	}
   668  }
   669  
   670  func TestIsGreaterThan(t *testing.T) {
   671  	tcases := []struct {
   672  		name                 string
   673  		firstMask            []int
   674  		secondMask           []int
   675  		expectedFirstGreater bool
   676  	}{
   677  		{
   678  			name:                 "Check which value is greater of masks with equal bits set 1/1",
   679  			firstMask:            []int{0},
   680  			secondMask:           []int{0},
   681  			expectedFirstGreater: false,
   682  		},
   683  		{
   684  			name:                 "Check which value is greater of masks with unequal bits set 2/1",
   685  			firstMask:            []int{1},
   686  			secondMask:           []int{0},
   687  			expectedFirstGreater: true,
   688  		},
   689  		{
   690  			name:                 "Check which value is greater of masks with unequal bits set 1/2",
   691  			firstMask:            []int{0},
   692  			secondMask:           []int{1},
   693  			expectedFirstGreater: false,
   694  		},
   695  	}
   696  	for _, tc := range tcases {
   697  		firstMask, _ := NewBitMask(tc.firstMask...)
   698  		secondMask, _ := NewBitMask(tc.secondMask...)
   699  		expectedFirstGreater := firstMask.IsGreaterThan(secondMask)
   700  		if expectedFirstGreater != tc.expectedFirstGreater {
   701  			t.Errorf("Expected value to be %v, got %v", tc.expectedFirstGreater, expectedFirstGreater)
   702  		}
   703  	}
   704  }
   705  

View as plain text