...

Source file src/k8s.io/kubernetes/pkg/kubelet/kuberuntime/kuberuntime_container_windows_test.go

Documentation: k8s.io/kubernetes/pkg/kubelet/kuberuntime

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2022 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package kuberuntime
    21  
    22  import (
    23  	"testing"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  	"github.com/stretchr/testify/require"
    27  
    28  	v1 "k8s.io/api/core/v1"
    29  	"k8s.io/apimachinery/pkg/api/resource"
    30  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    31  	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
    32  	"k8s.io/kubernetes/pkg/kubelet/winstats"
    33  )
    34  
    35  func TestApplyPlatformSpecificContainerConfig(t *testing.T) {
    36  	_, _, fakeRuntimeSvc, err := createTestRuntimeManager()
    37  	require.NoError(t, err)
    38  
    39  	containerConfig := &runtimeapi.ContainerConfig{}
    40  
    41  	resources := v1.ResourceRequirements{
    42  		Requests: v1.ResourceList{
    43  			v1.ResourceMemory: resource.MustParse("128Mi"),
    44  			v1.ResourceCPU:    resource.MustParse("1"),
    45  		},
    46  		Limits: v1.ResourceList{
    47  			v1.ResourceMemory: resource.MustParse("256Mi"),
    48  			v1.ResourceCPU:    resource.MustParse("3"),
    49  		},
    50  	}
    51  
    52  	gmsaCredSpecName := "gmsa spec name"
    53  	gmsaCredSpec := "credential spec"
    54  	username := "ContainerAdministrator"
    55  	asHostProcess := true
    56  	pod := &v1.Pod{
    57  		ObjectMeta: metav1.ObjectMeta{
    58  			UID:       "12345678",
    59  			Name:      "bar",
    60  			Namespace: "new",
    61  		},
    62  		Spec: v1.PodSpec{
    63  			Containers: []v1.Container{
    64  				{
    65  					Name:            "foo",
    66  					Image:           "busybox",
    67  					ImagePullPolicy: v1.PullIfNotPresent,
    68  					Command:         []string{"testCommand"},
    69  					WorkingDir:      "testWorkingDir",
    70  					Resources:       resources,
    71  					SecurityContext: &v1.SecurityContext{
    72  						WindowsOptions: &v1.WindowsSecurityContextOptions{
    73  							GMSACredentialSpecName: &gmsaCredSpecName,
    74  							GMSACredentialSpec:     &gmsaCredSpec,
    75  							RunAsUserName:          &username,
    76  							HostProcess:            &asHostProcess,
    77  						},
    78  					},
    79  				},
    80  			},
    81  		},
    82  	}
    83  
    84  	err = fakeRuntimeSvc.applyPlatformSpecificContainerConfig(containerConfig, &pod.Spec.Containers[0], pod, new(int64), "foo", nil)
    85  	require.NoError(t, err)
    86  
    87  	limit := int64(3000)
    88  	expectedCpuMax := 10 * limit / int64(winstats.ProcessorCount())
    89  	// Above, we're setting the limit to 3 CPUs. But we can't expect more than 100% of the CPUs
    90  	// we have. (e.g.: if we only have 2 CPUs, we can't have 150% CPU max).
    91  	if expectedCpuMax > 10000 {
    92  		expectedCpuMax = 10000
    93  	}
    94  	expectedWindowsConfig := &runtimeapi.WindowsContainerConfig{
    95  		Resources: &runtimeapi.WindowsContainerResources{
    96  			CpuMaximum:         expectedCpuMax,
    97  			MemoryLimitInBytes: 256 * 1024 * 1024,
    98  		},
    99  		SecurityContext: &runtimeapi.WindowsContainerSecurityContext{
   100  			CredentialSpec: gmsaCredSpec,
   101  			RunAsUsername:  "ContainerAdministrator",
   102  			HostProcess:    true,
   103  		},
   104  	}
   105  	assert.Equal(t, expectedWindowsConfig, containerConfig.Windows)
   106  }
   107  
   108  func TestCalculateCPUMaximum(t *testing.T) {
   109  	tests := []struct {
   110  		name     string
   111  		cpuLimit resource.Quantity
   112  		cpuCount int64
   113  		want     int64
   114  	}{
   115  		{
   116  			name:     "max range when same amount",
   117  			cpuLimit: resource.MustParse("1"),
   118  			cpuCount: 1,
   119  			want:     10000,
   120  		},
   121  		{
   122  			name:     "percentage calculation is working as intended",
   123  			cpuLimit: resource.MustParse("94"),
   124  			cpuCount: 96,
   125  			want:     9791,
   126  		},
   127  		{
   128  			name:     "half range when half amount",
   129  			cpuLimit: resource.MustParse("1"),
   130  			cpuCount: 2,
   131  			want:     5000,
   132  		},
   133  		{
   134  			name:     "max range when more requested than available",
   135  			cpuLimit: resource.MustParse("2"),
   136  			cpuCount: 1,
   137  			want:     10000,
   138  		},
   139  		{
   140  			name:     "min range when less than minimum",
   141  			cpuLimit: resource.MustParse("1m"),
   142  			cpuCount: 100,
   143  			want:     1,
   144  		},
   145  	}
   146  	for _, tt := range tests {
   147  		t.Run(tt.name, func(t *testing.T) {
   148  			assert.Equal(t, tt.want, calculateCPUMaximum(&tt.cpuLimit, tt.cpuCount))
   149  		})
   150  	}
   151  }
   152  
   153  func TestCalculateWindowsResources(t *testing.T) {
   154  	_, _, fakeRuntimeSvc, err := createTestRuntimeManager()
   155  	require.NoError(t, err)
   156  
   157  	tests := []struct {
   158  		name     string
   159  		cpuLim   resource.Quantity
   160  		memLim   resource.Quantity
   161  		expected *runtimeapi.WindowsContainerResources
   162  	}{
   163  		{
   164  			name:   "Request128MBLimit256MB",
   165  			cpuLim: resource.MustParse("2"),
   166  			memLim: resource.MustParse("128Mi"),
   167  			expected: &runtimeapi.WindowsContainerResources{
   168  				CpuMaximum:         2500,
   169  				MemoryLimitInBytes: 134217728,
   170  			},
   171  		},
   172  		{
   173  			name:   "RequestNoMemory",
   174  			cpuLim: resource.MustParse("8"),
   175  			memLim: resource.MustParse("0"),
   176  			expected: &runtimeapi.WindowsContainerResources{
   177  				CpuMaximum:         10000,
   178  				MemoryLimitInBytes: 0,
   179  			},
   180  		},
   181  		{
   182  			name:   "RequestZeroCPU",
   183  			cpuLim: resource.MustParse("0"),
   184  			memLim: resource.MustParse("128Mi"),
   185  			expected: &runtimeapi.WindowsContainerResources{
   186  				CpuMaximum:         1,
   187  				MemoryLimitInBytes: 134217728,
   188  			},
   189  		},
   190  	}
   191  	for _, test := range tests {
   192  		windowsContainerResources := fakeRuntimeSvc.calculateWindowsResources(&test.cpuLim, &test.memLim)
   193  		assert.Equal(t, test.expected, windowsContainerResources)
   194  	}
   195  }
   196  

View as plain text