github.com/kubewharf/katalyst-core@v0.5.3/pkg/util/cnr_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 util
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	v1 "k8s.io/api/core/v1"
    25  	"k8s.io/apimachinery/pkg/api/resource"
    26  
    27  	nodeapis "github.com/kubewharf/katalyst-api/pkg/apis/node/v1alpha1"
    28  )
    29  
    30  func TestAddOrUpdateCNRTaint(t *testing.T) {
    31  	t.Parallel()
    32  
    33  	type args struct {
    34  		cnr   *nodeapis.CustomNodeResource
    35  		taint *nodeapis.Taint
    36  	}
    37  	tests := []struct {
    38  		name    string
    39  		args    args
    40  		want    *nodeapis.CustomNodeResource
    41  		want1   bool
    42  		wantErr assert.ErrorAssertionFunc
    43  	}{
    44  		{
    45  			name: "add taint",
    46  			args: args{
    47  				cnr: &nodeapis.CustomNodeResource{},
    48  				taint: &nodeapis.Taint{
    49  					Key:    "test-key",
    50  					Value:  "test-value",
    51  					Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
    52  				},
    53  			},
    54  			want: &nodeapis.CustomNodeResource{
    55  				Spec: nodeapis.CustomNodeResourceSpec{
    56  					Taints: []*nodeapis.Taint{
    57  						{
    58  							Key:    "test-key",
    59  							Value:  "test-value",
    60  							Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
    61  						},
    62  					},
    63  				},
    64  			},
    65  			want1: true,
    66  			wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
    67  				return true
    68  			},
    69  		},
    70  		{
    71  			name: "update taint",
    72  			args: args{
    73  				cnr: &nodeapis.CustomNodeResource{
    74  					Spec: nodeapis.CustomNodeResourceSpec{
    75  						Taints: []*nodeapis.Taint{
    76  							{
    77  								Key:    "test-key",
    78  								Value:  "test-value",
    79  								Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
    80  							},
    81  						},
    82  					},
    83  				},
    84  				taint: &nodeapis.Taint{
    85  					Key:    "test-key",
    86  					Value:  "test-value-1",
    87  					Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
    88  				},
    89  			},
    90  			want: &nodeapis.CustomNodeResource{
    91  				Spec: nodeapis.CustomNodeResourceSpec{
    92  					Taints: []*nodeapis.Taint{
    93  						{
    94  							Key:    "test-key",
    95  							Value:  "test-value-1",
    96  							Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
    97  						},
    98  					},
    99  				},
   100  			},
   101  			want1: true,
   102  			wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
   103  				return true
   104  			},
   105  		},
   106  		{
   107  			name: "no update taint",
   108  			args: args{
   109  				cnr: &nodeapis.CustomNodeResource{
   110  					Spec: nodeapis.CustomNodeResourceSpec{
   111  						Taints: []*nodeapis.Taint{
   112  							{
   113  								Key:    "test-key",
   114  								Value:  "test-value",
   115  								Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   116  							},
   117  						},
   118  					},
   119  				},
   120  				taint: &nodeapis.Taint{
   121  					Key:    "test-key",
   122  					Value:  "test-value",
   123  					Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   124  				},
   125  			},
   126  			want: &nodeapis.CustomNodeResource{
   127  				Spec: nodeapis.CustomNodeResourceSpec{
   128  					Taints: []*nodeapis.Taint{
   129  						{
   130  							Key:    "test-key",
   131  							Value:  "test-value",
   132  							Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   133  						},
   134  					},
   135  				},
   136  			},
   137  			want1: false,
   138  			wantErr: func(t assert.TestingT, err error, i ...interface{}) bool {
   139  				return true
   140  			},
   141  		},
   142  	}
   143  	for _, tt := range tests {
   144  		tt := tt
   145  		t.Run(tt.name, func(t *testing.T) {
   146  			t.Parallel()
   147  			got, got1, err := AddOrUpdateCNRTaint(tt.args.cnr, tt.args.taint)
   148  			if !tt.wantErr(t, err, fmt.Sprintf("AddOrUpdateCNRTaint(%v, %v)", tt.args.cnr, tt.args.taint)) {
   149  				return
   150  			}
   151  			assert.Equalf(t, tt.want, got, "AddOrUpdateCNRTaint(%v, %v)", tt.args.cnr, tt.args.taint)
   152  			assert.Equalf(t, tt.want1, got1, "AddOrUpdateCNRTaint(%v, %v)", tt.args.cnr, tt.args.taint)
   153  		})
   154  	}
   155  }
   156  
   157  func TestCNRTaintExists(t *testing.T) {
   158  	t.Parallel()
   159  
   160  	type args struct {
   161  		taints      []*nodeapis.Taint
   162  		taintToFind *nodeapis.Taint
   163  	}
   164  	tests := []struct {
   165  		name string
   166  		args args
   167  		want bool
   168  	}{
   169  		{
   170  			name: "taint exists",
   171  			args: args{
   172  				taints: []*nodeapis.Taint{
   173  					{
   174  						Key:    "test-key",
   175  						Value:  "test-value",
   176  						Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   177  					},
   178  				},
   179  				taintToFind: &nodeapis.Taint{
   180  					Key:    "test-key",
   181  					Value:  "test-value",
   182  					Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   183  				},
   184  			},
   185  			want: true,
   186  		},
   187  		{
   188  			name: "taint no exists",
   189  			args: args{
   190  				taints: []*nodeapis.Taint{
   191  					{
   192  						Key:    "test-key",
   193  						Value:  "test-value",
   194  						Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   195  					},
   196  				},
   197  				taintToFind: &nodeapis.Taint{
   198  					Key:    "test-key-1",
   199  					Value:  "test-value-1",
   200  					Effect: nodeapis.TaintEffectNoScheduleForReclaimedTasks,
   201  				},
   202  			},
   203  			want: false,
   204  		},
   205  	}
   206  	for _, tt := range tests {
   207  		tt := tt
   208  		t.Run(tt.name, func(t *testing.T) {
   209  			t.Parallel()
   210  			assert.Equalf(t, tt.want, CNRTaintExists(tt.args.taints, tt.args.taintToFind), "CNRTaintExists(%v, %v)", tt.args.taints, tt.args.taintToFind)
   211  		})
   212  	}
   213  }
   214  
   215  func TestMergeAllocations(t *testing.T) {
   216  	t.Parallel()
   217  
   218  	type args struct {
   219  		dst []*nodeapis.Allocation
   220  		src []*nodeapis.Allocation
   221  	}
   222  	tests := []struct {
   223  		name string
   224  		args args
   225  		want []*nodeapis.Allocation
   226  	}{
   227  		{
   228  			name: "merge all",
   229  			args: args{
   230  				src: []*nodeapis.Allocation{
   231  					{
   232  						Consumer: "aa",
   233  						Requests: &v1.ResourceList{
   234  							v1.ResourceCPU: resource.MustParse("10"),
   235  						},
   236  					},
   237  				},
   238  				dst: []*nodeapis.Allocation{
   239  					{
   240  						Consumer: "bb",
   241  						Requests: &v1.ResourceList{
   242  							v1.ResourceCPU: resource.MustParse("10"),
   243  						},
   244  					},
   245  				},
   246  			},
   247  			want: []*nodeapis.Allocation{
   248  				{
   249  					Consumer: "aa",
   250  					Requests: &v1.ResourceList{
   251  						v1.ResourceCPU: resource.MustParse("10"),
   252  					},
   253  				},
   254  				{
   255  					Consumer: "bb",
   256  					Requests: &v1.ResourceList{
   257  						v1.ResourceCPU: resource.MustParse("10"),
   258  					},
   259  				},
   260  			},
   261  		},
   262  		{
   263  			name: "merge resources",
   264  			args: args{
   265  				src: []*nodeapis.Allocation{
   266  					{
   267  						Consumer: "aa",
   268  						Requests: &v1.ResourceList{
   269  							v1.ResourceCPU: resource.MustParse("10"),
   270  						},
   271  					},
   272  				},
   273  				dst: []*nodeapis.Allocation{
   274  					{
   275  						Consumer: "aa",
   276  						Requests: &v1.ResourceList{
   277  							v1.ResourceMemory: resource.MustParse("10"),
   278  						},
   279  					},
   280  				},
   281  			},
   282  			want: []*nodeapis.Allocation{
   283  				{
   284  					Consumer: "aa",
   285  					Requests: &v1.ResourceList{
   286  						v1.ResourceCPU:    resource.MustParse("10"),
   287  						v1.ResourceMemory: resource.MustParse("10"),
   288  					},
   289  				},
   290  			},
   291  		},
   292  	}
   293  	for _, tt := range tests {
   294  		tt := tt
   295  		t.Run(tt.name, func(t *testing.T) {
   296  			t.Parallel()
   297  			assert.Equalf(t, tt.want, MergeAllocations(tt.args.dst, tt.args.src), "MergeAllocations(%v, %v)", tt.args.dst, tt.args.src)
   298  		})
   299  	}
   300  }
   301  
   302  func TestMergeAttributes(t *testing.T) {
   303  	t.Parallel()
   304  
   305  	type args struct {
   306  		dst []nodeapis.Attribute
   307  		src []nodeapis.Attribute
   308  	}
   309  	tests := []struct {
   310  		name string
   311  		args args
   312  		want []nodeapis.Attribute
   313  	}{
   314  		{
   315  			name: "merge two attribute",
   316  			args: args{
   317  				src: []nodeapis.Attribute{
   318  					{
   319  						Name:  "aa",
   320  						Value: "aa-value",
   321  					},
   322  				},
   323  				dst: []nodeapis.Attribute{
   324  					{
   325  						Name:  "bb",
   326  						Value: "bb-value",
   327  					},
   328  				},
   329  			},
   330  			want: []nodeapis.Attribute{
   331  				{
   332  					Name:  "aa",
   333  					Value: "aa-value",
   334  				},
   335  				{
   336  					Name:  "bb",
   337  					Value: "bb-value",
   338  				},
   339  			},
   340  		},
   341  		{
   342  			name: "merge same attribute",
   343  			args: args{
   344  				src: []nodeapis.Attribute{
   345  					{
   346  						Name:  "aa",
   347  						Value: "aa-value",
   348  					},
   349  				},
   350  				dst: []nodeapis.Attribute{
   351  					{
   352  						Name:  "aa",
   353  						Value: "aa-value-1",
   354  					},
   355  				},
   356  			},
   357  			want: []nodeapis.Attribute{
   358  				{
   359  					Name:  "aa",
   360  					Value: "aa-value-1",
   361  				},
   362  			},
   363  		},
   364  	}
   365  	for _, tt := range tests {
   366  		tt := tt
   367  		t.Run(tt.name, func(t *testing.T) {
   368  			t.Parallel()
   369  			assert.Equalf(t, tt.want, MergeAttributes(tt.args.dst, tt.args.src), "MergeAttributes(%v, %v)", tt.args.dst, tt.args.src)
   370  		})
   371  	}
   372  }
   373  
   374  func TestMergeResources(t *testing.T) {
   375  	t.Parallel()
   376  
   377  	type args struct {
   378  		dst nodeapis.Resources
   379  		src nodeapis.Resources
   380  	}
   381  	tests := []struct {
   382  		name string
   383  		args args
   384  		want nodeapis.Resources
   385  	}{
   386  		{
   387  			name: "merge capacity and allocatable",
   388  			args: args{
   389  				src: nodeapis.Resources{
   390  					Capacity: &v1.ResourceList{
   391  						v1.ResourceCPU:    resource.MustParse("10"),
   392  						v1.ResourceMemory: resource.MustParse("10"),
   393  					},
   394  				},
   395  				dst: nodeapis.Resources{
   396  					Allocatable: &v1.ResourceList{
   397  						v1.ResourceCPU:    resource.MustParse("10"),
   398  						v1.ResourceMemory: resource.MustParse("10"),
   399  					},
   400  				},
   401  			},
   402  			want: nodeapis.Resources{
   403  				Capacity: &v1.ResourceList{
   404  					v1.ResourceCPU:    resource.MustParse("10"),
   405  					v1.ResourceMemory: resource.MustParse("10"),
   406  				},
   407  				Allocatable: &v1.ResourceList{
   408  					v1.ResourceCPU:    resource.MustParse("10"),
   409  					v1.ResourceMemory: resource.MustParse("10"),
   410  				},
   411  			},
   412  		},
   413  	}
   414  	for _, tt := range tests {
   415  		tt := tt
   416  		t.Run(tt.name, func(t *testing.T) {
   417  			t.Parallel()
   418  			assert.Equalf(t, tt.want, MergeResources(tt.args.dst, tt.args.src), "MergeResources(%v, %v)", tt.args.dst, tt.args.src)
   419  		})
   420  	}
   421  }
   422  
   423  func TestMergeTopologyZone(t *testing.T) {
   424  	t.Parallel()
   425  
   426  	type args struct {
   427  		dst []*nodeapis.TopologyZone
   428  		src []*nodeapis.TopologyZone
   429  	}
   430  	tests := []struct {
   431  		name string
   432  		args args
   433  		want []*nodeapis.TopologyZone
   434  	}{
   435  		{
   436  			name: "merge two topology zone",
   437  			args: args{
   438  				src: []*nodeapis.TopologyZone{
   439  					{
   440  						Type: nodeapis.TopologyTypeSocket,
   441  						Name: "0",
   442  						Children: []*nodeapis.TopologyZone{
   443  							{
   444  								Type: nodeapis.TopologyTypeNuma,
   445  								Name: "0",
   446  								Resources: nodeapis.Resources{
   447  									Capacity: &v1.ResourceList{
   448  										"gpu": resource.MustParse("2"),
   449  									},
   450  									Allocatable: &v1.ResourceList{
   451  										"gpu": resource.MustParse("2"),
   452  									},
   453  								},
   454  								Allocations: []*nodeapis.Allocation{
   455  									{
   456  										Consumer: "default/pod-1/pod-1-uid",
   457  										Requests: &v1.ResourceList{
   458  											"gpu": resource.MustParse("1"),
   459  										},
   460  									},
   461  									{
   462  										Consumer: "default/pod-2/pod-2-uid",
   463  										Requests: &v1.ResourceList{
   464  											"gpu": resource.MustParse("1"),
   465  										},
   466  									},
   467  									{
   468  										Consumer: "default/pod-3/pod-3-uid",
   469  										Requests: &v1.ResourceList{
   470  											"gpu": resource.MustParse("1"),
   471  										},
   472  									},
   473  								},
   474  								Children: []*nodeapis.TopologyZone{
   475  									{
   476  										Type: nodeapis.TopologyTypeNIC,
   477  										Name: "eth0",
   478  										Resources: nodeapis.Resources{
   479  											Capacity: &v1.ResourceList{
   480  												"nic": resource.MustParse("10G"),
   481  											},
   482  											Allocatable: &v1.ResourceList{
   483  												"nic": resource.MustParse("10G"),
   484  											},
   485  										},
   486  										Allocations: []*nodeapis.Allocation{
   487  											{
   488  												Consumer: "default/pod-2/pod-2-uid",
   489  												Requests: &v1.ResourceList{
   490  													"nic": resource.MustParse("10G"),
   491  												},
   492  											},
   493  										},
   494  									},
   495  								},
   496  							},
   497  						},
   498  					},
   499  					{
   500  						Type: nodeapis.TopologyTypeSocket,
   501  						Name: "1",
   502  						Children: []*nodeapis.TopologyZone{
   503  							{
   504  								Type: nodeapis.TopologyTypeNuma,
   505  								Name: "1",
   506  								Resources: nodeapis.Resources{
   507  									Capacity: &v1.ResourceList{
   508  										"cpu":    resource.MustParse("24"),
   509  										"memory": resource.MustParse("32G"),
   510  									},
   511  									Allocatable: &v1.ResourceList{
   512  										"cpu":    resource.MustParse("24"),
   513  										"memory": resource.MustParse("32G"),
   514  									},
   515  								},
   516  								Allocations: []*nodeapis.Allocation{
   517  									{
   518  										Consumer: "default/pod-1/pod-1-uid",
   519  										Requests: &v1.ResourceList{
   520  											"cpu":    resource.MustParse("15"),
   521  											"memory": resource.MustParse("15G"),
   522  										},
   523  									},
   524  									{
   525  										Consumer: "default/pod-2/pod-2-uid",
   526  										Requests: &v1.ResourceList{
   527  											"gpu":    resource.MustParse("1"),
   528  											"cpu":    resource.MustParse("24"),
   529  											"memory": resource.MustParse("32G"),
   530  										},
   531  									},
   532  									{
   533  										Consumer: "default/pod-3/pod-3-uid",
   534  										Requests: &v1.ResourceList{
   535  											"gpu":    resource.MustParse("1"),
   536  											"cpu":    resource.MustParse("24"),
   537  											"memory": resource.MustParse("32G"),
   538  										},
   539  									},
   540  								},
   541  								Children: []*nodeapis.TopologyZone{
   542  									{
   543  										Type: nodeapis.TopologyTypeNIC,
   544  										Name: "eth1",
   545  										Resources: nodeapis.Resources{
   546  											Capacity: &v1.ResourceList{
   547  												"nic": resource.MustParse("10G"),
   548  											},
   549  											Allocatable: &v1.ResourceList{
   550  												"nic": resource.MustParse("10G"),
   551  											},
   552  										},
   553  									},
   554  								},
   555  							},
   556  						},
   557  					},
   558  				},
   559  				dst: []*nodeapis.TopologyZone{
   560  					{
   561  						Type: nodeapis.TopologyTypeSocket,
   562  						Name: "0",
   563  						Children: []*nodeapis.TopologyZone{
   564  							{
   565  								Type: nodeapis.TopologyTypeNuma,
   566  								Name: "0",
   567  								Resources: nodeapis.Resources{
   568  									Capacity: &v1.ResourceList{
   569  										"cpu":    resource.MustParse("24"),
   570  										"memory": resource.MustParse("32G"),
   571  									},
   572  									Allocatable: &v1.ResourceList{
   573  										"cpu":    resource.MustParse("24"),
   574  										"memory": resource.MustParse("32G"),
   575  									},
   576  								},
   577  								Allocations: []*nodeapis.Allocation{
   578  									{
   579  										Consumer: "default/pod-1/pod-1-uid",
   580  										Requests: &v1.ResourceList{
   581  											"cpu":    resource.MustParse("12"),
   582  											"memory": resource.MustParse("12G"),
   583  										},
   584  									},
   585  									{
   586  										Consumer: "default/pod-2/pod-2-uid",
   587  										Requests: &v1.ResourceList{
   588  											"cpu":    resource.MustParse("24"),
   589  											"memory": resource.MustParse("32G"),
   590  										},
   591  									},
   592  									{
   593  										Consumer: "default/pod-3/pod-3-uid",
   594  										Requests: &v1.ResourceList{
   595  											"cpu":    resource.MustParse("24"),
   596  											"memory": resource.MustParse("32G"),
   597  										},
   598  									},
   599  								},
   600  							},
   601  						},
   602  					},
   603  					{
   604  						Type: nodeapis.TopologyTypeSocket,
   605  						Name: "1",
   606  						Children: []*nodeapis.TopologyZone{
   607  							{
   608  								Type: nodeapis.TopologyTypeNuma,
   609  								Name: "1",
   610  								Resources: nodeapis.Resources{
   611  									Capacity: &v1.ResourceList{
   612  										"cpu":    resource.MustParse("24"),
   613  										"memory": resource.MustParse("32G"),
   614  									},
   615  									Allocatable: &v1.ResourceList{
   616  										"cpu":    resource.MustParse("24"),
   617  										"memory": resource.MustParse("32G"),
   618  									},
   619  								},
   620  								Allocations: []*nodeapis.Allocation{
   621  									{
   622  										Consumer: "default/pod-1/pod-1-uid",
   623  										Requests: &v1.ResourceList{
   624  											"cpu":    resource.MustParse("15"),
   625  											"memory": resource.MustParse("15G"),
   626  										},
   627  									},
   628  									{
   629  										Consumer: "default/pod-2/pod-2-uid",
   630  										Requests: &v1.ResourceList{
   631  											"cpu":    resource.MustParse("24"),
   632  											"memory": resource.MustParse("32G"),
   633  										},
   634  									},
   635  									{
   636  										Consumer: "default/pod-3/pod-3-uid",
   637  										Requests: &v1.ResourceList{
   638  											"cpu":    resource.MustParse("24"),
   639  											"memory": resource.MustParse("32G"),
   640  										},
   641  									},
   642  								},
   643  							},
   644  						},
   645  					},
   646  				},
   647  			},
   648  			want: []*nodeapis.TopologyZone{
   649  				{
   650  					Type: nodeapis.TopologyTypeSocket,
   651  					Name: "0",
   652  					Children: []*nodeapis.TopologyZone{
   653  						{
   654  							Type: nodeapis.TopologyTypeNuma,
   655  							Name: "0",
   656  							Resources: nodeapis.Resources{
   657  								Capacity: &v1.ResourceList{
   658  									"gpu":    resource.MustParse("2"),
   659  									"cpu":    resource.MustParse("24"),
   660  									"memory": resource.MustParse("32G"),
   661  								},
   662  								Allocatable: &v1.ResourceList{
   663  									"gpu":    resource.MustParse("2"),
   664  									"cpu":    resource.MustParse("24"),
   665  									"memory": resource.MustParse("32G"),
   666  								},
   667  							},
   668  							Allocations: []*nodeapis.Allocation{
   669  								{
   670  									Consumer: "default/pod-1/pod-1-uid",
   671  									Requests: &v1.ResourceList{
   672  										"gpu":    resource.MustParse("1"),
   673  										"cpu":    resource.MustParse("12"),
   674  										"memory": resource.MustParse("12G"),
   675  									},
   676  								},
   677  								{
   678  									Consumer: "default/pod-2/pod-2-uid",
   679  									Requests: &v1.ResourceList{
   680  										"gpu":    resource.MustParse("1"),
   681  										"cpu":    resource.MustParse("24"),
   682  										"memory": resource.MustParse("32G"),
   683  									},
   684  								},
   685  								{
   686  									Consumer: "default/pod-3/pod-3-uid",
   687  									Requests: &v1.ResourceList{
   688  										"gpu":    resource.MustParse("1"),
   689  										"cpu":    resource.MustParse("24"),
   690  										"memory": resource.MustParse("32G"),
   691  									},
   692  								},
   693  							},
   694  							Children: []*nodeapis.TopologyZone{
   695  								{
   696  									Type: nodeapis.TopologyTypeNIC,
   697  									Name: "eth0",
   698  									Resources: nodeapis.Resources{
   699  										Capacity: &v1.ResourceList{
   700  											"nic": resource.MustParse("10G"),
   701  										},
   702  										Allocatable: &v1.ResourceList{
   703  											"nic": resource.MustParse("10G"),
   704  										},
   705  									},
   706  									Allocations: []*nodeapis.Allocation{
   707  										{
   708  											Consumer: "default/pod-2/pod-2-uid",
   709  											Requests: &v1.ResourceList{
   710  												"nic": resource.MustParse("10G"),
   711  											},
   712  										},
   713  									},
   714  								},
   715  							},
   716  						},
   717  					},
   718  				},
   719  				{
   720  					Type: nodeapis.TopologyTypeSocket,
   721  					Name: "1",
   722  					Children: []*nodeapis.TopologyZone{
   723  						{
   724  							Type: nodeapis.TopologyTypeNuma,
   725  							Name: "1",
   726  							Resources: nodeapis.Resources{
   727  								Capacity: &v1.ResourceList{
   728  									"cpu":    resource.MustParse("24"),
   729  									"memory": resource.MustParse("32G"),
   730  								},
   731  								Allocatable: &v1.ResourceList{
   732  									"cpu":    resource.MustParse("24"),
   733  									"memory": resource.MustParse("32G"),
   734  								},
   735  							},
   736  							Allocations: []*nodeapis.Allocation{
   737  								{
   738  									Consumer: "default/pod-1/pod-1-uid",
   739  									Requests: &v1.ResourceList{
   740  										"cpu":    resource.MustParse("15"),
   741  										"memory": resource.MustParse("15G"),
   742  									},
   743  								},
   744  								{
   745  									Consumer: "default/pod-2/pod-2-uid",
   746  									Requests: &v1.ResourceList{
   747  										"gpu":    resource.MustParse("1"),
   748  										"cpu":    resource.MustParse("24"),
   749  										"memory": resource.MustParse("32G"),
   750  									},
   751  								},
   752  								{
   753  									Consumer: "default/pod-3/pod-3-uid",
   754  									Requests: &v1.ResourceList{
   755  										"gpu":    resource.MustParse("1"),
   756  										"cpu":    resource.MustParse("24"),
   757  										"memory": resource.MustParse("32G"),
   758  									},
   759  								},
   760  							},
   761  							Children: []*nodeapis.TopologyZone{
   762  								{
   763  									Type: nodeapis.TopologyTypeNIC,
   764  									Name: "eth1",
   765  									Resources: nodeapis.Resources{
   766  										Capacity: &v1.ResourceList{
   767  											"nic": resource.MustParse("10G"),
   768  										},
   769  										Allocatable: &v1.ResourceList{
   770  											"nic": resource.MustParse("10G"),
   771  										},
   772  									},
   773  								},
   774  							},
   775  						},
   776  					},
   777  				},
   778  			},
   779  		},
   780  		{
   781  			name: "merge two topology zone with siblings",
   782  			args: args{
   783  				src: []*nodeapis.TopologyZone{
   784  					{
   785  						Type: nodeapis.TopologyTypeSocket,
   786  						Name: "0",
   787  						Children: []*nodeapis.TopologyZone{
   788  							{
   789  								Type: nodeapis.TopologyTypeNuma,
   790  								Name: "0",
   791  								Resources: nodeapis.Resources{
   792  									Capacity: &v1.ResourceList{
   793  										"gpu":    resource.MustParse("2"),
   794  										"cpu":    resource.MustParse("24"),
   795  										"memory": resource.MustParse("32G"),
   796  									},
   797  									Allocatable: &v1.ResourceList{
   798  										"gpu":    resource.MustParse("2"),
   799  										"cpu":    resource.MustParse("24"),
   800  										"memory": resource.MustParse("32G"),
   801  									},
   802  								},
   803  								Allocations: []*nodeapis.Allocation{
   804  									{
   805  										Consumer: "default/pod-1/pod-1-uid",
   806  										Requests: &v1.ResourceList{
   807  											"gpu":    resource.MustParse("1"),
   808  											"cpu":    resource.MustParse("12"),
   809  											"memory": resource.MustParse("12G"),
   810  										},
   811  									},
   812  									{
   813  										Consumer: "default/pod-2/pod-2-uid",
   814  										Requests: &v1.ResourceList{
   815  											"gpu":    resource.MustParse("1"),
   816  											"cpu":    resource.MustParse("24"),
   817  											"memory": resource.MustParse("32G"),
   818  										},
   819  									},
   820  									{
   821  										Consumer: "default/pod-3/pod-3-uid",
   822  										Requests: &v1.ResourceList{
   823  											"gpu":    resource.MustParse("1"),
   824  											"cpu":    resource.MustParse("24"),
   825  											"memory": resource.MustParse("32G"),
   826  										},
   827  									},
   828  								},
   829  								Children: []*nodeapis.TopologyZone{
   830  									{
   831  										Type: nodeapis.TopologyTypeNIC,
   832  										Name: "eth0",
   833  										Resources: nodeapis.Resources{
   834  											Capacity: &v1.ResourceList{
   835  												"nic": resource.MustParse("10G"),
   836  											},
   837  											Allocatable: &v1.ResourceList{
   838  												"nic": resource.MustParse("10G"),
   839  											},
   840  										},
   841  										Allocations: []*nodeapis.Allocation{
   842  											{
   843  												Consumer: "default/pod-2/pod-2-uid",
   844  												Requests: &v1.ResourceList{
   845  													"nic": resource.MustParse("10G"),
   846  												},
   847  											},
   848  										},
   849  									},
   850  								},
   851  								Siblings: []nodeapis.Sibling{
   852  									{
   853  										Type: nodeapis.TopologyTypeNuma,
   854  										Name: "1",
   855  									},
   856  								},
   857  							},
   858  							{
   859  								Type: nodeapis.TopologyTypeNuma,
   860  								Name: "1",
   861  								Resources: nodeapis.Resources{
   862  									Capacity: &v1.ResourceList{
   863  										"gpu":    resource.MustParse("2"),
   864  										"cpu":    resource.MustParse("24"),
   865  										"memory": resource.MustParse("32G"),
   866  									},
   867  									Allocatable: &v1.ResourceList{
   868  										"gpu":    resource.MustParse("2"),
   869  										"cpu":    resource.MustParse("24"),
   870  										"memory": resource.MustParse("32G"),
   871  									},
   872  								},
   873  								Allocations: []*nodeapis.Allocation{
   874  									{
   875  										Consumer: "default/pod-1/pod-1-uid",
   876  										Requests: &v1.ResourceList{
   877  											"gpu":    resource.MustParse("1"),
   878  											"cpu":    resource.MustParse("12"),
   879  											"memory": resource.MustParse("12G"),
   880  										},
   881  									},
   882  									{
   883  										Consumer: "default/pod-2/pod-2-uid",
   884  										Requests: &v1.ResourceList{
   885  											"gpu":    resource.MustParse("1"),
   886  											"cpu":    resource.MustParse("24"),
   887  											"memory": resource.MustParse("32G"),
   888  										},
   889  									},
   890  									{
   891  										Consumer: "default/pod-3/pod-3-uid",
   892  										Requests: &v1.ResourceList{
   893  											"gpu":    resource.MustParse("1"),
   894  											"cpu":    resource.MustParse("24"),
   895  											"memory": resource.MustParse("32G"),
   896  										},
   897  									},
   898  								},
   899  								Children: []*nodeapis.TopologyZone{
   900  									{
   901  										Type: nodeapis.TopologyTypeNIC,
   902  										Name: "eth0",
   903  										Resources: nodeapis.Resources{
   904  											Capacity: &v1.ResourceList{
   905  												"nic": resource.MustParse("10G"),
   906  											},
   907  											Allocatable: &v1.ResourceList{
   908  												"nic": resource.MustParse("10G"),
   909  											},
   910  										},
   911  										Allocations: []*nodeapis.Allocation{
   912  											{
   913  												Consumer: "default/pod-2/pod-2-uid",
   914  												Requests: &v1.ResourceList{
   915  													"nic": resource.MustParse("10G"),
   916  												},
   917  											},
   918  										},
   919  									},
   920  								},
   921  								Siblings: []nodeapis.Sibling{
   922  									{
   923  										Type: nodeapis.TopologyTypeNuma,
   924  										Name: "0",
   925  									},
   926  								},
   927  							},
   928  						},
   929  					},
   930  					{
   931  						Type: nodeapis.TopologyTypeSocket,
   932  						Name: "1",
   933  						Children: []*nodeapis.TopologyZone{
   934  							{
   935  								Type: nodeapis.TopologyTypeNuma,
   936  								Name: "2",
   937  								Resources: nodeapis.Resources{
   938  									Capacity: &v1.ResourceList{
   939  										"cpu":    resource.MustParse("24"),
   940  										"memory": resource.MustParse("32G"),
   941  									},
   942  									Allocatable: &v1.ResourceList{
   943  										"cpu":    resource.MustParse("24"),
   944  										"memory": resource.MustParse("32G"),
   945  									},
   946  								},
   947  								Allocations: []*nodeapis.Allocation{
   948  									{
   949  										Consumer: "default/pod-1/pod-1-uid",
   950  										Requests: &v1.ResourceList{
   951  											"cpu":    resource.MustParse("15"),
   952  											"memory": resource.MustParse("15G"),
   953  										},
   954  									},
   955  									{
   956  										Consumer: "default/pod-2/pod-2-uid",
   957  										Requests: &v1.ResourceList{
   958  											"gpu":    resource.MustParse("1"),
   959  											"cpu":    resource.MustParse("24"),
   960  											"memory": resource.MustParse("32G"),
   961  										},
   962  									},
   963  									{
   964  										Consumer: "default/pod-3/pod-3-uid",
   965  										Requests: &v1.ResourceList{
   966  											"gpu":    resource.MustParse("1"),
   967  											"cpu":    resource.MustParse("24"),
   968  											"memory": resource.MustParse("32G"),
   969  										},
   970  									},
   971  								},
   972  								Children: []*nodeapis.TopologyZone{
   973  									{
   974  										Type: nodeapis.TopologyTypeNIC,
   975  										Name: "eth1",
   976  										Resources: nodeapis.Resources{
   977  											Capacity: &v1.ResourceList{
   978  												"nic": resource.MustParse("10G"),
   979  											},
   980  											Allocatable: &v1.ResourceList{
   981  												"nic": resource.MustParse("10G"),
   982  											},
   983  										},
   984  									},
   985  								},
   986  								Siblings: []nodeapis.Sibling{
   987  									{
   988  										Type: nodeapis.TopologyTypeNuma,
   989  										Name: "3",
   990  									},
   991  								},
   992  							},
   993  							{
   994  								Type: nodeapis.TopologyTypeNuma,
   995  								Name: "3",
   996  								Resources: nodeapis.Resources{
   997  									Capacity: &v1.ResourceList{
   998  										"cpu":    resource.MustParse("24"),
   999  										"memory": resource.MustParse("32G"),
  1000  									},
  1001  									Allocatable: &v1.ResourceList{
  1002  										"cpu":    resource.MustParse("24"),
  1003  										"memory": resource.MustParse("32G"),
  1004  									},
  1005  								},
  1006  								Allocations: []*nodeapis.Allocation{
  1007  									{
  1008  										Consumer: "default/pod-1/pod-1-uid",
  1009  										Requests: &v1.ResourceList{
  1010  											"cpu":    resource.MustParse("15"),
  1011  											"memory": resource.MustParse("15G"),
  1012  										},
  1013  									},
  1014  									{
  1015  										Consumer: "default/pod-2/pod-2-uid",
  1016  										Requests: &v1.ResourceList{
  1017  											"gpu":    resource.MustParse("1"),
  1018  											"cpu":    resource.MustParse("24"),
  1019  											"memory": resource.MustParse("32G"),
  1020  										},
  1021  									},
  1022  									{
  1023  										Consumer: "default/pod-3/pod-3-uid",
  1024  										Requests: &v1.ResourceList{
  1025  											"gpu":    resource.MustParse("1"),
  1026  											"cpu":    resource.MustParse("24"),
  1027  											"memory": resource.MustParse("32G"),
  1028  										},
  1029  									},
  1030  								},
  1031  								Children: []*nodeapis.TopologyZone{
  1032  									{
  1033  										Type: nodeapis.TopologyTypeNIC,
  1034  										Name: "eth1",
  1035  										Resources: nodeapis.Resources{
  1036  											Capacity: &v1.ResourceList{
  1037  												"nic": resource.MustParse("10G"),
  1038  											},
  1039  											Allocatable: &v1.ResourceList{
  1040  												"nic": resource.MustParse("10G"),
  1041  											},
  1042  										},
  1043  									},
  1044  								},
  1045  								Siblings: []nodeapis.Sibling{
  1046  									{
  1047  										Type: nodeapis.TopologyTypeNuma,
  1048  										Name: "2",
  1049  									},
  1050  								},
  1051  							},
  1052  						},
  1053  					},
  1054  				},
  1055  				dst: []*nodeapis.TopologyZone{
  1056  					{
  1057  						Type: nodeapis.TopologyTypeSocket,
  1058  						Name: "0",
  1059  						Children: []*nodeapis.TopologyZone{
  1060  							{
  1061  								Type: nodeapis.TopologyTypeNuma,
  1062  								Name: "0",
  1063  								Siblings: []nodeapis.Sibling{
  1064  									{
  1065  										Type: nodeapis.TopologyTypeNuma,
  1066  										Name: "1",
  1067  										Attributes: []nodeapis.Attribute{
  1068  											{
  1069  												Name:  "aa",
  1070  												Value: "bb",
  1071  											},
  1072  										},
  1073  									},
  1074  								},
  1075  							},
  1076  							{
  1077  								Type: nodeapis.TopologyTypeNuma,
  1078  								Name: "1",
  1079  								Siblings: []nodeapis.Sibling{
  1080  									{
  1081  										Type: nodeapis.TopologyTypeNuma,
  1082  										Name: "0",
  1083  										Attributes: []nodeapis.Attribute{
  1084  											{
  1085  												Name:  "aa",
  1086  												Value: "bb",
  1087  											},
  1088  										},
  1089  									},
  1090  								},
  1091  							},
  1092  						},
  1093  					},
  1094  					{
  1095  						Type: nodeapis.TopologyTypeSocket,
  1096  						Name: "1",
  1097  						Children: []*nodeapis.TopologyZone{
  1098  							{
  1099  								Type: nodeapis.TopologyTypeNuma,
  1100  								Name: "2",
  1101  								Siblings: []nodeapis.Sibling{
  1102  									{
  1103  										Type: nodeapis.TopologyTypeNuma,
  1104  										Name: "3",
  1105  										Attributes: []nodeapis.Attribute{
  1106  											{
  1107  												Name:  "aa",
  1108  												Value: "bb",
  1109  											},
  1110  										},
  1111  									},
  1112  								},
  1113  							},
  1114  							{
  1115  								Type: nodeapis.TopologyTypeNuma,
  1116  								Name: "3",
  1117  								Siblings: []nodeapis.Sibling{
  1118  									{
  1119  										Type: nodeapis.TopologyTypeNuma,
  1120  										Name: "2",
  1121  										Attributes: []nodeapis.Attribute{
  1122  											{
  1123  												Name:  "aa",
  1124  												Value: "bb",
  1125  											},
  1126  										},
  1127  									},
  1128  								},
  1129  							},
  1130  						},
  1131  					},
  1132  				},
  1133  			},
  1134  			want: []*nodeapis.TopologyZone{
  1135  				{
  1136  					Type: nodeapis.TopologyTypeSocket,
  1137  					Name: "0",
  1138  					Children: []*nodeapis.TopologyZone{
  1139  						{
  1140  							Type: nodeapis.TopologyTypeNuma,
  1141  							Name: "0",
  1142  							Resources: nodeapis.Resources{
  1143  								Capacity: &v1.ResourceList{
  1144  									"gpu":    resource.MustParse("2"),
  1145  									"cpu":    resource.MustParse("24"),
  1146  									"memory": resource.MustParse("32G"),
  1147  								},
  1148  								Allocatable: &v1.ResourceList{
  1149  									"gpu":    resource.MustParse("2"),
  1150  									"cpu":    resource.MustParse("24"),
  1151  									"memory": resource.MustParse("32G"),
  1152  								},
  1153  							},
  1154  							Allocations: []*nodeapis.Allocation{
  1155  								{
  1156  									Consumer: "default/pod-1/pod-1-uid",
  1157  									Requests: &v1.ResourceList{
  1158  										"gpu":    resource.MustParse("1"),
  1159  										"cpu":    resource.MustParse("12"),
  1160  										"memory": resource.MustParse("12G"),
  1161  									},
  1162  								},
  1163  								{
  1164  									Consumer: "default/pod-2/pod-2-uid",
  1165  									Requests: &v1.ResourceList{
  1166  										"gpu":    resource.MustParse("1"),
  1167  										"cpu":    resource.MustParse("24"),
  1168  										"memory": resource.MustParse("32G"),
  1169  									},
  1170  								},
  1171  								{
  1172  									Consumer: "default/pod-3/pod-3-uid",
  1173  									Requests: &v1.ResourceList{
  1174  										"gpu":    resource.MustParse("1"),
  1175  										"cpu":    resource.MustParse("24"),
  1176  										"memory": resource.MustParse("32G"),
  1177  									},
  1178  								},
  1179  							},
  1180  							Children: []*nodeapis.TopologyZone{
  1181  								{
  1182  									Type: nodeapis.TopologyTypeNIC,
  1183  									Name: "eth0",
  1184  									Resources: nodeapis.Resources{
  1185  										Capacity: &v1.ResourceList{
  1186  											"nic": resource.MustParse("10G"),
  1187  										},
  1188  										Allocatable: &v1.ResourceList{
  1189  											"nic": resource.MustParse("10G"),
  1190  										},
  1191  									},
  1192  									Allocations: []*nodeapis.Allocation{
  1193  										{
  1194  											Consumer: "default/pod-2/pod-2-uid",
  1195  											Requests: &v1.ResourceList{
  1196  												"nic": resource.MustParse("10G"),
  1197  											},
  1198  										},
  1199  									},
  1200  								},
  1201  							},
  1202  							Siblings: []nodeapis.Sibling{
  1203  								{
  1204  									Type: nodeapis.TopologyTypeNuma,
  1205  									Name: "1",
  1206  									Attributes: []nodeapis.Attribute{
  1207  										{
  1208  											Name:  "aa",
  1209  											Value: "bb",
  1210  										},
  1211  									},
  1212  								},
  1213  							},
  1214  						},
  1215  						{
  1216  							Type: nodeapis.TopologyTypeNuma,
  1217  							Name: "1",
  1218  							Resources: nodeapis.Resources{
  1219  								Capacity: &v1.ResourceList{
  1220  									"gpu":    resource.MustParse("2"),
  1221  									"cpu":    resource.MustParse("24"),
  1222  									"memory": resource.MustParse("32G"),
  1223  								},
  1224  								Allocatable: &v1.ResourceList{
  1225  									"gpu":    resource.MustParse("2"),
  1226  									"cpu":    resource.MustParse("24"),
  1227  									"memory": resource.MustParse("32G"),
  1228  								},
  1229  							},
  1230  							Allocations: []*nodeapis.Allocation{
  1231  								{
  1232  									Consumer: "default/pod-1/pod-1-uid",
  1233  									Requests: &v1.ResourceList{
  1234  										"gpu":    resource.MustParse("1"),
  1235  										"cpu":    resource.MustParse("12"),
  1236  										"memory": resource.MustParse("12G"),
  1237  									},
  1238  								},
  1239  								{
  1240  									Consumer: "default/pod-2/pod-2-uid",
  1241  									Requests: &v1.ResourceList{
  1242  										"gpu":    resource.MustParse("1"),
  1243  										"cpu":    resource.MustParse("24"),
  1244  										"memory": resource.MustParse("32G"),
  1245  									},
  1246  								},
  1247  								{
  1248  									Consumer: "default/pod-3/pod-3-uid",
  1249  									Requests: &v1.ResourceList{
  1250  										"gpu":    resource.MustParse("1"),
  1251  										"cpu":    resource.MustParse("24"),
  1252  										"memory": resource.MustParse("32G"),
  1253  									},
  1254  								},
  1255  							},
  1256  							Children: []*nodeapis.TopologyZone{
  1257  								{
  1258  									Type: nodeapis.TopologyTypeNIC,
  1259  									Name: "eth0",
  1260  									Resources: nodeapis.Resources{
  1261  										Capacity: &v1.ResourceList{
  1262  											"nic": resource.MustParse("10G"),
  1263  										},
  1264  										Allocatable: &v1.ResourceList{
  1265  											"nic": resource.MustParse("10G"),
  1266  										},
  1267  									},
  1268  									Allocations: []*nodeapis.Allocation{
  1269  										{
  1270  											Consumer: "default/pod-2/pod-2-uid",
  1271  											Requests: &v1.ResourceList{
  1272  												"nic": resource.MustParse("10G"),
  1273  											},
  1274  										},
  1275  									},
  1276  								},
  1277  							},
  1278  							Siblings: []nodeapis.Sibling{
  1279  								{
  1280  									Type: nodeapis.TopologyTypeNuma,
  1281  									Name: "0",
  1282  									Attributes: []nodeapis.Attribute{
  1283  										{
  1284  											Name:  "aa",
  1285  											Value: "bb",
  1286  										},
  1287  									},
  1288  								},
  1289  							},
  1290  						},
  1291  					},
  1292  				},
  1293  				{
  1294  					Type: nodeapis.TopologyTypeSocket,
  1295  					Name: "1",
  1296  					Children: []*nodeapis.TopologyZone{
  1297  						{
  1298  							Type: nodeapis.TopologyTypeNuma,
  1299  							Name: "2",
  1300  							Resources: nodeapis.Resources{
  1301  								Capacity: &v1.ResourceList{
  1302  									"cpu":    resource.MustParse("24"),
  1303  									"memory": resource.MustParse("32G"),
  1304  								},
  1305  								Allocatable: &v1.ResourceList{
  1306  									"cpu":    resource.MustParse("24"),
  1307  									"memory": resource.MustParse("32G"),
  1308  								},
  1309  							},
  1310  							Allocations: []*nodeapis.Allocation{
  1311  								{
  1312  									Consumer: "default/pod-1/pod-1-uid",
  1313  									Requests: &v1.ResourceList{
  1314  										"cpu":    resource.MustParse("15"),
  1315  										"memory": resource.MustParse("15G"),
  1316  									},
  1317  								},
  1318  								{
  1319  									Consumer: "default/pod-2/pod-2-uid",
  1320  									Requests: &v1.ResourceList{
  1321  										"gpu":    resource.MustParse("1"),
  1322  										"cpu":    resource.MustParse("24"),
  1323  										"memory": resource.MustParse("32G"),
  1324  									},
  1325  								},
  1326  								{
  1327  									Consumer: "default/pod-3/pod-3-uid",
  1328  									Requests: &v1.ResourceList{
  1329  										"gpu":    resource.MustParse("1"),
  1330  										"cpu":    resource.MustParse("24"),
  1331  										"memory": resource.MustParse("32G"),
  1332  									},
  1333  								},
  1334  							},
  1335  							Children: []*nodeapis.TopologyZone{
  1336  								{
  1337  									Type: nodeapis.TopologyTypeNIC,
  1338  									Name: "eth1",
  1339  									Resources: nodeapis.Resources{
  1340  										Capacity: &v1.ResourceList{
  1341  											"nic": resource.MustParse("10G"),
  1342  										},
  1343  										Allocatable: &v1.ResourceList{
  1344  											"nic": resource.MustParse("10G"),
  1345  										},
  1346  									},
  1347  								},
  1348  							},
  1349  							Siblings: []nodeapis.Sibling{
  1350  								{
  1351  									Type: nodeapis.TopologyTypeNuma,
  1352  									Name: "3",
  1353  									Attributes: []nodeapis.Attribute{
  1354  										{
  1355  											Name:  "aa",
  1356  											Value: "bb",
  1357  										},
  1358  									},
  1359  								},
  1360  							},
  1361  						},
  1362  						{
  1363  							Type: nodeapis.TopologyTypeNuma,
  1364  							Name: "3",
  1365  							Resources: nodeapis.Resources{
  1366  								Capacity: &v1.ResourceList{
  1367  									"cpu":    resource.MustParse("24"),
  1368  									"memory": resource.MustParse("32G"),
  1369  								},
  1370  								Allocatable: &v1.ResourceList{
  1371  									"cpu":    resource.MustParse("24"),
  1372  									"memory": resource.MustParse("32G"),
  1373  								},
  1374  							},
  1375  							Allocations: []*nodeapis.Allocation{
  1376  								{
  1377  									Consumer: "default/pod-1/pod-1-uid",
  1378  									Requests: &v1.ResourceList{
  1379  										"cpu":    resource.MustParse("15"),
  1380  										"memory": resource.MustParse("15G"),
  1381  									},
  1382  								},
  1383  								{
  1384  									Consumer: "default/pod-2/pod-2-uid",
  1385  									Requests: &v1.ResourceList{
  1386  										"gpu":    resource.MustParse("1"),
  1387  										"cpu":    resource.MustParse("24"),
  1388  										"memory": resource.MustParse("32G"),
  1389  									},
  1390  								},
  1391  								{
  1392  									Consumer: "default/pod-3/pod-3-uid",
  1393  									Requests: &v1.ResourceList{
  1394  										"gpu":    resource.MustParse("1"),
  1395  										"cpu":    resource.MustParse("24"),
  1396  										"memory": resource.MustParse("32G"),
  1397  									},
  1398  								},
  1399  							},
  1400  							Children: []*nodeapis.TopologyZone{
  1401  								{
  1402  									Type: nodeapis.TopologyTypeNIC,
  1403  									Name: "eth1",
  1404  									Resources: nodeapis.Resources{
  1405  										Capacity: &v1.ResourceList{
  1406  											"nic": resource.MustParse("10G"),
  1407  										},
  1408  										Allocatable: &v1.ResourceList{
  1409  											"nic": resource.MustParse("10G"),
  1410  										},
  1411  									},
  1412  								},
  1413  							},
  1414  							Siblings: []nodeapis.Sibling{
  1415  								{
  1416  									Type: nodeapis.TopologyTypeNuma,
  1417  									Name: "2",
  1418  									Attributes: []nodeapis.Attribute{
  1419  										{
  1420  											Name:  "aa",
  1421  											Value: "bb",
  1422  										},
  1423  									},
  1424  								},
  1425  							},
  1426  						},
  1427  					},
  1428  				},
  1429  			},
  1430  		},
  1431  	}
  1432  	for _, tt := range tests {
  1433  		tt := tt
  1434  		t.Run(tt.name, func(t *testing.T) {
  1435  			t.Parallel()
  1436  			expect := MergeTopologyZone(tt.args.dst, tt.args.src)
  1437  			assert.Equalf(t, tt.want, expect, "MergeTopologyZone(%v, %v)", tt.args.dst, tt.args.src)
  1438  		})
  1439  	}
  1440  }