...

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

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

     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 topologymanager
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"k8s.io/api/core/v1"
    24  	"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
    25  )
    26  
    27  type policyMergeTestCase struct {
    28  	name     string
    29  	hp       []HintProvider
    30  	expected TopologyHint
    31  }
    32  
    33  func commonPolicyMergeTestCases(numaNodes []int) []policyMergeTestCase {
    34  	return []policyMergeTestCase{
    35  		{
    36  			name: "Two providers, 1 hint each, same mask, both preferred 1/2",
    37  			hp: []HintProvider{
    38  				&mockHintProvider{
    39  					map[string][]TopologyHint{
    40  						"resource1": {
    41  							{
    42  								NUMANodeAffinity: NewTestBitMask(0),
    43  								Preferred:        true,
    44  							},
    45  						},
    46  					},
    47  				},
    48  				&mockHintProvider{
    49  					map[string][]TopologyHint{
    50  						"resource2": {
    51  							{
    52  								NUMANodeAffinity: NewTestBitMask(0),
    53  								Preferred:        true,
    54  							},
    55  						},
    56  					},
    57  				},
    58  			},
    59  			expected: TopologyHint{
    60  				NUMANodeAffinity: NewTestBitMask(0),
    61  				Preferred:        true,
    62  			},
    63  		},
    64  		{
    65  			name: "Two providers, 1 hint each, same mask, both preferred 2/2",
    66  			hp: []HintProvider{
    67  				&mockHintProvider{
    68  					map[string][]TopologyHint{
    69  						"resource1": {
    70  							{
    71  								NUMANodeAffinity: NewTestBitMask(1),
    72  								Preferred:        true,
    73  							},
    74  						},
    75  					},
    76  				},
    77  				&mockHintProvider{
    78  					map[string][]TopologyHint{
    79  						"resource2": {
    80  							{
    81  								NUMANodeAffinity: NewTestBitMask(1),
    82  								Preferred:        true,
    83  							},
    84  						},
    85  					},
    86  				},
    87  			},
    88  			expected: TopologyHint{
    89  				NUMANodeAffinity: NewTestBitMask(1),
    90  				Preferred:        true,
    91  			},
    92  		},
    93  		{
    94  			name: "Two providers, 1 no hints, 1 single hint preferred 1/2",
    95  			hp: []HintProvider{
    96  				&mockHintProvider{},
    97  				&mockHintProvider{
    98  					map[string][]TopologyHint{
    99  						"resource": {
   100  							{
   101  								NUMANodeAffinity: NewTestBitMask(0),
   102  								Preferred:        true,
   103  							},
   104  						},
   105  					},
   106  				},
   107  			},
   108  			expected: TopologyHint{
   109  				NUMANodeAffinity: NewTestBitMask(0),
   110  				Preferred:        true,
   111  			},
   112  		},
   113  		{
   114  			name: "Two providers, 1 no hints, 1 single hint preferred 2/2",
   115  			hp: []HintProvider{
   116  				&mockHintProvider{},
   117  				&mockHintProvider{
   118  					map[string][]TopologyHint{
   119  						"resource": {
   120  							{
   121  								NUMANodeAffinity: NewTestBitMask(1),
   122  								Preferred:        true,
   123  							},
   124  						},
   125  					},
   126  				},
   127  			},
   128  			expected: TopologyHint{
   129  				NUMANodeAffinity: NewTestBitMask(1),
   130  				Preferred:        true,
   131  			},
   132  		},
   133  		{
   134  			name: "Two providers, 1 with 2 hints, 1 with single hint matching 1/2",
   135  			hp: []HintProvider{
   136  				&mockHintProvider{
   137  					map[string][]TopologyHint{
   138  						"resource1": {
   139  							{
   140  								NUMANodeAffinity: NewTestBitMask(0),
   141  								Preferred:        true,
   142  							},
   143  							{
   144  								NUMANodeAffinity: NewTestBitMask(1),
   145  								Preferred:        true,
   146  							},
   147  						},
   148  					},
   149  				},
   150  				&mockHintProvider{
   151  					map[string][]TopologyHint{
   152  						"resource2": {
   153  							{
   154  								NUMANodeAffinity: NewTestBitMask(0),
   155  								Preferred:        true,
   156  							},
   157  						},
   158  					},
   159  				},
   160  			},
   161  			expected: TopologyHint{
   162  				NUMANodeAffinity: NewTestBitMask(0),
   163  				Preferred:        true,
   164  			},
   165  		},
   166  		{
   167  			name: "Two providers, 1 with 2 hints, 1 with single hint matching 2/2",
   168  			hp: []HintProvider{
   169  				&mockHintProvider{
   170  					map[string][]TopologyHint{
   171  						"resource1": {
   172  							{
   173  								NUMANodeAffinity: NewTestBitMask(0),
   174  								Preferred:        true,
   175  							},
   176  							{
   177  								NUMANodeAffinity: NewTestBitMask(1),
   178  								Preferred:        true,
   179  							},
   180  						},
   181  					},
   182  				},
   183  				&mockHintProvider{
   184  					map[string][]TopologyHint{
   185  						"resource2": {
   186  							{
   187  								NUMANodeAffinity: NewTestBitMask(1),
   188  								Preferred:        true,
   189  							},
   190  						},
   191  					},
   192  				},
   193  			},
   194  			expected: TopologyHint{
   195  				NUMANodeAffinity: NewTestBitMask(1),
   196  				Preferred:        true,
   197  			},
   198  		},
   199  		{
   200  			name: "Two providers, both with 2 hints, matching narrower preferred hint from both",
   201  			hp: []HintProvider{
   202  				&mockHintProvider{
   203  					map[string][]TopologyHint{
   204  						"resource1": {
   205  							{
   206  								NUMANodeAffinity: NewTestBitMask(0),
   207  								Preferred:        true,
   208  							},
   209  							{
   210  								NUMANodeAffinity: NewTestBitMask(1),
   211  								Preferred:        true,
   212  							},
   213  						},
   214  					},
   215  				},
   216  				&mockHintProvider{
   217  					map[string][]TopologyHint{
   218  						"resource2": {
   219  							{
   220  								NUMANodeAffinity: NewTestBitMask(0),
   221  								Preferred:        true,
   222  							},
   223  							{
   224  								NUMANodeAffinity: NewTestBitMask(0, 1),
   225  								Preferred:        false,
   226  							},
   227  						},
   228  					},
   229  				},
   230  			},
   231  			expected: TopologyHint{
   232  				NUMANodeAffinity: NewTestBitMask(0),
   233  				Preferred:        true,
   234  			},
   235  		},
   236  		{
   237  			name: "Ensure less narrow preferred hints are chosen over narrower non-preferred hints",
   238  			hp: []HintProvider{
   239  				&mockHintProvider{
   240  					map[string][]TopologyHint{
   241  						"resource1": {
   242  							{
   243  								NUMANodeAffinity: NewTestBitMask(1),
   244  								Preferred:        true,
   245  							},
   246  							{
   247  								NUMANodeAffinity: NewTestBitMask(0, 1),
   248  								Preferred:        false,
   249  							},
   250  						},
   251  					},
   252  				},
   253  				&mockHintProvider{
   254  					map[string][]TopologyHint{
   255  						"resource2": {
   256  							{
   257  								NUMANodeAffinity: NewTestBitMask(0),
   258  								Preferred:        true,
   259  							},
   260  							{
   261  								NUMANodeAffinity: NewTestBitMask(1),
   262  								Preferred:        true,
   263  							},
   264  							{
   265  								NUMANodeAffinity: NewTestBitMask(0, 1),
   266  								Preferred:        false,
   267  							},
   268  						},
   269  					},
   270  				},
   271  			},
   272  			expected: TopologyHint{
   273  				NUMANodeAffinity: NewTestBitMask(1),
   274  				Preferred:        true,
   275  			},
   276  		},
   277  		{
   278  			name: "Multiple resources, same provider",
   279  			hp: []HintProvider{
   280  				&mockHintProvider{
   281  					map[string][]TopologyHint{
   282  						"resource1": {
   283  							{
   284  								NUMANodeAffinity: NewTestBitMask(1),
   285  								Preferred:        true,
   286  							},
   287  							{
   288  								NUMANodeAffinity: NewTestBitMask(0, 1),
   289  								Preferred:        false,
   290  							},
   291  						},
   292  						"resource2": {
   293  							{
   294  								NUMANodeAffinity: NewTestBitMask(0),
   295  								Preferred:        true,
   296  							},
   297  							{
   298  								NUMANodeAffinity: NewTestBitMask(1),
   299  								Preferred:        true,
   300  							},
   301  							{
   302  								NUMANodeAffinity: NewTestBitMask(0, 1),
   303  								Preferred:        false,
   304  							},
   305  						},
   306  					},
   307  				},
   308  			},
   309  			expected: TopologyHint{
   310  				NUMANodeAffinity: NewTestBitMask(1),
   311  				Preferred:        true,
   312  			},
   313  		},
   314  	}
   315  }
   316  
   317  func (p *bestEffortPolicy) mergeTestCases(numaNodes []int) []policyMergeTestCase {
   318  	return []policyMergeTestCase{
   319  		{
   320  			name: "Two providers, 2 hints each, same mask (some with different bits), same preferred",
   321  			hp: []HintProvider{
   322  				&mockHintProvider{
   323  					map[string][]TopologyHint{
   324  						"resource1": {
   325  							{
   326  								NUMANodeAffinity: NewTestBitMask(0, 1),
   327  								Preferred:        true,
   328  							},
   329  							{
   330  								NUMANodeAffinity: NewTestBitMask(0, 2),
   331  								Preferred:        true,
   332  							},
   333  						},
   334  					},
   335  				},
   336  				&mockHintProvider{
   337  					map[string][]TopologyHint{
   338  						"resource2": {
   339  							{
   340  								NUMANodeAffinity: NewTestBitMask(0, 1),
   341  								Preferred:        true,
   342  							},
   343  							{
   344  								NUMANodeAffinity: NewTestBitMask(0, 2),
   345  								Preferred:        true,
   346  							},
   347  						},
   348  					},
   349  				},
   350  			},
   351  			expected: TopologyHint{
   352  				NUMANodeAffinity: NewTestBitMask(0, 1),
   353  				Preferred:        true,
   354  			},
   355  		},
   356  		{
   357  			name: "TopologyHint not set",
   358  			hp:   []HintProvider{},
   359  			expected: TopologyHint{
   360  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   361  				Preferred:        true,
   362  			},
   363  		},
   364  		{
   365  			name: "HintProvider returns empty non-nil map[string][]TopologyHint",
   366  			hp: []HintProvider{
   367  				&mockHintProvider{
   368  					map[string][]TopologyHint{},
   369  				},
   370  			},
   371  			expected: TopologyHint{
   372  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   373  				Preferred:        true,
   374  			},
   375  		},
   376  		{
   377  			name: "HintProvider returns -nil map[string][]TopologyHint from provider",
   378  			hp: []HintProvider{
   379  				&mockHintProvider{
   380  					map[string][]TopologyHint{
   381  						"resource": nil,
   382  					},
   383  				},
   384  			},
   385  			expected: TopologyHint{
   386  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   387  				Preferred:        true,
   388  			},
   389  		},
   390  		{
   391  			name: "HintProvider returns empty non-nil map[string][]TopologyHint from provider", hp: []HintProvider{
   392  				&mockHintProvider{
   393  					map[string][]TopologyHint{
   394  						"resource": {},
   395  					},
   396  				},
   397  			},
   398  			expected: TopologyHint{
   399  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   400  				Preferred:        false,
   401  			},
   402  		},
   403  		{
   404  			name: "Single TopologyHint with Preferred as true and NUMANodeAffinity as nil",
   405  			hp: []HintProvider{
   406  				&mockHintProvider{
   407  					map[string][]TopologyHint{
   408  						"resource": {
   409  							{
   410  								NUMANodeAffinity: nil,
   411  								Preferred:        true,
   412  							},
   413  						},
   414  					},
   415  				},
   416  			},
   417  			expected: TopologyHint{
   418  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   419  				Preferred:        true,
   420  			},
   421  		},
   422  		{
   423  			name: "Single TopologyHint with Preferred as false and NUMANodeAffinity as nil",
   424  			hp: []HintProvider{
   425  				&mockHintProvider{
   426  					map[string][]TopologyHint{
   427  						"resource": {
   428  							{
   429  								NUMANodeAffinity: nil,
   430  								Preferred:        false,
   431  							},
   432  						},
   433  					},
   434  				},
   435  			},
   436  			expected: TopologyHint{
   437  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   438  				Preferred:        false,
   439  			},
   440  		},
   441  		{
   442  			name: "Two providers, 1 hint each, no common mask",
   443  			hp: []HintProvider{
   444  				&mockHintProvider{
   445  					map[string][]TopologyHint{
   446  						"resource1": {
   447  							{
   448  								NUMANodeAffinity: NewTestBitMask(0),
   449  								Preferred:        true,
   450  							},
   451  						},
   452  					},
   453  				},
   454  				&mockHintProvider{
   455  					map[string][]TopologyHint{
   456  						"resource2": {
   457  							{
   458  								NUMANodeAffinity: NewTestBitMask(1),
   459  								Preferred:        true,
   460  							},
   461  						},
   462  					},
   463  				},
   464  			},
   465  			expected: TopologyHint{
   466  				NUMANodeAffinity: NewTestBitMask(numaNodes...),
   467  				Preferred:        false,
   468  			},
   469  		},
   470  		{
   471  			name: "Two providers, 1 hint each, same mask, 1 preferred, 1 not 1/2",
   472  			hp: []HintProvider{
   473  				&mockHintProvider{
   474  					map[string][]TopologyHint{
   475  						"resource1": {
   476  							{
   477  								NUMANodeAffinity: NewTestBitMask(0),
   478  								Preferred:        true,
   479  							},
   480  						},
   481  					},
   482  				},
   483  				&mockHintProvider{
   484  					map[string][]TopologyHint{
   485  						"resource2": {
   486  							{
   487  								NUMANodeAffinity: NewTestBitMask(0),
   488  								Preferred:        false,
   489  							},
   490  						},
   491  					},
   492  				},
   493  			},
   494  			expected: TopologyHint{
   495  				NUMANodeAffinity: NewTestBitMask(0),
   496  				Preferred:        false,
   497  			},
   498  		},
   499  		{
   500  			name: "Two providers, 1 hint each, same mask, 1 preferred, 1 not 2/2",
   501  			hp: []HintProvider{
   502  				&mockHintProvider{
   503  					map[string][]TopologyHint{
   504  						"resource1": {
   505  							{
   506  								NUMANodeAffinity: NewTestBitMask(1),
   507  								Preferred:        true,
   508  							},
   509  						},
   510  					},
   511  				},
   512  				&mockHintProvider{
   513  					map[string][]TopologyHint{
   514  						"resource2": {
   515  							{
   516  								NUMANodeAffinity: NewTestBitMask(1),
   517  								Preferred:        false,
   518  							},
   519  						},
   520  					},
   521  				},
   522  			},
   523  			expected: TopologyHint{
   524  				NUMANodeAffinity: NewTestBitMask(1),
   525  				Preferred:        false,
   526  			},
   527  		},
   528  		{
   529  			name: "Two providers, 1 hint each, 1 wider mask, both preferred 1/2",
   530  			hp: []HintProvider{
   531  				&mockHintProvider{
   532  					map[string][]TopologyHint{
   533  						"resource1": {
   534  							{
   535  								NUMANodeAffinity: NewTestBitMask(0),
   536  								Preferred:        true,
   537  							},
   538  						},
   539  					},
   540  				},
   541  				&mockHintProvider{
   542  					map[string][]TopologyHint{
   543  						"resource2": {
   544  							{
   545  								NUMANodeAffinity: NewTestBitMask(0, 1),
   546  								Preferred:        true,
   547  							},
   548  						},
   549  					},
   550  				},
   551  			},
   552  			expected: TopologyHint{
   553  				NUMANodeAffinity: NewTestBitMask(0),
   554  				Preferred:        false,
   555  			},
   556  		},
   557  		{
   558  			name: "Two providers, 1 with 2 hints, 1 with single non-preferred hint matching",
   559  			hp: []HintProvider{
   560  				&mockHintProvider{
   561  					map[string][]TopologyHint{
   562  						"resource1": {
   563  							{
   564  								NUMANodeAffinity: NewTestBitMask(0),
   565  								Preferred:        true,
   566  							},
   567  							{
   568  								NUMANodeAffinity: NewTestBitMask(1),
   569  								Preferred:        true,
   570  							},
   571  						},
   572  					},
   573  				},
   574  				&mockHintProvider{
   575  					map[string][]TopologyHint{
   576  						"resource2": {
   577  							{
   578  								NUMANodeAffinity: NewTestBitMask(0, 1),
   579  								Preferred:        false,
   580  							},
   581  						},
   582  					},
   583  				},
   584  			},
   585  			expected: TopologyHint{
   586  				NUMANodeAffinity: NewTestBitMask(0),
   587  				Preferred:        false,
   588  			},
   589  		},
   590  		{
   591  			name: "Two providers, 1 hint each, 1 wider mask, both preferred 2/2",
   592  			hp: []HintProvider{
   593  				&mockHintProvider{
   594  					map[string][]TopologyHint{
   595  						"resource1": {
   596  							{
   597  								NUMANodeAffinity: NewTestBitMask(1),
   598  								Preferred:        true,
   599  							},
   600  						},
   601  					},
   602  				},
   603  				&mockHintProvider{
   604  					map[string][]TopologyHint{
   605  						"resource2": {
   606  							{
   607  								NUMANodeAffinity: NewTestBitMask(0, 1),
   608  								Preferred:        true,
   609  							},
   610  						},
   611  					},
   612  				},
   613  			},
   614  			expected: TopologyHint{
   615  				NUMANodeAffinity: NewTestBitMask(1),
   616  				Preferred:        false,
   617  			},
   618  		},
   619  		{
   620  			name: "bestNonPreferredAffinityCount (1)",
   621  			hp: []HintProvider{
   622  				&mockHintProvider{
   623  					map[string][]TopologyHint{
   624  						"resource1": {
   625  							{
   626  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   627  								Preferred:        false,
   628  							},
   629  							{
   630  								NUMANodeAffinity: NewTestBitMask(0, 1),
   631  								Preferred:        false,
   632  							},
   633  						},
   634  					},
   635  				},
   636  				&mockHintProvider{
   637  					map[string][]TopologyHint{
   638  						"resource2": {
   639  							{
   640  								NUMANodeAffinity: NewTestBitMask(0, 1),
   641  								Preferred:        false,
   642  							},
   643  						},
   644  					},
   645  				},
   646  			},
   647  			expected: TopologyHint{
   648  				NUMANodeAffinity: NewTestBitMask(0, 1),
   649  				Preferred:        false,
   650  			},
   651  		},
   652  		{
   653  			name: "bestNonPreferredAffinityCount (2)",
   654  			hp: []HintProvider{
   655  				&mockHintProvider{
   656  					map[string][]TopologyHint{
   657  						"resource1": {
   658  							{
   659  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   660  								Preferred:        false,
   661  							},
   662  							{
   663  								NUMANodeAffinity: NewTestBitMask(0, 1),
   664  								Preferred:        false,
   665  							},
   666  						},
   667  					},
   668  				},
   669  				&mockHintProvider{
   670  					map[string][]TopologyHint{
   671  						"resource2": {
   672  							{
   673  								NUMANodeAffinity: NewTestBitMask(0, 3),
   674  								Preferred:        false,
   675  							},
   676  						},
   677  					},
   678  				},
   679  			},
   680  			expected: TopologyHint{
   681  				NUMANodeAffinity: NewTestBitMask(0, 3),
   682  				Preferred:        false,
   683  			},
   684  		},
   685  		{
   686  			name: "bestNonPreferredAffinityCount (3)",
   687  			hp: []HintProvider{
   688  				&mockHintProvider{
   689  					map[string][]TopologyHint{
   690  						"resource1": {
   691  							{
   692  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   693  								Preferred:        false,
   694  							},
   695  							{
   696  								NUMANodeAffinity: NewTestBitMask(0, 1),
   697  								Preferred:        false,
   698  							},
   699  						},
   700  					},
   701  				},
   702  				&mockHintProvider{
   703  					map[string][]TopologyHint{
   704  						"resource2": {
   705  							{
   706  								NUMANodeAffinity: NewTestBitMask(1, 2),
   707  								Preferred:        false,
   708  							},
   709  						},
   710  					},
   711  				},
   712  			},
   713  			expected: TopologyHint{
   714  				NUMANodeAffinity: NewTestBitMask(1, 2),
   715  				Preferred:        false,
   716  			},
   717  		},
   718  		{
   719  			name: "bestNonPreferredAffinityCount (4)",
   720  			hp: []HintProvider{
   721  				&mockHintProvider{
   722  					map[string][]TopologyHint{
   723  						"resource1": {
   724  							{
   725  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   726  								Preferred:        false,
   727  							},
   728  							{
   729  								NUMANodeAffinity: NewTestBitMask(0, 1),
   730  								Preferred:        false,
   731  							},
   732  						},
   733  					},
   734  				},
   735  				&mockHintProvider{
   736  					map[string][]TopologyHint{
   737  						"resource2": {
   738  							{
   739  								NUMANodeAffinity: NewTestBitMask(2, 3),
   740  								Preferred:        false,
   741  							},
   742  						},
   743  					},
   744  				},
   745  			},
   746  			expected: TopologyHint{
   747  				NUMANodeAffinity: NewTestBitMask(2, 3),
   748  				Preferred:        false,
   749  			},
   750  		},
   751  	}
   752  }
   753  
   754  func (p *bestEffortPolicy) mergeTestCasesNoPolicies(numaNodes []int) []policyMergeTestCase {
   755  	return []policyMergeTestCase{
   756  		{
   757  			name: "bestNonPreferredAffinityCount (5)",
   758  			hp: []HintProvider{
   759  				&mockHintProvider{
   760  					map[string][]TopologyHint{
   761  						"resource1": {
   762  							{
   763  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   764  								Preferred:        false,
   765  							},
   766  							{
   767  								NUMANodeAffinity: NewTestBitMask(0, 1),
   768  								Preferred:        false,
   769  							},
   770  						},
   771  					},
   772  				},
   773  				&mockHintProvider{
   774  					map[string][]TopologyHint{
   775  						"resource2": {
   776  							{
   777  								NUMANodeAffinity: NewTestBitMask(1, 2),
   778  								Preferred:        false,
   779  							},
   780  							{
   781  								NUMANodeAffinity: NewTestBitMask(2, 3),
   782  								Preferred:        false,
   783  							},
   784  						},
   785  					},
   786  				},
   787  			},
   788  			expected: TopologyHint{
   789  				NUMANodeAffinity: NewTestBitMask(1, 2),
   790  				Preferred:        false,
   791  			},
   792  		},
   793  		{
   794  			name: "bestNonPreferredAffinityCount (6)",
   795  			hp: []HintProvider{
   796  				&mockHintProvider{
   797  					map[string][]TopologyHint{
   798  						"resource1": {
   799  							{
   800  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   801  								Preferred:        false,
   802  							},
   803  							{
   804  								NUMANodeAffinity: NewTestBitMask(0, 1),
   805  								Preferred:        false,
   806  							},
   807  						},
   808  					},
   809  				},
   810  				&mockHintProvider{
   811  					map[string][]TopologyHint{
   812  						"resource2": {
   813  							{
   814  								NUMANodeAffinity: NewTestBitMask(1, 2, 3),
   815  								Preferred:        false,
   816  							},
   817  							{
   818  								NUMANodeAffinity: NewTestBitMask(1, 2),
   819  								Preferred:        false,
   820  							},
   821  							{
   822  								NUMANodeAffinity: NewTestBitMask(1, 3),
   823  								Preferred:        false,
   824  							},
   825  							{
   826  								NUMANodeAffinity: NewTestBitMask(2, 3),
   827  								Preferred:        false,
   828  							},
   829  						},
   830  					},
   831  				},
   832  			},
   833  			expected: TopologyHint{
   834  				NUMANodeAffinity: NewTestBitMask(1, 2),
   835  				Preferred:        false,
   836  			},
   837  		},
   838  	}
   839  }
   840  
   841  func (p *bestEffortPolicy) mergeTestCasesClosestNUMA(numaNodes []int) []policyMergeTestCase {
   842  	return []policyMergeTestCase{
   843  		{
   844  			name: "Two providers, 2 hints each, same mask (some with different bits), same preferred",
   845  			hp: []HintProvider{
   846  				&mockHintProvider{
   847  					map[string][]TopologyHint{
   848  						"resource1": {
   849  							{
   850  								NUMANodeAffinity: NewTestBitMask(0, 4),
   851  								Preferred:        true,
   852  							},
   853  							{
   854  								NUMANodeAffinity: NewTestBitMask(0, 2),
   855  								Preferred:        true,
   856  							},
   857  						},
   858  					},
   859  				},
   860  				&mockHintProvider{
   861  					map[string][]TopologyHint{
   862  						"resource2": {
   863  							{
   864  								NUMANodeAffinity: NewTestBitMask(0, 4),
   865  								Preferred:        true,
   866  							},
   867  							{
   868  								NUMANodeAffinity: NewTestBitMask(0, 2),
   869  								Preferred:        true,
   870  							},
   871  						},
   872  					},
   873  				},
   874  			},
   875  			expected: TopologyHint{
   876  				NUMANodeAffinity: NewTestBitMask(0, 2),
   877  				Preferred:        true,
   878  			},
   879  		},
   880  		{
   881  			name: "Two providers, 2 hints each, different mask",
   882  			hp: []HintProvider{
   883  				&mockHintProvider{
   884  					map[string][]TopologyHint{
   885  						"resource1": {
   886  							{
   887  								NUMANodeAffinity: NewTestBitMask(4),
   888  								Preferred:        true,
   889  							},
   890  							{
   891  								NUMANodeAffinity: NewTestBitMask(0, 2),
   892  								Preferred:        true,
   893  							},
   894  						},
   895  					},
   896  				},
   897  				&mockHintProvider{
   898  					map[string][]TopologyHint{
   899  						"resource2": {
   900  							{
   901  								NUMANodeAffinity: NewTestBitMask(4),
   902  								Preferred:        true,
   903  							},
   904  							{
   905  								NUMANodeAffinity: NewTestBitMask(0, 2),
   906  								Preferred:        true,
   907  							},
   908  						},
   909  					},
   910  				},
   911  			},
   912  			expected: TopologyHint{
   913  				NUMANodeAffinity: NewTestBitMask(4),
   914  				Preferred:        true,
   915  			},
   916  		},
   917  		{
   918  			name: "bestNonPreferredAffinityCount (5)",
   919  			hp: []HintProvider{
   920  				&mockHintProvider{
   921  					map[string][]TopologyHint{
   922  						"resource1": {
   923  							{
   924  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   925  								Preferred:        false,
   926  							},
   927  							{
   928  								NUMANodeAffinity: NewTestBitMask(0, 1),
   929  								Preferred:        false,
   930  							},
   931  						},
   932  					},
   933  				},
   934  				&mockHintProvider{
   935  					map[string][]TopologyHint{
   936  						"resource2": {
   937  							{
   938  								NUMANodeAffinity: NewTestBitMask(1, 2),
   939  								Preferred:        false,
   940  							},
   941  							{
   942  								NUMANodeAffinity: NewTestBitMask(2, 3),
   943  								Preferred:        false,
   944  							},
   945  						},
   946  					},
   947  				},
   948  			},
   949  			expected: TopologyHint{
   950  				NUMANodeAffinity: NewTestBitMask(2, 3),
   951  				Preferred:        false,
   952  			},
   953  		},
   954  		{
   955  			name: "bestNonPreferredAffinityCount (6)",
   956  			hp: []HintProvider{
   957  				&mockHintProvider{
   958  					map[string][]TopologyHint{
   959  						"resource1": {
   960  							{
   961  								NUMANodeAffinity: NewTestBitMask(0, 1, 2, 3),
   962  								Preferred:        false,
   963  							},
   964  							{
   965  								NUMANodeAffinity: NewTestBitMask(0, 1),
   966  								Preferred:        false,
   967  							},
   968  						},
   969  					},
   970  				},
   971  				&mockHintProvider{
   972  					map[string][]TopologyHint{
   973  						"resource2": {
   974  							{
   975  								NUMANodeAffinity: NewTestBitMask(1, 2, 3),
   976  								Preferred:        false,
   977  							},
   978  							{
   979  								NUMANodeAffinity: NewTestBitMask(1, 2),
   980  								Preferred:        false,
   981  							},
   982  							{
   983  								NUMANodeAffinity: NewTestBitMask(1, 3),
   984  								Preferred:        false,
   985  							},
   986  							{
   987  								NUMANodeAffinity: NewTestBitMask(2, 3),
   988  								Preferred:        false,
   989  							},
   990  						},
   991  					},
   992  				},
   993  			},
   994  			expected: TopologyHint{
   995  				NUMANodeAffinity: NewTestBitMask(2, 3),
   996  				Preferred:        false,
   997  			},
   998  		},
   999  	}
  1000  }
  1001  
  1002  func (p *singleNumaNodePolicy) mergeTestCases(numaNodes []int) []policyMergeTestCase {
  1003  	return []policyMergeTestCase{
  1004  		{
  1005  			name: "TopologyHint not set",
  1006  			hp:   []HintProvider{},
  1007  			expected: TopologyHint{
  1008  				NUMANodeAffinity: nil,
  1009  				Preferred:        true,
  1010  			},
  1011  		},
  1012  		{
  1013  			name: "HintProvider returns empty non-nil map[string][]TopologyHint",
  1014  			hp: []HintProvider{
  1015  				&mockHintProvider{
  1016  					map[string][]TopologyHint{},
  1017  				},
  1018  			},
  1019  			expected: TopologyHint{
  1020  				NUMANodeAffinity: nil,
  1021  				Preferred:        true,
  1022  			},
  1023  		},
  1024  		{
  1025  			name: "HintProvider returns -nil map[string][]TopologyHint from provider",
  1026  			hp: []HintProvider{
  1027  				&mockHintProvider{
  1028  					map[string][]TopologyHint{
  1029  						"resource": nil,
  1030  					},
  1031  				},
  1032  			},
  1033  			expected: TopologyHint{
  1034  				NUMANodeAffinity: nil,
  1035  				Preferred:        true,
  1036  			},
  1037  		},
  1038  		{
  1039  			name: "HintProvider returns empty non-nil map[string][]TopologyHint from provider", hp: []HintProvider{
  1040  				&mockHintProvider{
  1041  					map[string][]TopologyHint{
  1042  						"resource": {},
  1043  					},
  1044  				},
  1045  			},
  1046  			expected: TopologyHint{
  1047  				NUMANodeAffinity: nil,
  1048  				Preferred:        false,
  1049  			},
  1050  		},
  1051  		{
  1052  			name: "Single TopologyHint with Preferred as true and NUMANodeAffinity as nil",
  1053  			hp: []HintProvider{
  1054  				&mockHintProvider{
  1055  					map[string][]TopologyHint{
  1056  						"resource": {
  1057  							{
  1058  								NUMANodeAffinity: nil,
  1059  								Preferred:        true,
  1060  							},
  1061  						},
  1062  					},
  1063  				},
  1064  			},
  1065  			expected: TopologyHint{
  1066  				NUMANodeAffinity: nil,
  1067  				Preferred:        true,
  1068  			},
  1069  		},
  1070  		{
  1071  			name: "Single TopologyHint with Preferred as false and NUMANodeAffinity as nil",
  1072  			hp: []HintProvider{
  1073  				&mockHintProvider{
  1074  					map[string][]TopologyHint{
  1075  						"resource": {
  1076  							{
  1077  								NUMANodeAffinity: nil,
  1078  								Preferred:        false,
  1079  							},
  1080  						},
  1081  					},
  1082  				},
  1083  			},
  1084  			expected: TopologyHint{
  1085  				NUMANodeAffinity: nil,
  1086  				Preferred:        false,
  1087  			},
  1088  		},
  1089  		{
  1090  			name: "Two providers, 1 hint each, no common mask",
  1091  			hp: []HintProvider{
  1092  				&mockHintProvider{
  1093  					map[string][]TopologyHint{
  1094  						"resource1": {
  1095  							{
  1096  								NUMANodeAffinity: NewTestBitMask(0),
  1097  								Preferred:        true,
  1098  							},
  1099  						},
  1100  					},
  1101  				},
  1102  				&mockHintProvider{
  1103  					map[string][]TopologyHint{
  1104  						"resource2": {
  1105  							{
  1106  								NUMANodeAffinity: NewTestBitMask(1),
  1107  								Preferred:        true,
  1108  							},
  1109  						},
  1110  					},
  1111  				},
  1112  			},
  1113  			expected: TopologyHint{
  1114  				NUMANodeAffinity: nil,
  1115  				Preferred:        false,
  1116  			},
  1117  		},
  1118  		{
  1119  			name: "Two providers, 1 hint each, same mask, 1 preferred, 1 not 1/2",
  1120  			hp: []HintProvider{
  1121  				&mockHintProvider{
  1122  					map[string][]TopologyHint{
  1123  						"resource1": {
  1124  							{
  1125  								NUMANodeAffinity: NewTestBitMask(0),
  1126  								Preferred:        true,
  1127  							},
  1128  						},
  1129  					},
  1130  				},
  1131  				&mockHintProvider{
  1132  					map[string][]TopologyHint{
  1133  						"resource2": {
  1134  							{
  1135  								NUMANodeAffinity: NewTestBitMask(0),
  1136  								Preferred:        false,
  1137  							},
  1138  						},
  1139  					},
  1140  				},
  1141  			},
  1142  			expected: TopologyHint{
  1143  				NUMANodeAffinity: nil,
  1144  				Preferred:        false,
  1145  			},
  1146  		},
  1147  		{
  1148  			name: "Two providers, 1 hint each, same mask, 1 preferred, 1 not 2/2",
  1149  			hp: []HintProvider{
  1150  				&mockHintProvider{
  1151  					map[string][]TopologyHint{
  1152  						"resource1": {
  1153  							{
  1154  								NUMANodeAffinity: NewTestBitMask(1),
  1155  								Preferred:        true,
  1156  							},
  1157  						},
  1158  					},
  1159  				},
  1160  				&mockHintProvider{
  1161  					map[string][]TopologyHint{
  1162  						"resource2": {
  1163  							{
  1164  								NUMANodeAffinity: NewTestBitMask(1),
  1165  								Preferred:        false,
  1166  							},
  1167  						},
  1168  					},
  1169  				},
  1170  			},
  1171  			expected: TopologyHint{
  1172  				NUMANodeAffinity: nil,
  1173  				Preferred:        false,
  1174  			},
  1175  		},
  1176  		{
  1177  			name: "Two providers, 1 with 2 hints, 1 with single non-preferred hint matching",
  1178  			hp: []HintProvider{
  1179  				&mockHintProvider{
  1180  					map[string][]TopologyHint{
  1181  						"resource1": {
  1182  							{
  1183  								NUMANodeAffinity: NewTestBitMask(0),
  1184  								Preferred:        true,
  1185  							},
  1186  							{
  1187  								NUMANodeAffinity: NewTestBitMask(1),
  1188  								Preferred:        true,
  1189  							},
  1190  						},
  1191  					},
  1192  				},
  1193  				&mockHintProvider{
  1194  					map[string][]TopologyHint{
  1195  						"resource2": {
  1196  							{
  1197  								NUMANodeAffinity: NewTestBitMask(0, 1),
  1198  								Preferred:        false,
  1199  							},
  1200  						},
  1201  					},
  1202  				},
  1203  			},
  1204  			expected: TopologyHint{
  1205  				NUMANodeAffinity: nil,
  1206  				Preferred:        false,
  1207  			},
  1208  		},
  1209  		{
  1210  			name: "Single NUMA hint generation",
  1211  			hp: []HintProvider{
  1212  				&mockHintProvider{
  1213  					map[string][]TopologyHint{
  1214  						"resource1": {
  1215  							{
  1216  								NUMANodeAffinity: NewTestBitMask(0, 1),
  1217  								Preferred:        true,
  1218  							},
  1219  						},
  1220  						"resource2": {
  1221  							{
  1222  								NUMANodeAffinity: NewTestBitMask(0),
  1223  								Preferred:        true,
  1224  							},
  1225  							{
  1226  								NUMANodeAffinity: NewTestBitMask(1),
  1227  								Preferred:        true,
  1228  							},
  1229  							{
  1230  								NUMANodeAffinity: NewTestBitMask(0, 1),
  1231  								Preferred:        false,
  1232  							},
  1233  						},
  1234  					},
  1235  				},
  1236  			},
  1237  			expected: TopologyHint{
  1238  				NUMANodeAffinity: nil,
  1239  				Preferred:        false,
  1240  			},
  1241  		},
  1242  		{
  1243  			name: "One no-preference provider",
  1244  			hp: []HintProvider{
  1245  				&mockHintProvider{
  1246  					map[string][]TopologyHint{
  1247  						"resource1": {
  1248  							{
  1249  								NUMANodeAffinity: NewTestBitMask(0),
  1250  								Preferred:        true,
  1251  							},
  1252  							{
  1253  								NUMANodeAffinity: NewTestBitMask(1),
  1254  								Preferred:        true,
  1255  							},
  1256  							{
  1257  								NUMANodeAffinity: NewTestBitMask(0, 1),
  1258  								Preferred:        false,
  1259  							},
  1260  						},
  1261  					},
  1262  				},
  1263  				&mockHintProvider{
  1264  					nil,
  1265  				},
  1266  			},
  1267  			expected: TopologyHint{
  1268  				NUMANodeAffinity: NewTestBitMask(0),
  1269  				Preferred:        true,
  1270  			},
  1271  		},
  1272  	}
  1273  }
  1274  
  1275  func testPolicyMerge(policy Policy, tcases []policyMergeTestCase, t *testing.T) {
  1276  	for _, tc := range tcases {
  1277  		var providersHints []map[string][]TopologyHint
  1278  		for _, provider := range tc.hp {
  1279  			hints := provider.GetTopologyHints(&v1.Pod{}, &v1.Container{})
  1280  			providersHints = append(providersHints, hints)
  1281  		}
  1282  
  1283  		actual, _ := policy.Merge(providersHints)
  1284  		if !reflect.DeepEqual(actual, tc.expected) {
  1285  			t.Errorf("%v: Expected Topology Hint to be %v, got %v:", tc.name, tc.expected, actual)
  1286  		}
  1287  	}
  1288  }
  1289  
  1290  func TestMaxOfMinAffinityCounts(t *testing.T) {
  1291  	tcases := []struct {
  1292  		hints    [][]TopologyHint
  1293  		expected int
  1294  	}{
  1295  		{
  1296  			[][]TopologyHint{},
  1297  			0,
  1298  		},
  1299  		{
  1300  			[][]TopologyHint{
  1301  				{
  1302  					TopologyHint{NewTestBitMask(), true},
  1303  				},
  1304  			},
  1305  			0,
  1306  		},
  1307  		{
  1308  			[][]TopologyHint{
  1309  				{
  1310  					TopologyHint{NewTestBitMask(0), true},
  1311  				},
  1312  			},
  1313  			1,
  1314  		},
  1315  		{
  1316  			[][]TopologyHint{
  1317  				{
  1318  					TopologyHint{NewTestBitMask(0, 1), true},
  1319  				},
  1320  			},
  1321  			2,
  1322  		},
  1323  		{
  1324  			[][]TopologyHint{
  1325  				{
  1326  					TopologyHint{NewTestBitMask(0, 1), true},
  1327  					TopologyHint{NewTestBitMask(0, 1, 2), true},
  1328  				},
  1329  			},
  1330  			2,
  1331  		},
  1332  		{
  1333  			[][]TopologyHint{
  1334  				{
  1335  					TopologyHint{NewTestBitMask(0, 1), true},
  1336  					TopologyHint{NewTestBitMask(0, 1, 2), true},
  1337  				},
  1338  				{
  1339  					TopologyHint{NewTestBitMask(0, 1, 2), true},
  1340  				},
  1341  			},
  1342  			3,
  1343  		},
  1344  		{
  1345  			[][]TopologyHint{
  1346  				{
  1347  					TopologyHint{NewTestBitMask(0, 1), true},
  1348  					TopologyHint{NewTestBitMask(0, 1, 2), true},
  1349  				},
  1350  				{
  1351  					TopologyHint{NewTestBitMask(0, 1, 2), true},
  1352  					TopologyHint{NewTestBitMask(0, 1, 2, 3), true},
  1353  				},
  1354  			},
  1355  			3,
  1356  		},
  1357  	}
  1358  
  1359  	for _, tc := range tcases {
  1360  		t.Run("", func(t *testing.T) {
  1361  			result := maxOfMinAffinityCounts(tc.hints)
  1362  			if result != tc.expected {
  1363  				t.Errorf("Expected result to be %v, got %v", tc.expected, result)
  1364  			}
  1365  		})
  1366  	}
  1367  }
  1368  
  1369  func TestCompareHintsNarrowest(t *testing.T) {
  1370  	tcases := []struct {
  1371  		description                   string
  1372  		bestNonPreferredAffinityCount int
  1373  		current                       *TopologyHint
  1374  		candidate                     *TopologyHint
  1375  		expected                      string
  1376  	}{
  1377  		{
  1378  			"candidate.NUMANodeAffinity.Count() == 0 (1)",
  1379  			-1,
  1380  			nil,
  1381  			&TopologyHint{bitmask.NewEmptyBitMask(), false},
  1382  			"current",
  1383  		},
  1384  		{
  1385  			"candidate.NUMANodeAffinity.Count() == 0 (2)",
  1386  			-1,
  1387  			&TopologyHint{NewTestBitMask(), true},
  1388  			&TopologyHint{NewTestBitMask(), false},
  1389  			"current",
  1390  		},
  1391  		{
  1392  			"current == nil (1)",
  1393  			-1,
  1394  			nil,
  1395  			&TopologyHint{NewTestBitMask(0), true},
  1396  			"candidate",
  1397  		},
  1398  		{
  1399  			"current == nil (2)",
  1400  			-1,
  1401  			nil,
  1402  			&TopologyHint{NewTestBitMask(0), false},
  1403  			"candidate",
  1404  		},
  1405  		{
  1406  			"!current.Preferred && candidate.Preferred",
  1407  			-1,
  1408  			&TopologyHint{NewTestBitMask(0), false},
  1409  			&TopologyHint{NewTestBitMask(0), true},
  1410  			"candidate",
  1411  		},
  1412  		{
  1413  			"current.Preferred && !candidate.Preferred",
  1414  			-1,
  1415  			&TopologyHint{NewTestBitMask(0), true},
  1416  			&TopologyHint{NewTestBitMask(0), false},
  1417  			"current",
  1418  		},
  1419  		{
  1420  			"current.Preferred && candidate.Preferred (1)",
  1421  			-1,
  1422  			&TopologyHint{NewTestBitMask(0), true},
  1423  			&TopologyHint{NewTestBitMask(0), true},
  1424  			"current",
  1425  		},
  1426  		{
  1427  			"current.Preferred && candidate.Preferred (2)",
  1428  			-1,
  1429  			&TopologyHint{NewTestBitMask(0, 1), true},
  1430  			&TopologyHint{NewTestBitMask(0), true},
  1431  			"candidate",
  1432  		},
  1433  		{
  1434  			"current.Preferred && candidate.Preferred (3)",
  1435  			-1,
  1436  			&TopologyHint{NewTestBitMask(0), true},
  1437  			&TopologyHint{NewTestBitMask(0, 1), true},
  1438  			"current",
  1439  		},
  1440  		{
  1441  			"!current.Preferred && !candidate.Preferred (1.1)",
  1442  			1,
  1443  			&TopologyHint{NewTestBitMask(0, 1), false},
  1444  			&TopologyHint{NewTestBitMask(0, 1), false},
  1445  			"current",
  1446  		},
  1447  		{
  1448  			"!current.Preferred && !candidate.Preferred (1.2)",
  1449  			1,
  1450  			&TopologyHint{NewTestBitMask(1, 2), false},
  1451  			&TopologyHint{NewTestBitMask(0, 1), false},
  1452  			"candidate",
  1453  		},
  1454  		{
  1455  			"!current.Preferred && !candidate.Preferred (1.3)",
  1456  			1,
  1457  			&TopologyHint{NewTestBitMask(0, 1), false},
  1458  			&TopologyHint{NewTestBitMask(1, 2), false},
  1459  			"current",
  1460  		},
  1461  		{
  1462  			"!current.Preferred && !candidate.Preferred (2.1)",
  1463  			2,
  1464  			&TopologyHint{NewTestBitMask(0, 1), false},
  1465  			&TopologyHint{NewTestBitMask(0), false},
  1466  			"current",
  1467  		},
  1468  		{
  1469  			"!current.Preferred && !candidate.Preferred (2.2)",
  1470  			2,
  1471  			&TopologyHint{NewTestBitMask(0, 1), false},
  1472  			&TopologyHint{NewTestBitMask(0, 1), false},
  1473  			"current",
  1474  		},
  1475  		{
  1476  			"!current.Preferred && !candidate.Preferred (2.3)",
  1477  			2,
  1478  			&TopologyHint{NewTestBitMask(1, 2), false},
  1479  			&TopologyHint{NewTestBitMask(0, 1), false},
  1480  			"candidate",
  1481  		},
  1482  		{
  1483  			"!current.Preferred && !candidate.Preferred (2.4)",
  1484  			2,
  1485  			&TopologyHint{NewTestBitMask(0, 1), false},
  1486  			&TopologyHint{NewTestBitMask(1, 2), false},
  1487  			"current",
  1488  		},
  1489  		{
  1490  			"!current.Preferred && !candidate.Preferred (3a)",
  1491  			2,
  1492  			&TopologyHint{NewTestBitMask(0), false},
  1493  			&TopologyHint{NewTestBitMask(0, 1, 2), false},
  1494  			"current",
  1495  		},
  1496  		{
  1497  			"!current.Preferred && !candidate.Preferred (3b)",
  1498  			2,
  1499  			&TopologyHint{NewTestBitMask(0), false},
  1500  			&TopologyHint{NewTestBitMask(0, 1), false},
  1501  			"candidate",
  1502  		},
  1503  		{
  1504  			"!current.Preferred && !candidate.Preferred (3ca.1)",
  1505  			3,
  1506  			&TopologyHint{NewTestBitMask(0), false},
  1507  			&TopologyHint{NewTestBitMask(0, 1), false},
  1508  			"candidate",
  1509  		},
  1510  		{
  1511  			"!current.Preferred && !candidate.Preferred (3ca.2)",
  1512  			3,
  1513  			&TopologyHint{NewTestBitMask(0), false},
  1514  			&TopologyHint{NewTestBitMask(1, 2), false},
  1515  			"candidate",
  1516  		},
  1517  		{
  1518  			"!current.Preferred && !candidate.Preferred (3ca.3)",
  1519  			4,
  1520  			&TopologyHint{NewTestBitMask(0, 1), false},
  1521  			&TopologyHint{NewTestBitMask(1, 2, 3), false},
  1522  			"candidate",
  1523  		},
  1524  		{
  1525  			"!current.Preferred && !candidate.Preferred (3cb)",
  1526  			4,
  1527  			&TopologyHint{NewTestBitMask(1, 2, 3), false},
  1528  			&TopologyHint{NewTestBitMask(0, 1), false},
  1529  			"current",
  1530  		},
  1531  		{
  1532  			"!current.Preferred && !candidate.Preferred (3cc.1)",
  1533  			4,
  1534  			&TopologyHint{NewTestBitMask(0, 1, 2), false},
  1535  			&TopologyHint{NewTestBitMask(0, 1, 2), false},
  1536  			"current",
  1537  		},
  1538  		{
  1539  			"!current.Preferred && !candidate.Preferred (3cc.2)",
  1540  			4,
  1541  			&TopologyHint{NewTestBitMask(0, 1, 2), false},
  1542  			&TopologyHint{NewTestBitMask(1, 2, 3), false},
  1543  			"current",
  1544  		},
  1545  		{
  1546  			"!current.Preferred && !candidate.Preferred (3cc.3)",
  1547  			4,
  1548  			&TopologyHint{NewTestBitMask(1, 2, 3), false},
  1549  			&TopologyHint{NewTestBitMask(0, 1, 2), false},
  1550  			"candidate",
  1551  		},
  1552  	}
  1553  
  1554  	for _, tc := range tcases {
  1555  		t.Run(tc.description, func(t *testing.T) {
  1556  			numaInfo := &NUMAInfo{}
  1557  			merger := NewHintMerger(numaInfo, [][]TopologyHint{}, PolicyBestEffort, PolicyOptions{})
  1558  			merger.BestNonPreferredAffinityCount = tc.bestNonPreferredAffinityCount
  1559  
  1560  			result := merger.compare(tc.current, tc.candidate)
  1561  			if result != tc.current && result != tc.candidate {
  1562  				t.Errorf("Expected result to be either 'current' or 'candidate' hint")
  1563  			}
  1564  			if tc.expected == "current" && result != tc.current {
  1565  				t.Errorf("Expected result to be %v, got %v", tc.current, result)
  1566  			}
  1567  			if tc.expected == "candidate" && result != tc.candidate {
  1568  				t.Errorf("Expected result to be %v, got %v", tc.candidate, result)
  1569  			}
  1570  		})
  1571  	}
  1572  }
  1573  
  1574  func commonNUMAInfoTwoNodes() *NUMAInfo {
  1575  	return &NUMAInfo{
  1576  		Nodes: []int{0, 1},
  1577  		NUMADistances: NUMADistances{
  1578  			0: {10, 11},
  1579  			1: {11, 10},
  1580  		},
  1581  	}
  1582  }
  1583  
  1584  func commonNUMAInfoFourNodes() *NUMAInfo {
  1585  	return &NUMAInfo{
  1586  		Nodes: []int{0, 1, 2, 3},
  1587  		NUMADistances: NUMADistances{
  1588  			0: {10, 11, 12, 12},
  1589  			1: {11, 10, 12, 12},
  1590  			2: {12, 12, 10, 11},
  1591  			3: {12, 12, 11, 10},
  1592  		},
  1593  	}
  1594  }
  1595  
  1596  func commonNUMAInfoEightNodes() *NUMAInfo {
  1597  	return &NUMAInfo{
  1598  		Nodes: []int{0, 1, 2, 3, 4, 5, 6, 7},
  1599  		NUMADistances: NUMADistances{
  1600  			0: {10, 11, 12, 12, 30, 30, 30, 30},
  1601  			1: {11, 10, 12, 12, 30, 30, 30, 30},
  1602  			2: {12, 12, 10, 11, 30, 30, 30, 30},
  1603  			3: {12, 12, 11, 10, 30, 30, 30, 30},
  1604  			4: {30, 30, 30, 30, 10, 11, 12, 12},
  1605  			5: {30, 30, 30, 30, 11, 10, 12, 12},
  1606  			6: {30, 30, 30, 30, 12, 12, 10, 11},
  1607  			7: {30, 30, 30, 30, 12, 12, 13, 10},
  1608  		},
  1609  	}
  1610  }
  1611  

View as plain text