...

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

Documentation: k8s.io/kubernetes/pkg/apis/core/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  	"testing"
    21  
    22  	"k8s.io/apimachinery/pkg/api/resource"
    23  	"k8s.io/kubernetes/pkg/apis/core"
    24  )
    25  
    26  func TestSemantic(t *testing.T) {
    27  	table := []struct {
    28  		a, b        interface{}
    29  		shouldEqual bool
    30  	}{
    31  		{resource.MustParse("0"), resource.Quantity{}, true},
    32  		{resource.Quantity{}, resource.MustParse("0"), true},
    33  		{resource.Quantity{}, resource.MustParse("1m"), false},
    34  		{
    35  			resource.NewQuantity(5, resource.BinarySI),
    36  			resource.NewQuantity(5, resource.DecimalSI),
    37  			true,
    38  		},
    39  		{resource.MustParse("2m"), resource.MustParse("1m"), false},
    40  	}
    41  
    42  	for index, item := range table {
    43  		if e, a := item.shouldEqual, Semantic.DeepEqual(item.a, item.b); e != a {
    44  			t.Errorf("case[%d], expected %v, got %v.", index, e, a)
    45  		}
    46  	}
    47  }
    48  
    49  func TestIsStandardResource(t *testing.T) {
    50  	testCases := []struct {
    51  		input  string
    52  		output bool
    53  	}{
    54  		{"cpu", true},
    55  		{"memory", true},
    56  		{"disk", false},
    57  		{"blah", false},
    58  		{"x.y.z", false},
    59  		{"hugepages-2Mi", true},
    60  		{"requests.hugepages-2Mi", true},
    61  	}
    62  	for i, tc := range testCases {
    63  		if IsStandardResourceName(core.ResourceName(tc.input)) != tc.output {
    64  			t.Errorf("case[%d], input: %s, expected: %t, got: %t", i, tc.input, tc.output, !tc.output)
    65  		}
    66  	}
    67  }
    68  
    69  func TestIsStandardContainerResource(t *testing.T) {
    70  	testCases := []struct {
    71  		input  string
    72  		output bool
    73  	}{
    74  		{"cpu", true},
    75  		{"memory", true},
    76  		{"disk", false},
    77  		{"hugepages-2Mi", true},
    78  	}
    79  	for i, tc := range testCases {
    80  		if IsStandardContainerResourceName(core.ResourceName(tc.input)) != tc.output {
    81  			t.Errorf("case[%d], input: %s, expected: %t, got: %t", i, tc.input, tc.output, !tc.output)
    82  		}
    83  	}
    84  }
    85  
    86  func TestGetAccessModesFromString(t *testing.T) {
    87  	modes := GetAccessModesFromString("ROX")
    88  	if !ContainsAccessMode(modes, core.ReadOnlyMany) {
    89  		t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
    90  	}
    91  
    92  	modes = GetAccessModesFromString("ROX,RWX")
    93  	if !ContainsAccessMode(modes, core.ReadOnlyMany) {
    94  		t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
    95  	}
    96  	if !ContainsAccessMode(modes, core.ReadWriteMany) {
    97  		t.Errorf("Expected mode %s, but got %+v", core.ReadWriteMany, modes)
    98  	}
    99  
   100  	modes = GetAccessModesFromString("RWO,ROX,RWX")
   101  	if !ContainsAccessMode(modes, core.ReadWriteOnce) {
   102  		t.Errorf("Expected mode %s, but got %+v", core.ReadWriteOnce, modes)
   103  	}
   104  	if !ContainsAccessMode(modes, core.ReadOnlyMany) {
   105  		t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
   106  	}
   107  	if !ContainsAccessMode(modes, core.ReadWriteMany) {
   108  		t.Errorf("Expected mode %s, but got %+v", core.ReadWriteMany, modes)
   109  	}
   110  
   111  	modes = GetAccessModesFromString("RWO,ROX,RWX,RWOP")
   112  	if !ContainsAccessMode(modes, core.ReadWriteOnce) {
   113  		t.Errorf("Expected mode %s, but got %+v", core.ReadWriteOnce, modes)
   114  	}
   115  	if !ContainsAccessMode(modes, core.ReadOnlyMany) {
   116  		t.Errorf("Expected mode %s, but got %+v", core.ReadOnlyMany, modes)
   117  	}
   118  	if !ContainsAccessMode(modes, core.ReadWriteMany) {
   119  		t.Errorf("Expected mode %s, but got %+v", core.ReadWriteMany, modes)
   120  	}
   121  	if !ContainsAccessMode(modes, core.ReadWriteOncePod) {
   122  		t.Errorf("Expected mode %s, but got %+v", core.ReadWriteOncePod, modes)
   123  	}
   124  }
   125  
   126  func TestRemoveDuplicateAccessModes(t *testing.T) {
   127  	modes := []core.PersistentVolumeAccessMode{
   128  		core.ReadWriteOnce, core.ReadOnlyMany, core.ReadOnlyMany, core.ReadOnlyMany,
   129  	}
   130  	modes = removeDuplicateAccessModes(modes)
   131  	if len(modes) != 2 {
   132  		t.Errorf("Expected 2 distinct modes in set but found %v", len(modes))
   133  	}
   134  }
   135  
   136  func TestIsHugePageResourceName(t *testing.T) {
   137  	testCases := []struct {
   138  		name   core.ResourceName
   139  		result bool
   140  	}{
   141  		{
   142  			name:   core.ResourceName("hugepages-2Mi"),
   143  			result: true,
   144  		},
   145  		{
   146  			name:   core.ResourceName("hugepages-1Gi"),
   147  			result: true,
   148  		},
   149  		{
   150  			name:   core.ResourceName("cpu"),
   151  			result: false,
   152  		},
   153  		{
   154  			name:   core.ResourceName("memory"),
   155  			result: false,
   156  		},
   157  	}
   158  	for _, testCase := range testCases {
   159  		if testCase.result != IsHugePageResourceName(testCase.name) {
   160  			t.Errorf("resource: %v expected result: %v", testCase.name, testCase.result)
   161  		}
   162  	}
   163  }
   164  
   165  func TestIsHugePageResourceValueDivisible(t *testing.T) {
   166  	testCases := []struct {
   167  		name     core.ResourceName
   168  		quantity resource.Quantity
   169  		result   bool
   170  	}{
   171  		{
   172  			name:     core.ResourceName("hugepages-2Mi"),
   173  			quantity: resource.MustParse("4Mi"),
   174  			result:   true,
   175  		},
   176  		{
   177  			name:     core.ResourceName("hugepages-2Mi"),
   178  			quantity: resource.MustParse("5Mi"),
   179  			result:   false,
   180  		},
   181  		{
   182  			name:     core.ResourceName("hugepages-1Gi"),
   183  			quantity: resource.MustParse("2Gi"),
   184  			result:   true,
   185  		},
   186  		{
   187  			name:     core.ResourceName("hugepages-1Gi"),
   188  			quantity: resource.MustParse("2.1Gi"),
   189  			result:   false,
   190  		},
   191  		{
   192  			name:     core.ResourceName("hugepages-1Mi"),
   193  			quantity: resource.MustParse("2.1Mi"),
   194  			result:   false,
   195  		},
   196  		{
   197  			name:     core.ResourceName("hugepages-64Ki"),
   198  			quantity: resource.MustParse("128Ki"),
   199  			result:   true,
   200  		},
   201  		{
   202  			name:     core.ResourceName("hugepages-"),
   203  			quantity: resource.MustParse("128Ki"),
   204  			result:   false,
   205  		},
   206  		{
   207  			name:     core.ResourceName("hugepages"),
   208  			quantity: resource.MustParse("128Ki"),
   209  			result:   false,
   210  		},
   211  	}
   212  	for _, testCase := range testCases {
   213  		if testCase.result != IsHugePageResourceValueDivisible(testCase.name, testCase.quantity) {
   214  			t.Errorf("resource: %v storage:%v expected result: %v", testCase.name, testCase.quantity, testCase.result)
   215  		}
   216  	}
   217  }
   218  
   219  func TestHugePageResourceName(t *testing.T) {
   220  	testCases := []struct {
   221  		pageSize resource.Quantity
   222  		name     core.ResourceName
   223  	}{
   224  		{
   225  			pageSize: resource.MustParse("2Mi"),
   226  			name:     core.ResourceName("hugepages-2Mi"),
   227  		},
   228  		{
   229  			pageSize: resource.MustParse("1Gi"),
   230  			name:     core.ResourceName("hugepages-1Gi"),
   231  		},
   232  		{
   233  			// verify we do not regress our canonical representation
   234  			pageSize: *resource.NewQuantity(int64(2097152), resource.BinarySI),
   235  			name:     core.ResourceName("hugepages-2Mi"),
   236  		},
   237  	}
   238  	for _, testCase := range testCases {
   239  		if result := HugePageResourceName(testCase.pageSize); result != testCase.name {
   240  			t.Errorf("pageSize: %v, expected: %v, but got: %v", testCase.pageSize.String(), testCase.name, result.String())
   241  		}
   242  	}
   243  }
   244  
   245  func TestHugePageSizeFromResourceName(t *testing.T) {
   246  	testCases := []struct {
   247  		name      core.ResourceName
   248  		expectErr bool
   249  		pageSize  resource.Quantity
   250  	}{
   251  		{
   252  			name:      core.ResourceName("hugepages-2Mi"),
   253  			pageSize:  resource.MustParse("2Mi"),
   254  			expectErr: false,
   255  		},
   256  		{
   257  			name:      core.ResourceName("hugepages-1Gi"),
   258  			pageSize:  resource.MustParse("1Gi"),
   259  			expectErr: false,
   260  		},
   261  		{
   262  			name:      core.ResourceName("hugepages-bad"),
   263  			expectErr: true,
   264  		},
   265  	}
   266  	for _, testCase := range testCases {
   267  		value, err := HugePageSizeFromResourceName(testCase.name)
   268  		if testCase.expectErr && err == nil {
   269  			t.Errorf("Expected an error for %v", testCase.name)
   270  		} else if !testCase.expectErr && err != nil {
   271  			t.Errorf("Unexpected error for %v, got %v", testCase.name, err)
   272  		} else if testCase.pageSize.Value() != value.Value() {
   273  			t.Errorf("Unexpected pageSize for resource %v got %v", testCase.name, value.String())
   274  		}
   275  	}
   276  }
   277  
   278  func TestIsOvercommitAllowed(t *testing.T) {
   279  	testCases := []struct {
   280  		name    core.ResourceName
   281  		allowed bool
   282  	}{
   283  		{
   284  			name:    core.ResourceCPU,
   285  			allowed: true,
   286  		},
   287  		{
   288  			name:    core.ResourceMemory,
   289  			allowed: true,
   290  		},
   291  		{
   292  			name:    HugePageResourceName(resource.MustParse("2Mi")),
   293  			allowed: false,
   294  		},
   295  	}
   296  	for _, testCase := range testCases {
   297  		if testCase.allowed != IsOvercommitAllowed(testCase.name) {
   298  			t.Errorf("Unexpected result for %v", testCase.name)
   299  		}
   300  	}
   301  }
   302  
   303  func TestIsServiceIPSet(t *testing.T) {
   304  	testCases := []struct {
   305  		input  core.ServiceSpec
   306  		output bool
   307  		name   string
   308  	}{
   309  		{
   310  			name: "nil cluster ip",
   311  			input: core.ServiceSpec{
   312  				ClusterIPs: nil,
   313  			},
   314  
   315  			output: false,
   316  		},
   317  		{
   318  			name: "headless service",
   319  			input: core.ServiceSpec{
   320  				ClusterIP:  "None",
   321  				ClusterIPs: []string{"None"},
   322  			},
   323  			output: false,
   324  		},
   325  		// true cases
   326  		{
   327  			name: "one ipv4",
   328  			input: core.ServiceSpec{
   329  				ClusterIP:  "1.2.3.4",
   330  				ClusterIPs: []string{"1.2.3.4"},
   331  			},
   332  			output: true,
   333  		},
   334  		{
   335  			name: "one ipv6",
   336  			input: core.ServiceSpec{
   337  				ClusterIP:  "2001::1",
   338  				ClusterIPs: []string{"2001::1"},
   339  			},
   340  			output: true,
   341  		},
   342  		{
   343  			name: "v4, v6",
   344  			input: core.ServiceSpec{
   345  				ClusterIP:  "1.2.3.4",
   346  				ClusterIPs: []string{"1.2.3.4", "2001::1"},
   347  			},
   348  			output: true,
   349  		},
   350  		{
   351  			name: "v6, v4",
   352  			input: core.ServiceSpec{
   353  				ClusterIP:  "2001::1",
   354  				ClusterIPs: []string{"2001::1", "1.2.3.4"},
   355  			},
   356  
   357  			output: true,
   358  		},
   359  	}
   360  
   361  	for _, tc := range testCases {
   362  		t.Run(tc.name, func(t *testing.T) {
   363  			s := core.Service{
   364  				Spec: tc.input,
   365  			}
   366  			if IsServiceIPSet(&s) != tc.output {
   367  				t.Errorf("case, input: %v, expected: %v, got: %v", tc.input, tc.output, !tc.output)
   368  			}
   369  		})
   370  	}
   371  }
   372  

View as plain text