github.com/kubewharf/katalyst-core@v0.5.3/pkg/agent/orm/topology/policy_numeric_test.go (about)

     1  /*
     2  Copyright 2022 The Katalyst 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 topology
    18  
    19  import "testing"
    20  
    21  func TestPolicyNumericMerge(t *testing.T) {
    22  	t.Parallel()
    23  
    24  	policy := NewNumericPolicy(defaultAlignResourceNames)
    25  
    26  	tcases := []policyMergeTestCase{
    27  		{
    28  			name: "Two providers, 1 hint each, same mask, both preferred 1/2",
    29  			hp: []HintProvider{
    30  				&mockHintProvider{
    31  					map[string][]TopologyHint{
    32  						"resource1": {
    33  							{
    34  								NUMANodeAffinity: NewTestBitMask(0),
    35  								Preferred:        true,
    36  							},
    37  						},
    38  					},
    39  				},
    40  				&mockHintProvider{
    41  					map[string][]TopologyHint{
    42  						"resource2": {
    43  							{
    44  								NUMANodeAffinity: NewTestBitMask(0),
    45  								Preferred:        true,
    46  							},
    47  						},
    48  					},
    49  				},
    50  			},
    51  			expected: map[string]TopologyHint{
    52  				"resource1": {
    53  					NUMANodeAffinity: NewTestBitMask(0),
    54  					Preferred:        true,
    55  				},
    56  				"resource2": {
    57  					NUMANodeAffinity: NewTestBitMask(0),
    58  					Preferred:        true,
    59  				},
    60  			},
    61  		},
    62  		{
    63  			name: "Two providers, 1 hint each, same mask, both preferred 2/2",
    64  			hp: []HintProvider{
    65  				&mockHintProvider{
    66  					map[string][]TopologyHint{
    67  						"resource1": {
    68  							{
    69  								NUMANodeAffinity: NewTestBitMask(1),
    70  								Preferred:        true,
    71  							},
    72  						},
    73  					},
    74  				},
    75  				&mockHintProvider{
    76  					map[string][]TopologyHint{
    77  						"resource2": {
    78  							{
    79  								NUMANodeAffinity: NewTestBitMask(1),
    80  								Preferred:        true,
    81  							},
    82  						},
    83  					},
    84  				},
    85  			},
    86  			expected: map[string]TopologyHint{
    87  				"resource1": {
    88  					NUMANodeAffinity: NewTestBitMask(1),
    89  					Preferred:        true,
    90  				},
    91  				"resource2": {
    92  					NUMANodeAffinity: NewTestBitMask(1),
    93  					Preferred:        true,
    94  				},
    95  			},
    96  		},
    97  		{
    98  			name: "Two providers, 1 no hints, 1 single hint preferred 1/2",
    99  			hp: []HintProvider{
   100  				&mockHintProvider{},
   101  				&mockHintProvider{
   102  					map[string][]TopologyHint{
   103  						"resource": {
   104  							{
   105  								NUMANodeAffinity: NewTestBitMask(0),
   106  								Preferred:        true,
   107  							},
   108  						},
   109  					},
   110  				},
   111  			},
   112  			expected: map[string]TopologyHint{
   113  				"resource": {
   114  					NUMANodeAffinity: NewTestBitMask(0),
   115  					Preferred:        true,
   116  				},
   117  				defaultResourceKey: {
   118  					NUMANodeAffinity: nil,
   119  					Preferred:        true,
   120  				},
   121  			},
   122  		},
   123  		{
   124  			name: "Two providers, 1 no hints, 1 single hint preferred 2/2",
   125  			hp: []HintProvider{
   126  				&mockHintProvider{},
   127  				&mockHintProvider{
   128  					map[string][]TopologyHint{
   129  						"resource": {
   130  							{
   131  								NUMANodeAffinity: NewTestBitMask(1),
   132  								Preferred:        true,
   133  							},
   134  						},
   135  					},
   136  				},
   137  			},
   138  			expected: map[string]TopologyHint{
   139  				"resource": {
   140  					NUMANodeAffinity: NewTestBitMask(1),
   141  					Preferred:        true,
   142  				},
   143  				defaultResourceKey: {
   144  					NUMANodeAffinity: nil,
   145  					Preferred:        true,
   146  				},
   147  			},
   148  		},
   149  		{
   150  			name: "Two providers, 1 with 2 hints, 1 with single hint matching 1/2",
   151  			hp: []HintProvider{
   152  				&mockHintProvider{
   153  					map[string][]TopologyHint{
   154  						"resource1": {
   155  							{
   156  								NUMANodeAffinity: NewTestBitMask(0),
   157  								Preferred:        true,
   158  							},
   159  							{
   160  								NUMANodeAffinity: NewTestBitMask(1),
   161  								Preferred:        true,
   162  							},
   163  						},
   164  					},
   165  				},
   166  				&mockHintProvider{
   167  					map[string][]TopologyHint{
   168  						"resource2": {
   169  							{
   170  								NUMANodeAffinity: NewTestBitMask(0),
   171  								Preferred:        true,
   172  							},
   173  						},
   174  					},
   175  				},
   176  			},
   177  			expected: map[string]TopologyHint{
   178  				"resource1": {
   179  					NUMANodeAffinity: NewTestBitMask(0),
   180  					Preferred:        true,
   181  				},
   182  				"resource2": {
   183  					NUMANodeAffinity: NewTestBitMask(0),
   184  					Preferred:        true,
   185  				},
   186  			},
   187  		},
   188  
   189  		{
   190  			name: "Two providers, 1 with 2 hints, 1 with single hint matching 2/2",
   191  			hp: []HintProvider{
   192  				&mockHintProvider{
   193  					map[string][]TopologyHint{
   194  						"resource1": {
   195  							{
   196  								NUMANodeAffinity: NewTestBitMask(0),
   197  								Preferred:        true,
   198  							},
   199  							{
   200  								NUMANodeAffinity: NewTestBitMask(1),
   201  								Preferred:        true,
   202  							},
   203  						},
   204  					},
   205  				},
   206  				&mockHintProvider{
   207  					map[string][]TopologyHint{
   208  						"resource2": {
   209  							{
   210  								NUMANodeAffinity: NewTestBitMask(1),
   211  								Preferred:        true,
   212  							},
   213  						},
   214  					},
   215  				},
   216  			},
   217  			expected: map[string]TopologyHint{
   218  				"resource1": {
   219  					NUMANodeAffinity: NewTestBitMask(1),
   220  					Preferred:        true,
   221  				},
   222  				"resource2": {
   223  					NUMANodeAffinity: NewTestBitMask(1),
   224  					Preferred:        true,
   225  				},
   226  			},
   227  		},
   228  		{
   229  			name: "Two providers, both with 2 hints, matching narrower preferred hint from both",
   230  			hp: []HintProvider{
   231  				&mockHintProvider{
   232  					map[string][]TopologyHint{
   233  						"resource1": {
   234  							{
   235  								NUMANodeAffinity: NewTestBitMask(0),
   236  								Preferred:        true,
   237  							},
   238  							{
   239  								NUMANodeAffinity: NewTestBitMask(1),
   240  								Preferred:        true,
   241  							},
   242  						},
   243  					},
   244  				},
   245  				&mockHintProvider{
   246  					map[string][]TopologyHint{
   247  						"resource2": {
   248  							{
   249  								NUMANodeAffinity: NewTestBitMask(0),
   250  								Preferred:        true,
   251  							},
   252  							{
   253  								NUMANodeAffinity: NewTestBitMask(0, 1),
   254  								Preferred:        false,
   255  							},
   256  						},
   257  					},
   258  				},
   259  			},
   260  			expected: map[string]TopologyHint{
   261  				"resource1": {
   262  					NUMANodeAffinity: NewTestBitMask(0),
   263  					Preferred:        true,
   264  				},
   265  				"resource2": {
   266  					NUMANodeAffinity: NewTestBitMask(0),
   267  					Preferred:        true,
   268  				},
   269  			},
   270  		},
   271  		{
   272  			name: "Ensure less narrow preferred hints are chosen over narrower non-preferred hints",
   273  			hp: []HintProvider{
   274  				&mockHintProvider{
   275  					map[string][]TopologyHint{
   276  						"resource1": {
   277  							{
   278  								NUMANodeAffinity: NewTestBitMask(1),
   279  								Preferred:        true,
   280  							},
   281  							{
   282  								NUMANodeAffinity: NewTestBitMask(0, 1),
   283  								Preferred:        false,
   284  							},
   285  						},
   286  					},
   287  				},
   288  				&mockHintProvider{
   289  					map[string][]TopologyHint{
   290  						"resource2": {
   291  							{
   292  								NUMANodeAffinity: NewTestBitMask(0),
   293  								Preferred:        true,
   294  							},
   295  							{
   296  								NUMANodeAffinity: NewTestBitMask(1),
   297  								Preferred:        true,
   298  							},
   299  							{
   300  								NUMANodeAffinity: NewTestBitMask(0, 1),
   301  								Preferred:        false,
   302  							},
   303  						},
   304  					},
   305  				},
   306  			},
   307  			expected: map[string]TopologyHint{
   308  				"resource1": {
   309  					NUMANodeAffinity: NewTestBitMask(1),
   310  					Preferred:        true,
   311  				},
   312  				"resource2": {
   313  					NUMANodeAffinity: NewTestBitMask(1),
   314  					Preferred:        true,
   315  				},
   316  			},
   317  		},
   318  		{
   319  			name: "Multiple resources, same provider",
   320  			hp: []HintProvider{
   321  				&mockHintProvider{
   322  					map[string][]TopologyHint{
   323  						"resource1": {
   324  							{
   325  								NUMANodeAffinity: NewTestBitMask(1),
   326  								Preferred:        true,
   327  							},
   328  							{
   329  								NUMANodeAffinity: NewTestBitMask(0, 1),
   330  								Preferred:        false,
   331  							},
   332  						},
   333  						"resource2": {
   334  							{
   335  								NUMANodeAffinity: NewTestBitMask(0),
   336  								Preferred:        true,
   337  							},
   338  							{
   339  								NUMANodeAffinity: NewTestBitMask(1),
   340  								Preferred:        true,
   341  							},
   342  							{
   343  								NUMANodeAffinity: NewTestBitMask(0, 1),
   344  								Preferred:        false,
   345  							},
   346  						},
   347  					},
   348  				},
   349  			},
   350  			expected: map[string]TopologyHint{
   351  				"resource1": {
   352  					NUMANodeAffinity: NewTestBitMask(1),
   353  					Preferred:        true,
   354  				},
   355  				"resource2": {
   356  					NUMANodeAffinity: NewTestBitMask(1),
   357  					Preferred:        true,
   358  				},
   359  			},
   360  		},
   361  		{
   362  			name: "TopologyHint not set",
   363  			hp:   []HintProvider{},
   364  			expected: map[string]TopologyHint{
   365  				defaultResourceKey: {
   366  					NUMANodeAffinity: nil,
   367  					Preferred:        true,
   368  				},
   369  			},
   370  		},
   371  		{
   372  			name: "HintProvider returns empty non-nil map[string][]TopologyHint",
   373  			hp: []HintProvider{
   374  				&mockHintProvider{
   375  					map[string][]TopologyHint{},
   376  				},
   377  			},
   378  			expected: map[string]TopologyHint{
   379  				defaultResourceKey: {
   380  					NUMANodeAffinity: nil,
   381  					Preferred:        true,
   382  				},
   383  			},
   384  		},
   385  		{
   386  			name: "HintProvider returns -nil map[string][]TopologyHint from provider",
   387  			hp: []HintProvider{
   388  				&mockHintProvider{
   389  					map[string][]TopologyHint{
   390  						"resource": nil,
   391  					},
   392  				},
   393  			},
   394  			expected: map[string]TopologyHint{
   395  				"resource": {
   396  					NUMANodeAffinity: nil,
   397  					Preferred:        true,
   398  				},
   399  			},
   400  		},
   401  		{
   402  			name: "HintProvider returns empty non-nil map[string][]TopologyHint from provider",
   403  			hp: []HintProvider{
   404  				&mockHintProvider{
   405  					map[string][]TopologyHint{
   406  						"resource": {},
   407  					},
   408  				},
   409  			},
   410  			expected: nil,
   411  		},
   412  		{
   413  			name: "Single TopologyHint with Preferred as true and NUMANodeAffinity as nil",
   414  			hp: []HintProvider{
   415  				&mockHintProvider{
   416  					map[string][]TopologyHint{
   417  						"resource": {
   418  							{
   419  								NUMANodeAffinity: nil,
   420  								Preferred:        true,
   421  							},
   422  						},
   423  					},
   424  				},
   425  			},
   426  			expected: map[string]TopologyHint{
   427  				"resource": {
   428  					NUMANodeAffinity: nil,
   429  					Preferred:        true,
   430  				},
   431  			},
   432  		},
   433  		{
   434  			name: "Two providers, 1 hint each, no common mask",
   435  			hp: []HintProvider{
   436  				&mockHintProvider{
   437  					map[string][]TopologyHint{
   438  						"resource1": {
   439  							{
   440  								NUMANodeAffinity: NewTestBitMask(0),
   441  								Preferred:        true,
   442  							},
   443  						},
   444  					},
   445  				},
   446  				&mockHintProvider{
   447  					map[string][]TopologyHint{
   448  						"resource2": {
   449  							{
   450  								NUMANodeAffinity: NewTestBitMask(1),
   451  								Preferred:        true,
   452  							},
   453  						},
   454  					},
   455  				},
   456  			},
   457  			expected: nil,
   458  		},
   459  		{
   460  			name: "Two providers, 1 hint each, same mask, 1 preferred, 1 not 1/2",
   461  			hp: []HintProvider{
   462  				&mockHintProvider{
   463  					map[string][]TopologyHint{
   464  						"resource1": {
   465  							{
   466  								NUMANodeAffinity: NewTestBitMask(0),
   467  								Preferred:        true,
   468  							},
   469  						},
   470  					},
   471  				},
   472  				&mockHintProvider{
   473  					map[string][]TopologyHint{
   474  						"resource2": {
   475  							{
   476  								NUMANodeAffinity: NewTestBitMask(0),
   477  								Preferred:        false,
   478  							},
   479  						},
   480  					},
   481  				},
   482  			},
   483  			expected: map[string]TopologyHint{
   484  				"resource1": {
   485  					NUMANodeAffinity: NewTestBitMask(0),
   486  					Preferred:        true,
   487  				},
   488  				"resource2": {
   489  					NUMANodeAffinity: NewTestBitMask(0),
   490  					Preferred:        false,
   491  				},
   492  			},
   493  		},
   494  		{
   495  			name: "Two providers, 1 hint each, same mask, 1 preferred, 1 not 2/2",
   496  			hp: []HintProvider{
   497  				&mockHintProvider{
   498  					map[string][]TopologyHint{
   499  						"resource1": {
   500  							{
   501  								NUMANodeAffinity: NewTestBitMask(1),
   502  								Preferred:        true,
   503  							},
   504  						},
   505  					},
   506  				},
   507  				&mockHintProvider{
   508  					map[string][]TopologyHint{
   509  						"resource2": {
   510  							{
   511  								NUMANodeAffinity: NewTestBitMask(1),
   512  								Preferred:        false,
   513  							},
   514  						},
   515  					},
   516  				},
   517  			},
   518  			expected: map[string]TopologyHint{
   519  				"resource1": {
   520  					NUMANodeAffinity: NewTestBitMask(1),
   521  					Preferred:        true,
   522  				},
   523  				"resource2": {
   524  					NUMANodeAffinity: NewTestBitMask(1),
   525  					Preferred:        false,
   526  				},
   527  			},
   528  		},
   529  		{
   530  			name: "Two providers, 1 with 2 hints, 1 with single non-preferred hint matching",
   531  			hp: []HintProvider{
   532  				&mockHintProvider{
   533  					map[string][]TopologyHint{
   534  						"resource1": {
   535  							{
   536  								NUMANodeAffinity: NewTestBitMask(0),
   537  								Preferred:        true,
   538  							},
   539  							{
   540  								NUMANodeAffinity: NewTestBitMask(1),
   541  								Preferred:        true,
   542  							},
   543  						},
   544  					},
   545  				},
   546  				&mockHintProvider{
   547  					map[string][]TopologyHint{
   548  						"resource2": {
   549  							{
   550  								NUMANodeAffinity: NewTestBitMask(0, 1),
   551  								Preferred:        false,
   552  							},
   553  						},
   554  					},
   555  				},
   556  			},
   557  			expected: map[string]TopologyHint{
   558  				"resource1": {
   559  					NUMANodeAffinity: NewTestBitMask(0),
   560  					Preferred:        true,
   561  				},
   562  				"resource2": {
   563  					NUMANodeAffinity: NewTestBitMask(0, 1),
   564  					Preferred:        false,
   565  				},
   566  			},
   567  		},
   568  		{
   569  			name: "Numeric hint generation, two resource",
   570  			hp: []HintProvider{
   571  				&mockHintProvider{
   572  					map[string][]TopologyHint{
   573  						"resource1": {
   574  							{
   575  								NUMANodeAffinity: NewTestBitMask(0, 1),
   576  								Preferred:        true,
   577  							},
   578  						},
   579  						"resource2": {
   580  							{
   581  								NUMANodeAffinity: NewTestBitMask(0),
   582  								Preferred:        true,
   583  							},
   584  							{
   585  								NUMANodeAffinity: NewTestBitMask(1),
   586  								Preferred:        true,
   587  							},
   588  							{
   589  								NUMANodeAffinity: NewTestBitMask(0, 1),
   590  								Preferred:        false,
   591  							},
   592  						},
   593  					},
   594  				},
   595  			},
   596  			expected: map[string]TopologyHint{
   597  				"resource1": {
   598  					NUMANodeAffinity: NewTestBitMask(0, 1),
   599  					Preferred:        true,
   600  				},
   601  				"resource2": {
   602  					NUMANodeAffinity: NewTestBitMask(0),
   603  					Preferred:        true,
   604  				},
   605  			},
   606  		},
   607  		{
   608  			name: "Align cpu, memory, cpu with 2/2 hit, memory with 1/2, 2/2 hint",
   609  			hp: []HintProvider{
   610  				&mockHintProvider{
   611  					map[string][]TopologyHint{
   612  						"cpu": {
   613  							{
   614  								NUMANodeAffinity: NewTestBitMask(0, 1),
   615  								Preferred:        true,
   616  							},
   617  						},
   618  						"memory": {
   619  							{
   620  								NUMANodeAffinity: NewTestBitMask(0),
   621  								Preferred:        true,
   622  							},
   623  							{
   624  								NUMANodeAffinity: NewTestBitMask(1),
   625  								Preferred:        true,
   626  							},
   627  							{
   628  								NUMANodeAffinity: NewTestBitMask(0, 1),
   629  								Preferred:        false,
   630  							},
   631  						},
   632  						"gpu": {
   633  							{
   634  								NUMANodeAffinity: NewTestBitMask(0),
   635  								Preferred:        true,
   636  							},
   637  						},
   638  					},
   639  				},
   640  			},
   641  			expected: map[string]TopologyHint{
   642  				"cpu": {
   643  					NUMANodeAffinity: NewTestBitMask(0, 1),
   644  					Preferred:        true,
   645  				},
   646  				"memory": {
   647  					NUMANodeAffinity: NewTestBitMask(0, 1),
   648  					Preferred:        false,
   649  				},
   650  				"gpu": {
   651  					NUMANodeAffinity: NewTestBitMask(0),
   652  					Preferred:        true,
   653  				},
   654  			},
   655  		},
   656  		{
   657  			name: "Align cpu, memory, cpu with 2/2 hit, memory with 1/2, 2/2 hint",
   658  			hp: []HintProvider{
   659  				&mockHintProvider{
   660  					map[string][]TopologyHint{
   661  						"cpu": {
   662  							{
   663  								NUMANodeAffinity: NewTestBitMask(0, 1),
   664  								Preferred:        true,
   665  							},
   666  						},
   667  						"memory": {
   668  							{
   669  								NUMANodeAffinity: NewTestBitMask(0),
   670  								Preferred:        true,
   671  							},
   672  							{
   673  								NUMANodeAffinity: NewTestBitMask(1),
   674  								Preferred:        true,
   675  							},
   676  						},
   677  						"gpu": {
   678  							{
   679  								NUMANodeAffinity: NewTestBitMask(0),
   680  								Preferred:        true,
   681  							},
   682  						},
   683  					},
   684  				},
   685  			},
   686  			expected: nil,
   687  		},
   688  		{
   689  			name: "Align cpu, cpu with 2/2 hit",
   690  			hp: []HintProvider{
   691  				&mockHintProvider{
   692  					map[string][]TopologyHint{
   693  						"cpu": {
   694  							{
   695  								NUMANodeAffinity: NewTestBitMask(0, 1),
   696  								Preferred:        false,
   697  							},
   698  						},
   699  						"gpu": {
   700  							{
   701  								NUMANodeAffinity: NewTestBitMask(0),
   702  								Preferred:        true,
   703  							},
   704  						},
   705  					},
   706  				},
   707  			},
   708  			expected: nil,
   709  		},
   710  		{
   711  			name: "Align cpu, cpu with 1/2, 2/2 hit",
   712  			hp: []HintProvider{
   713  				&mockHintProvider{
   714  					map[string][]TopologyHint{
   715  						"cpu": {
   716  							{
   717  								NUMANodeAffinity: NewTestBitMask(0, 1),
   718  								Preferred:        false,
   719  							},
   720  							{
   721  								NUMANodeAffinity: NewTestBitMask(0),
   722  								Preferred:        true,
   723  							},
   724  						},
   725  						"gpu": {
   726  							{
   727  								NUMANodeAffinity: NewTestBitMask(0),
   728  								Preferred:        false,
   729  							},
   730  						},
   731  					},
   732  				},
   733  			},
   734  			expected: map[string]TopologyHint{
   735  				"cpu": {
   736  					NUMANodeAffinity: NewTestBitMask(0),
   737  					Preferred:        true,
   738  				},
   739  				"gpu": {
   740  					NUMANodeAffinity: NewTestBitMask(0),
   741  					Preferred:        false,
   742  				},
   743  			},
   744  		},
   745  		{
   746  			name: "Align cpu, cpu with 1/2 hit, gpu with 1/2, 2/2 hint",
   747  			hp: []HintProvider{
   748  				&mockHintProvider{
   749  					map[string][]TopologyHint{
   750  						"cpu": {
   751  							{
   752  								NUMANodeAffinity: NewTestBitMask(0),
   753  								Preferred:        true,
   754  							},
   755  						},
   756  						"gpu": {
   757  							{
   758  								NUMANodeAffinity: NewTestBitMask(0, 1),
   759  								Preferred:        false,
   760  							},
   761  							{
   762  								NUMANodeAffinity: NewTestBitMask(0),
   763  								Preferred:        true,
   764  							},
   765  						},
   766  					},
   767  				},
   768  			},
   769  			expected: map[string]TopologyHint{
   770  				"cpu": {
   771  					NUMANodeAffinity: NewTestBitMask(0),
   772  					Preferred:        true,
   773  				},
   774  				"gpu": {
   775  					NUMANodeAffinity: NewTestBitMask(0),
   776  					Preferred:        true,
   777  				},
   778  			},
   779  		},
   780  		{
   781  			name: "Align cpu, memory, cpu with 2/2 hit, memory with 1/2, 2/2 hint",
   782  			hp: []HintProvider{
   783  				&mockHintProvider{
   784  					map[string][]TopologyHint{
   785  						"gpu": {
   786  							{
   787  								NUMANodeAffinity: NewTestBitMask(0, 1),
   788  								Preferred:        false,
   789  							},
   790  							{
   791  								NUMANodeAffinity: NewTestBitMask(0),
   792  								Preferred:        true,
   793  							},
   794  						},
   795  						"cpu": {
   796  							{
   797  								NUMANodeAffinity: NewTestBitMask(0, 1),
   798  								Preferred:        true,
   799  							},
   800  						},
   801  						"memory": {
   802  							{
   803  								NUMANodeAffinity: NewTestBitMask(0),
   804  								Preferred:        true,
   805  							},
   806  							{
   807  								NUMANodeAffinity: NewTestBitMask(1),
   808  								Preferred:        true,
   809  							},
   810  							{
   811  								NUMANodeAffinity: NewTestBitMask(0, 1),
   812  								Preferred:        false,
   813  							},
   814  						},
   815  					},
   816  				},
   817  			},
   818  			expected: map[string]TopologyHint{
   819  				"cpu": {
   820  					NUMANodeAffinity: NewTestBitMask(0, 1),
   821  					Preferred:        true,
   822  				},
   823  				"memory": {
   824  					NUMANodeAffinity: NewTestBitMask(0, 1),
   825  					Preferred:        false,
   826  				},
   827  				"gpu": {
   828  					NUMANodeAffinity: NewTestBitMask(0),
   829  					Preferred:        true,
   830  				},
   831  			},
   832  		},
   833  		{
   834  			name: "Align cpu, memory, nil, nil provider to test append bug",
   835  			hp: []HintProvider{
   836  				&mockHintProvider{},
   837  				&mockHintProvider{},
   838  				&mockHintProvider{
   839  					map[string][]TopologyHint{
   840  						"cpu": {
   841  							{
   842  								NUMANodeAffinity: NewTestBitMask(0),
   843  								Preferred:        true,
   844  							},
   845  							{
   846  								NUMANodeAffinity: NewTestBitMask(1),
   847  								Preferred:        true,
   848  							},
   849  						},
   850  						"memory": {
   851  							{
   852  								NUMANodeAffinity: NewTestBitMask(0),
   853  								Preferred:        true,
   854  							},
   855  							{
   856  								NUMANodeAffinity: NewTestBitMask(1),
   857  								Preferred:        true,
   858  							},
   859  						},
   860  					},
   861  				},
   862  			},
   863  			expected: map[string]TopologyHint{
   864  				defaultResourceKey: {
   865  					NUMANodeAffinity: nil,
   866  					Preferred:        true,
   867  				},
   868  				"cpu": {
   869  					NUMANodeAffinity: NewTestBitMask(0),
   870  					Preferred:        true,
   871  				},
   872  				"memory": {
   873  					NUMANodeAffinity: NewTestBitMask(0),
   874  					Preferred:        true,
   875  				},
   876  			},
   877  		},
   878  		{
   879  			name: "Align cpu, memory. cpu nil preferred nil hint, memory with 2/2 hint",
   880  			hp: []HintProvider{
   881  				&mockHintProvider{
   882  					map[string][]TopologyHint{
   883  						"memory": {
   884  							{
   885  								NUMANodeAffinity: NewTestBitMask(0, 1),
   886  								Preferred:        true,
   887  							},
   888  						},
   889  						"cpu": {
   890  							{
   891  								NUMANodeAffinity: nil,
   892  								Preferred:        true,
   893  							},
   894  						},
   895  					},
   896  				},
   897  			},
   898  			expected: map[string]TopologyHint{
   899  				"memory": {
   900  					NUMANodeAffinity: NewTestBitMask(0, 1),
   901  					Preferred:        true,
   902  				},
   903  				"cpu": {
   904  					NUMANodeAffinity: nil,
   905  					Preferred:        true,
   906  				},
   907  			},
   908  		},
   909  	}
   910  	testPolicyMerge(policy, tcases, t)
   911  }