...

Source file src/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers_test.go

Documentation: k8s.io/kubernetes/pkg/apis/core/v1/helper

     1  /*
     2  Copyright 2015 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 helper
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"testing"
    23  
    24  	v1 "k8s.io/api/core/v1"
    25  	"k8s.io/apimachinery/pkg/api/resource"
    26  	"k8s.io/apimachinery/pkg/labels"
    27  )
    28  
    29  func TestIsNativeResource(t *testing.T) {
    30  	testCases := []struct {
    31  		resourceName v1.ResourceName
    32  		expectVal    bool
    33  	}{
    34  		{
    35  			resourceName: "pod.alpha.kubernetes.io/opaque-int-resource-foo",
    36  			expectVal:    true,
    37  		},
    38  		{
    39  			resourceName: "kubernetes.io/resource-foo",
    40  			expectVal:    true,
    41  		},
    42  		{
    43  			resourceName: "foo",
    44  			expectVal:    true,
    45  		},
    46  		{
    47  			resourceName: "a/b",
    48  			expectVal:    false,
    49  		},
    50  		{
    51  			resourceName: "",
    52  			expectVal:    true,
    53  		},
    54  	}
    55  
    56  	for _, tc := range testCases {
    57  		tc := tc
    58  		t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
    59  			t.Parallel()
    60  			v := IsNativeResource(tc.resourceName)
    61  			if v != tc.expectVal {
    62  				t.Errorf("Got %v but expected %v", v, tc.expectVal)
    63  			}
    64  		})
    65  	}
    66  }
    67  
    68  func TestHugePageSizeFromResourceName(t *testing.T) {
    69  	expected100m, _ := resource.ParseQuantity("100m")
    70  	testCases := []struct {
    71  		resourceName v1.ResourceName
    72  		expectVal    resource.Quantity
    73  		expectErr    bool
    74  	}{
    75  		{
    76  			resourceName: "pod.alpha.kubernetes.io/opaque-int-resource-foo",
    77  			expectVal:    resource.Quantity{},
    78  			expectErr:    true,
    79  		},
    80  		{
    81  			resourceName: "hugepages-",
    82  			expectVal:    resource.Quantity{},
    83  			expectErr:    true,
    84  		},
    85  		{
    86  			resourceName: "hugepages-100m",
    87  			expectVal:    expected100m,
    88  			expectErr:    false,
    89  		},
    90  		{
    91  			resourceName: "",
    92  			expectVal:    resource.Quantity{},
    93  			expectErr:    true,
    94  		},
    95  	}
    96  
    97  	for i, tc := range testCases {
    98  		i := i
    99  		tc := tc
   100  		t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
   101  			t.Parallel()
   102  			v, err := HugePageSizeFromResourceName(tc.resourceName)
   103  			if err == nil && tc.expectErr {
   104  				t.Errorf("[%v]expected error but got none.", i)
   105  			}
   106  			if err != nil && !tc.expectErr {
   107  				t.Errorf("[%v]did not expect error but got: %v", i, err)
   108  			}
   109  			if v != tc.expectVal {
   110  				t.Errorf("Got %v but expected %v", v, tc.expectVal)
   111  			}
   112  		})
   113  	}
   114  }
   115  
   116  func TestHugePageSizeFromMedium(t *testing.T) {
   117  	testCases := []struct {
   118  		description string
   119  		medium      v1.StorageMedium
   120  		expectVal   resource.Quantity
   121  		expectErr   bool
   122  	}{
   123  		{
   124  			description: "Invalid hugepages medium",
   125  			medium:      "Memory",
   126  			expectVal:   resource.Quantity{},
   127  			expectErr:   true,
   128  		},
   129  		{
   130  			description: "Invalid hugepages medium",
   131  			medium:      "Memory",
   132  			expectVal:   resource.Quantity{},
   133  			expectErr:   true,
   134  		},
   135  		{
   136  			description: "Invalid: HugePages without size",
   137  			medium:      "HugePages",
   138  			expectVal:   resource.Quantity{},
   139  			expectErr:   true,
   140  		},
   141  		{
   142  			description: "Invalid: HugePages without size",
   143  			medium:      "HugePages",
   144  			expectVal:   resource.Quantity{},
   145  			expectErr:   true,
   146  		},
   147  		{
   148  			description: "Valid: HugePages-1Gi",
   149  			medium:      "HugePages-1Gi",
   150  			expectVal:   resource.MustParse("1Gi"),
   151  			expectErr:   false,
   152  		},
   153  		{
   154  			description: "Valid: HugePages-2Mi",
   155  			medium:      "HugePages-2Mi",
   156  			expectVal:   resource.MustParse("2Mi"),
   157  			expectErr:   false,
   158  		},
   159  		{
   160  			description: "Valid: HugePages-64Ki",
   161  			medium:      "HugePages-64Ki",
   162  			expectVal:   resource.MustParse("64Ki"),
   163  			expectErr:   false,
   164  		},
   165  	}
   166  	for i, tc := range testCases {
   167  		i := i
   168  		tc := tc
   169  		t.Run(tc.description, func(t *testing.T) {
   170  			t.Parallel()
   171  			v, err := HugePageSizeFromMedium(tc.medium)
   172  			if err == nil && tc.expectErr {
   173  				t.Errorf("[%v]expected error but got none.", i)
   174  			}
   175  			if err != nil && !tc.expectErr {
   176  				t.Errorf("[%v]did not expect error but got: %v", i, err)
   177  			}
   178  			if v != tc.expectVal {
   179  				t.Errorf("Got %v but expected %v", v, tc.expectVal)
   180  			}
   181  		})
   182  	}
   183  }
   184  
   185  func TestIsOvercommitAllowed(t *testing.T) {
   186  	testCases := []struct {
   187  		resourceName v1.ResourceName
   188  		expectVal    bool
   189  	}{
   190  		{
   191  			resourceName: "pod.alpha.kubernetes.io/opaque-int-resource-foo",
   192  			expectVal:    true,
   193  		},
   194  		{
   195  			resourceName: "kubernetes.io/resource-foo",
   196  			expectVal:    true,
   197  		},
   198  		{
   199  			resourceName: "hugepages-100m",
   200  			expectVal:    false,
   201  		},
   202  		{
   203  			resourceName: "",
   204  			expectVal:    true,
   205  		},
   206  	}
   207  
   208  	for _, tc := range testCases {
   209  		tc := tc
   210  		t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
   211  			t.Parallel()
   212  			v := IsOvercommitAllowed(tc.resourceName)
   213  			if v != tc.expectVal {
   214  				t.Errorf("Got %v but expected %v", v, tc.expectVal)
   215  			}
   216  		})
   217  	}
   218  }
   219  
   220  func TestGetAccessModesFromString(t *testing.T) {
   221  	modes := GetAccessModesFromString("ROX")
   222  	if !ContainsAccessMode(modes, v1.ReadOnlyMany) {
   223  		t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
   224  	}
   225  
   226  	modes = GetAccessModesFromString("ROX,RWX")
   227  	if !ContainsAccessMode(modes, v1.ReadOnlyMany) {
   228  		t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
   229  	}
   230  	if !ContainsAccessMode(modes, v1.ReadWriteMany) {
   231  		t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteMany, modes)
   232  	}
   233  
   234  	modes = GetAccessModesFromString("RWO,ROX,RWX")
   235  	if !ContainsAccessMode(modes, v1.ReadWriteOnce) {
   236  		t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteOnce, modes)
   237  	}
   238  	if !ContainsAccessMode(modes, v1.ReadOnlyMany) {
   239  		t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
   240  	}
   241  	if !ContainsAccessMode(modes, v1.ReadWriteMany) {
   242  		t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteMany, modes)
   243  	}
   244  
   245  	modes = GetAccessModesFromString("RWO,ROX,RWX,RWOP")
   246  	if !ContainsAccessMode(modes, v1.ReadWriteOnce) {
   247  		t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteOnce, modes)
   248  	}
   249  	if !ContainsAccessMode(modes, v1.ReadOnlyMany) {
   250  		t.Errorf("Expected mode %s, but got %+v", v1.ReadOnlyMany, modes)
   251  	}
   252  	if !ContainsAccessMode(modes, v1.ReadWriteMany) {
   253  		t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteMany, modes)
   254  	}
   255  	if !ContainsAccessMode(modes, v1.ReadWriteOncePod) {
   256  		t.Errorf("Expected mode %s, but got %+v", v1.ReadWriteOncePod, modes)
   257  	}
   258  }
   259  
   260  func TestRemoveDuplicateAccessModes(t *testing.T) {
   261  	modes := []v1.PersistentVolumeAccessMode{
   262  		v1.ReadWriteOnce, v1.ReadOnlyMany, v1.ReadOnlyMany, v1.ReadOnlyMany,
   263  	}
   264  	modes = removeDuplicateAccessModes(modes)
   265  	if len(modes) != 2 {
   266  		t.Errorf("Expected 2 distinct modes in set but found %v", len(modes))
   267  	}
   268  }
   269  
   270  func TestTopologySelectorRequirementsAsSelector(t *testing.T) {
   271  	mustParse := func(s string) labels.Selector {
   272  		out, e := labels.Parse(s)
   273  		if e != nil {
   274  			panic(e)
   275  		}
   276  		return out
   277  	}
   278  	tc := []struct {
   279  		in        []v1.TopologySelectorLabelRequirement
   280  		out       labels.Selector
   281  		expectErr bool
   282  	}{
   283  		{in: nil, out: labels.Nothing()},
   284  		{in: []v1.TopologySelectorLabelRequirement{}, out: labels.Nothing()},
   285  		{
   286  			in: []v1.TopologySelectorLabelRequirement{{
   287  				Key:    "foo",
   288  				Values: []string{"bar", "baz"},
   289  			}},
   290  			out: mustParse("foo in (baz,bar)"),
   291  		},
   292  		{
   293  			in: []v1.TopologySelectorLabelRequirement{{
   294  				Key:    "foo",
   295  				Values: []string{},
   296  			}},
   297  			expectErr: true,
   298  		},
   299  		{
   300  			in: []v1.TopologySelectorLabelRequirement{
   301  				{
   302  					Key:    "foo",
   303  					Values: []string{"bar", "baz"},
   304  				},
   305  				{
   306  					Key:    "invalid",
   307  					Values: []string{},
   308  				},
   309  			},
   310  			expectErr: true,
   311  		},
   312  		{
   313  			in: []v1.TopologySelectorLabelRequirement{{
   314  				Key:    "/invalidkey",
   315  				Values: []string{"bar", "baz"},
   316  			}},
   317  			expectErr: true,
   318  		},
   319  	}
   320  
   321  	for i, tc := range tc {
   322  		out, err := TopologySelectorRequirementsAsSelector(tc.in)
   323  		if err == nil && tc.expectErr {
   324  			t.Errorf("[%v]expected error but got none.", i)
   325  		}
   326  		if err != nil && !tc.expectErr {
   327  			t.Errorf("[%v]did not expect error but got: %v", i, err)
   328  		}
   329  		if !reflect.DeepEqual(out, tc.out) {
   330  			t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
   331  		}
   332  	}
   333  }
   334  
   335  func TestMatchTopologySelectorTerms(t *testing.T) {
   336  	type args struct {
   337  		topologySelectorTerms []v1.TopologySelectorTerm
   338  		labels                labels.Set
   339  	}
   340  
   341  	tests := []struct {
   342  		name string
   343  		args args
   344  		want bool
   345  	}{
   346  		{
   347  			name: "nil term list",
   348  			args: args{
   349  				topologySelectorTerms: nil,
   350  				labels:                nil,
   351  			},
   352  			want: true,
   353  		},
   354  		{
   355  			name: "nil term",
   356  			args: args{
   357  				topologySelectorTerms: []v1.TopologySelectorTerm{
   358  					{
   359  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{},
   360  					},
   361  				},
   362  				labels: nil,
   363  			},
   364  			want: false,
   365  		},
   366  		{
   367  			name: "label matches MatchLabelExpressions terms",
   368  			args: args{
   369  				topologySelectorTerms: []v1.TopologySelectorTerm{
   370  					{
   371  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{{
   372  							Key:    "label_1",
   373  							Values: []string{"label_1_val"},
   374  						}},
   375  					},
   376  				},
   377  				labels: map[string]string{"label_1": "label_1_val"},
   378  			},
   379  			want: true,
   380  		},
   381  		{
   382  			name: "label does not match MatchLabelExpressions terms",
   383  			args: args{
   384  				topologySelectorTerms: []v1.TopologySelectorTerm{
   385  					{
   386  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{{
   387  							Key:    "label_1",
   388  							Values: []string{"label_1_val"},
   389  						}},
   390  					},
   391  				},
   392  				labels: map[string]string{"label_1": "label_1_val-failed"},
   393  			},
   394  			want: false,
   395  		},
   396  		{
   397  			name: "multi-values in one requirement, one matched",
   398  			args: args{
   399  				topologySelectorTerms: []v1.TopologySelectorTerm{
   400  					{
   401  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{{
   402  							Key:    "label_1",
   403  							Values: []string{"label_1_val1", "label_1_val2"},
   404  						}},
   405  					},
   406  				},
   407  				labels: map[string]string{"label_1": "label_1_val2"},
   408  			},
   409  			want: true,
   410  		},
   411  		{
   412  			name: "multi-terms was set, one matched",
   413  			args: args{
   414  				topologySelectorTerms: []v1.TopologySelectorTerm{
   415  					{
   416  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{{
   417  							Key:    "label_1",
   418  							Values: []string{"label_1_val"},
   419  						}},
   420  					},
   421  					{
   422  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{{
   423  							Key:    "label_2",
   424  							Values: []string{"label_2_val"},
   425  						}},
   426  					},
   427  				},
   428  				labels: map[string]string{
   429  					"label_2": "label_2_val",
   430  				},
   431  			},
   432  			want: true,
   433  		},
   434  		{
   435  			name: "multi-requirement in one term, fully matched",
   436  			args: args{
   437  				topologySelectorTerms: []v1.TopologySelectorTerm{
   438  					{
   439  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
   440  							{
   441  								Key:    "label_1",
   442  								Values: []string{"label_1_val"},
   443  							},
   444  							{
   445  								Key:    "label_2",
   446  								Values: []string{"label_2_val"},
   447  							},
   448  						},
   449  					},
   450  				},
   451  				labels: map[string]string{
   452  					"label_1": "label_1_val",
   453  					"label_2": "label_2_val",
   454  				},
   455  			},
   456  			want: true,
   457  		},
   458  		{
   459  			name: "multi-requirement in one term, partial matched",
   460  			args: args{
   461  				topologySelectorTerms: []v1.TopologySelectorTerm{
   462  					{
   463  						MatchLabelExpressions: []v1.TopologySelectorLabelRequirement{
   464  							{
   465  								Key:    "label_1",
   466  								Values: []string{"label_1_val"},
   467  							},
   468  							{
   469  								Key:    "label_2",
   470  								Values: []string{"label_2_val"},
   471  							},
   472  						},
   473  					},
   474  				},
   475  				labels: map[string]string{
   476  					"label_1": "label_1_val-failed",
   477  					"label_2": "label_2_val",
   478  				},
   479  			},
   480  			want: false,
   481  		},
   482  	}
   483  
   484  	for _, tt := range tests {
   485  		t.Run(tt.name, func(t *testing.T) {
   486  			if got := MatchTopologySelectorTerms(tt.args.topologySelectorTerms, tt.args.labels); got != tt.want {
   487  				t.Errorf("MatchTopologySelectorTermsORed() = %v, want %v", got, tt.want)
   488  			}
   489  		})
   490  	}
   491  }
   492  
   493  func TestNodeSelectorRequirementKeyExistsInNodeSelectorTerms(t *testing.T) {
   494  	tests := []struct {
   495  		name   string
   496  		reqs   []v1.NodeSelectorRequirement
   497  		terms  []v1.NodeSelectorTerm
   498  		exists bool
   499  	}{
   500  		{
   501  			name:   "empty set of keys in empty set of terms",
   502  			reqs:   []v1.NodeSelectorRequirement{},
   503  			terms:  []v1.NodeSelectorTerm{},
   504  			exists: false,
   505  		},
   506  		{
   507  			name: "key existence in terms with all keys specified",
   508  			reqs: []v1.NodeSelectorRequirement{
   509  				{
   510  					Key:      "key1",
   511  					Operator: v1.NodeSelectorOpIn,
   512  					Values:   []string{"test-value1"},
   513  				},
   514  				{
   515  					Key:      "key2",
   516  					Operator: v1.NodeSelectorOpIn,
   517  					Values:   []string{"test-value2"},
   518  				},
   519  			},
   520  			terms: []v1.NodeSelectorTerm{
   521  				{
   522  					MatchExpressions: []v1.NodeSelectorRequirement{
   523  						{
   524  							Key:      "key2",
   525  							Operator: v1.NodeSelectorOpIn,
   526  							Values:   []string{"test-value2"},
   527  						},
   528  						{
   529  							Key:      "key3",
   530  							Operator: v1.NodeSelectorOpIn,
   531  							Values:   []string{"test-value3"},
   532  						},
   533  					},
   534  				},
   535  				{
   536  					MatchExpressions: []v1.NodeSelectorRequirement{
   537  						{
   538  							Key:      "key1",
   539  							Operator: v1.NodeSelectorOpIn,
   540  							Values:   []string{"test-value11, test-value12"},
   541  						},
   542  						{
   543  							Key:      "key4",
   544  							Operator: v1.NodeSelectorOpIn,
   545  							Values:   []string{"test-value41, test-value42"},
   546  						},
   547  					},
   548  				},
   549  			},
   550  			exists: true,
   551  		},
   552  		{
   553  			name: "key existence in terms with one of the keys specified",
   554  			reqs: []v1.NodeSelectorRequirement{
   555  				{
   556  					Key:      "key1",
   557  					Operator: v1.NodeSelectorOpIn,
   558  					Values:   []string{"test-value1"},
   559  				},
   560  				{
   561  					Key:      "key2",
   562  					Operator: v1.NodeSelectorOpIn,
   563  					Values:   []string{"test-value2"},
   564  				},
   565  				{
   566  					Key:      "key3",
   567  					Operator: v1.NodeSelectorOpIn,
   568  					Values:   []string{"test-value3"},
   569  				},
   570  				{
   571  					Key:      "key6",
   572  					Operator: v1.NodeSelectorOpIn,
   573  					Values:   []string{"test-value6"},
   574  				},
   575  			},
   576  			terms: []v1.NodeSelectorTerm{
   577  				{
   578  					MatchExpressions: []v1.NodeSelectorRequirement{
   579  						{
   580  							Key:      "key2",
   581  							Operator: v1.NodeSelectorOpIn,
   582  							Values:   []string{"test-value2"},
   583  						}, {
   584  							Key:      "key4",
   585  							Operator: v1.NodeSelectorOpIn,
   586  							Values:   []string{"test-value4"},
   587  						},
   588  					},
   589  				},
   590  				{
   591  					MatchExpressions: []v1.NodeSelectorRequirement{
   592  						{
   593  							Key:      "key5",
   594  							Operator: v1.NodeSelectorOpIn,
   595  							Values:   []string{"test-value5"},
   596  						},
   597  					},
   598  				},
   599  			},
   600  			exists: true,
   601  		},
   602  		{
   603  			name: "key existence in terms without any of the keys specified",
   604  			reqs: []v1.NodeSelectorRequirement{
   605  				{
   606  					Key:      "key2",
   607  					Operator: v1.NodeSelectorOpIn,
   608  					Values:   []string{"test-value2"},
   609  				},
   610  				{
   611  					Key:      "key3",
   612  					Operator: v1.NodeSelectorOpIn,
   613  					Values:   []string{"test-value3"},
   614  				},
   615  			},
   616  			terms: []v1.NodeSelectorTerm{
   617  				{
   618  					MatchExpressions: []v1.NodeSelectorRequirement{
   619  						{
   620  							Key:      "key4",
   621  							Operator: v1.NodeSelectorOpIn,
   622  							Values:   []string{"test-value"},
   623  						},
   624  						{
   625  							Key:      "key5",
   626  							Operator: v1.NodeSelectorOpIn,
   627  							Values:   []string{"test-value"},
   628  						},
   629  					},
   630  				},
   631  				{
   632  					MatchExpressions: []v1.NodeSelectorRequirement{
   633  						{
   634  							Key:      "key6",
   635  							Operator: v1.NodeSelectorOpIn,
   636  							Values:   []string{"test-value"},
   637  						},
   638  					},
   639  				},
   640  				{
   641  					MatchExpressions: []v1.NodeSelectorRequirement{
   642  						{
   643  							Key:      "key7",
   644  							Operator: v1.NodeSelectorOpIn,
   645  							Values:   []string{"test-value"},
   646  						},
   647  						{
   648  							Key:      "key8",
   649  							Operator: v1.NodeSelectorOpIn,
   650  							Values:   []string{"test-value"},
   651  						},
   652  					},
   653  				},
   654  			},
   655  			exists: false,
   656  		},
   657  		{
   658  			name: "key existence in empty set of terms",
   659  			reqs: []v1.NodeSelectorRequirement{
   660  				{
   661  					Key:      "key2",
   662  					Operator: v1.NodeSelectorOpIn,
   663  					Values:   []string{"test-value2"},
   664  				},
   665  				{
   666  					Key:      "key3",
   667  					Operator: v1.NodeSelectorOpIn,
   668  					Values:   []string{"test-value3"},
   669  				},
   670  			},
   671  			terms:  []v1.NodeSelectorTerm{},
   672  			exists: false,
   673  		},
   674  	}
   675  	for _, test := range tests {
   676  		keyExists := NodeSelectorRequirementKeysExistInNodeSelectorTerms(test.reqs, test.terms)
   677  		if test.exists != keyExists {
   678  			t.Errorf("test %s failed. Expected %v but got %v", test.name, test.exists, keyExists)
   679  		}
   680  	}
   681  }
   682  
   683  func TestHugePageUnitSizeFromByteSize(t *testing.T) {
   684  	tests := []struct {
   685  		size     int64
   686  		expected string
   687  		wantErr  bool
   688  	}{
   689  		{
   690  			size:     1024,
   691  			expected: "1KB",
   692  			wantErr:  false,
   693  		},
   694  		{
   695  			size:     33554432,
   696  			expected: "32MB",
   697  			wantErr:  false,
   698  		},
   699  		{
   700  			size:     3221225472,
   701  			expected: "3GB",
   702  			wantErr:  false,
   703  		},
   704  		{
   705  			size:     1024 * 1024 * 1023 * 3,
   706  			expected: "3069MB",
   707  			wantErr:  true,
   708  		},
   709  	}
   710  	for _, test := range tests {
   711  		size := test.size
   712  		result, err := HugePageUnitSizeFromByteSize(size)
   713  		if err != nil {
   714  			if test.wantErr {
   715  				t.Logf("HugePageUnitSizeFromByteSize() expected error = %v", err)
   716  			} else {
   717  				t.Errorf("HugePageUnitSizeFromByteSize() error = %v, wantErr %v", err, test.wantErr)
   718  			}
   719  			continue
   720  		}
   721  		if test.expected != result {
   722  			t.Errorf("HugePageUnitSizeFromByteSize() expected %v but got %v", test.expected, result)
   723  		}
   724  	}
   725  }
   726  
   727  func TestLoadBalancerStatusEqual(t *testing.T) {
   728  
   729  	testCases := []struct {
   730  		left      *v1.LoadBalancerStatus
   731  		right     *v1.LoadBalancerStatus
   732  		name      string
   733  		expectVal bool
   734  	}{{
   735  		name: "left equals right",
   736  		left: &v1.LoadBalancerStatus{
   737  			Ingress: []v1.LoadBalancerIngress{{
   738  				IP:       "1.1.1.1",
   739  				Hostname: "host1",
   740  			}},
   741  		},
   742  		right: &v1.LoadBalancerStatus{
   743  			Ingress: []v1.LoadBalancerIngress{{
   744  				IP:       "1.1.1.1",
   745  				Hostname: "host1",
   746  			}},
   747  		},
   748  		expectVal: true,
   749  	}, {
   750  		name: "length of LoadBalancerIngress slice is not equal",
   751  		left: &v1.LoadBalancerStatus{
   752  			Ingress: []v1.LoadBalancerIngress{{
   753  				IP:       "1.1.1.1",
   754  				Hostname: "host1",
   755  			}, {
   756  				IP:       "1.1.1.2",
   757  				Hostname: "host1",
   758  			}},
   759  		},
   760  		right: &v1.LoadBalancerStatus{
   761  			Ingress: []v1.LoadBalancerIngress{{
   762  				IP:       "1.1.1.1",
   763  				Hostname: "host1",
   764  			}},
   765  		},
   766  		expectVal: false,
   767  	}, {
   768  		name: "LoadBalancerIngress ip is not equal",
   769  		left: &v1.LoadBalancerStatus{
   770  			Ingress: []v1.LoadBalancerIngress{{
   771  				IP:       "1.1.1.2",
   772  				Hostname: "host1",
   773  			}},
   774  		},
   775  		right: &v1.LoadBalancerStatus{
   776  			Ingress: []v1.LoadBalancerIngress{{
   777  				IP:       "1.1.1.1",
   778  				Hostname: "host1",
   779  			}},
   780  		},
   781  		expectVal: false,
   782  	}, {
   783  		name: "LoadBalancerIngress hostname is not equal",
   784  		left: &v1.LoadBalancerStatus{
   785  			Ingress: []v1.LoadBalancerIngress{{
   786  				IP:       "1.1.1.1",
   787  				Hostname: "host2",
   788  			}},
   789  		},
   790  		right: &v1.LoadBalancerStatus{
   791  			Ingress: []v1.LoadBalancerIngress{{
   792  				IP:       "1.1.1.1",
   793  				Hostname: "host1",
   794  			}},
   795  		},
   796  		expectVal: false,
   797  	}}
   798  
   799  	for _, tc := range testCases {
   800  		t.Run(tc.name, func(t *testing.T) {
   801  			v := LoadBalancerStatusEqual(tc.left, tc.right)
   802  			if v != tc.expectVal {
   803  				t.Errorf("test %s failed. left input=%v, right input=%v, Got %v but expected %v",
   804  					tc.name, tc.left, tc.right, v, tc.expectVal)
   805  			}
   806  		})
   807  	}
   808  }
   809  

View as plain text