mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Merge pull request #111020 from claudiubelu/adds-unittests-5
unittests: Adds Windows unittests
This commit is contained in:
		
							
								
								
									
										111
									
								
								pkg/kubelet/kuberuntime/kuberuntime_container_windows_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								pkg/kubelet/kuberuntime/kuberuntime_container_windows_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| //go:build windows | ||||
| // +build windows | ||||
|  | ||||
| /* | ||||
| Copyright 2022 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package kuberuntime | ||||
|  | ||||
| import ( | ||||
| 	"runtime" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
|  | ||||
| 	v1 "k8s.io/api/core/v1" | ||||
| 	"k8s.io/apimachinery/pkg/api/resource" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" | ||||
| 	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" | ||||
| 	"k8s.io/kubernetes/pkg/features" | ||||
| ) | ||||
|  | ||||
| func TestApplyPlatformSpecificContainerConfig(t *testing.T) { | ||||
| 	_, _, fakeRuntimeSvc, err := createTestRuntimeManager() | ||||
| 	require.NoError(t, err) | ||||
|  | ||||
| 	containerConfig := &runtimeapi.ContainerConfig{} | ||||
|  | ||||
| 	resources := v1.ResourceRequirements{ | ||||
| 		Requests: v1.ResourceList{ | ||||
| 			v1.ResourceMemory: resource.MustParse("128Mi"), | ||||
| 			v1.ResourceCPU:    resource.MustParse("1"), | ||||
| 		}, | ||||
| 		Limits: v1.ResourceList{ | ||||
| 			v1.ResourceMemory: resource.MustParse("256Mi"), | ||||
| 			v1.ResourceCPU:    resource.MustParse("3"), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	gmsaCredSpecName := "gmsa spec name" | ||||
| 	gmsaCredSpec := "credential spec" | ||||
| 	username := "ContainerAdministrator" | ||||
| 	asHostProcess := true | ||||
| 	pod := &v1.Pod{ | ||||
| 		ObjectMeta: metav1.ObjectMeta{ | ||||
| 			UID:       "12345678", | ||||
| 			Name:      "bar", | ||||
| 			Namespace: "new", | ||||
| 		}, | ||||
| 		Spec: v1.PodSpec{ | ||||
| 			Containers: []v1.Container{ | ||||
| 				{ | ||||
| 					Name:            "foo", | ||||
| 					Image:           "busybox", | ||||
| 					ImagePullPolicy: v1.PullIfNotPresent, | ||||
| 					Command:         []string{"testCommand"}, | ||||
| 					WorkingDir:      "testWorkingDir", | ||||
| 					Resources:       resources, | ||||
| 					SecurityContext: &v1.SecurityContext{ | ||||
| 						WindowsOptions: &v1.WindowsSecurityContextOptions{ | ||||
| 							GMSACredentialSpecName: &gmsaCredSpecName, | ||||
| 							GMSACredentialSpec:     &gmsaCredSpec, | ||||
| 							RunAsUserName:          &username, | ||||
| 							HostProcess:            &asHostProcess, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	err = fakeRuntimeSvc.applyPlatformSpecificContainerConfig(containerConfig, &pod.Spec.Containers[0], pod, new(int64), "foo", nil) | ||||
| 	require.NoError(t, err) | ||||
|  | ||||
| 	expectedCpuMax := ((10000 * 3000) / int64(runtime.NumCPU()) / 1000) | ||||
| 	expectedWindowsConfig := &runtimeapi.WindowsContainerConfig{ | ||||
| 		Resources: &runtimeapi.WindowsContainerResources{ | ||||
| 			CpuMaximum:         expectedCpuMax, | ||||
| 			MemoryLimitInBytes: 256 * 1024 * 1024, | ||||
| 		}, | ||||
| 		SecurityContext: &runtimeapi.WindowsContainerSecurityContext{ | ||||
| 			CredentialSpec: gmsaCredSpec, | ||||
| 			RunAsUsername:  "ContainerAdministrator", | ||||
| 			HostProcess:    true, | ||||
| 		}, | ||||
| 	} | ||||
| 	assert.Equal(t, expectedWindowsConfig, containerConfig.Windows) | ||||
|  | ||||
| 	// Check if it fails if we require HostProcess but the feature is not enabled. | ||||
| 	defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.WindowsHostProcessContainers, false)() | ||||
| 	err = fakeRuntimeSvc.applyPlatformSpecificContainerConfig(containerConfig, &pod.Spec.Containers[0], pod, new(int64), "foo", nil) | ||||
| 	expectedErrMsg := "pod contains HostProcess containers but feature 'WindowsHostProcessContainers' is not enabled" | ||||
| 	if err == nil || err.Error() != expectedErrMsg { | ||||
| 		t.Errorf("expected error message `%s` but got `%v`", expectedErrMsg, err) | ||||
| 	} | ||||
| } | ||||
| @@ -51,6 +51,7 @@ func TestVerifyRunAsNonRoot(t *testing.T) { | ||||
| 	anyUser := "anyone" | ||||
| 	runAsNonRootTrue := true | ||||
| 	runAsNonRootFalse := false | ||||
| 	uid := int64(0) | ||||
| 	for _, test := range []struct { | ||||
| 		desc     string | ||||
| 		sc       *v1.SecurityContext | ||||
| @@ -140,7 +141,11 @@ func TestVerifyRunAsNonRoot(t *testing.T) { | ||||
| 		{ | ||||
| 			desc: "Pass if container's user and image's user aren't set and RunAsNonRoot is true", | ||||
| 			sc: &v1.SecurityContext{ | ||||
| 				RunAsNonRoot: &runAsNonRootTrue, | ||||
| 				// verifyRunAsNonRoot should ignore the RunAsUser, SELinuxOptions, and RunAsGroup options. | ||||
| 				RunAsUser:      &uid, | ||||
| 				SELinuxOptions: &v1.SELinuxOptions{}, | ||||
| 				RunAsGroup:     &uid, | ||||
| 				RunAsNonRoot:   &runAsNonRootTrue, | ||||
| 			}, | ||||
| 			fail: false, | ||||
| 		}, | ||||
|   | ||||
							
								
								
									
										96
									
								
								pkg/volume/awsebs/attacher_windows_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								pkg/volume/awsebs/attacher_windows_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| //go:build !providerless && windows | ||||
| // +build !providerless,windows | ||||
|  | ||||
| /* | ||||
| Copyright 2022 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package awsebs | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
|  | ||||
| 	volumetest "k8s.io/kubernetes/pkg/volume/testing" | ||||
| 	"k8s.io/utils/exec" | ||||
| 	exectest "k8s.io/utils/exec/testing" | ||||
| ) | ||||
|  | ||||
| func TestGetDevicePath(t *testing.T) { | ||||
| 	testCases := []struct { | ||||
| 		commandOutput  string | ||||
| 		commandError   error | ||||
| 		expectedOutput string | ||||
| 		expectedError  bool | ||||
| 		expectedErrMsg string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			commandOutput:  "", | ||||
| 			commandError:   errors.New("expected error."), | ||||
| 			expectedError:  true, | ||||
| 			expectedErrMsg: "error calling ebsnvme-id.exe: expected error.", | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  "foolish output.", | ||||
| 			expectedError:  true, | ||||
| 			expectedErrMsg: `disk not found in ebsnvme-id.exe output: "foolish output."`, | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  "Disk Number: 42\nVolume ID: vol-fake-id", | ||||
| 			expectedOutput: "42", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	fakeHost := volumetest.NewFakeVolumeHost(t, os.TempDir(), nil, nil) | ||||
| 	fakeExec := fakeHost.GetExec("").(*exectest.FakeExec) | ||||
|  | ||||
| 	// This will enable fakeExec to "run" commands. | ||||
| 	fakeExec.DisableScripts = false | ||||
| 	attacher := &awsElasticBlockStoreAttacher{ | ||||
| 		host: fakeHost, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range testCases { | ||||
| 		fakeCmd := &exectest.FakeCmd{ | ||||
| 			CombinedOutputScript: []exectest.FakeAction{ | ||||
| 				func() ([]byte, []byte, error) { | ||||
| 					return []byte(tc.commandOutput), []byte(""), tc.commandError | ||||
| 				}, | ||||
| 			}, | ||||
| 		} | ||||
| 		fakeExec.CommandScript = []exectest.FakeCommandAction{ | ||||
| 			func(cmd string, args ...string) exec.Cmd { | ||||
| 				return fakeCmd | ||||
| 			}, | ||||
| 		} | ||||
| 		fakeExec.CommandCalls = 0 | ||||
|  | ||||
| 		fakeVolID := "aws://us-west-2b/vol-fake-id" | ||||
| 		devPath, err := attacher.getDevicePath(fakeVolID, "fake-partition", "fake-device-path") | ||||
| 		if tc.expectedError { | ||||
| 			if err == nil || err.Error() != tc.expectedErrMsg { | ||||
| 				t.Errorf("expected error message `%s` but got `%v`", tc.expectedErrMsg, err) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		require.NoError(t, err) | ||||
| 		assert.Equal(t, tc.expectedOutput, devPath) | ||||
| 	} | ||||
| } | ||||
| @@ -100,10 +100,10 @@ func findDiskByLun(lun int, iohandler ioHandler, exec utilexec.Interface) (strin | ||||
| 	return "", nil | ||||
| } | ||||
|  | ||||
| func formatIfNotFormatted(disk string, fstype string, exec utilexec.Interface) { | ||||
| func formatIfNotFormatted(disk string, fstype string, exec utilexec.Interface) error { | ||||
| 	if err := mount.ValidateDiskNumber(disk); err != nil { | ||||
| 		klog.Errorf("azureDisk Mount: formatIfNotFormatted failed, err: %v\n", err) | ||||
| 		return | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if len(fstype) == 0 { | ||||
| @@ -115,7 +115,8 @@ func formatIfNotFormatted(disk string, fstype string, exec utilexec.Interface) { | ||||
| 	output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() | ||||
| 	if err != nil { | ||||
| 		klog.Errorf("azureDisk Mount: Get-Disk failed, error: %v, output: %q", err, string(output)) | ||||
| 	} else { | ||||
| 		klog.Infof("azureDisk Mount: Disk successfully formatted, disk: %q, fstype: %q\n", disk, fstype) | ||||
| 		return err | ||||
| 	} | ||||
| 	klog.Infof("azureDisk Mount: Disk successfully formatted, disk: %q, fstype: %q\n", disk, fstype) | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										154
									
								
								pkg/volume/azuredd/azure_common_windows_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								pkg/volume/azuredd/azure_common_windows_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
| //go:build !providerless && windows | ||||
| // +build !providerless,windows | ||||
|  | ||||
| /* | ||||
| Copyright 2022 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package azuredd | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
|  | ||||
| 	"k8s.io/utils/exec" | ||||
| 	exectest "k8s.io/utils/exec/testing" | ||||
| ) | ||||
|  | ||||
| func newFakeExec(stdout []byte, err error) *exectest.FakeExec { | ||||
| 	fakeCmd := &exectest.FakeCmd{ | ||||
| 		CombinedOutputScript: []exectest.FakeAction{ | ||||
| 			func() ([]byte, []byte, error) { | ||||
| 				return stdout, []byte(""), err | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	return &exectest.FakeExec{ | ||||
| 		CommandScript: []exectest.FakeCommandAction{ | ||||
| 			func(cmd string, args ...string) exec.Cmd { | ||||
| 				return fakeCmd | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestScsiHostRescan(t *testing.T) { | ||||
| 	// NOTE: We don't have any assertions we can make for this test. | ||||
| 	fakeExec := newFakeExec([]byte("expected output."), errors.New("expected error.")) | ||||
| 	scsiHostRescan(nil, fakeExec) | ||||
| } | ||||
|  | ||||
| func TestGetDevicePath(t *testing.T) { | ||||
| 	diskNoLun := make(map[string]interface{}, 0) | ||||
| 	diskNoLun["location"] = "incorrect location" | ||||
|  | ||||
| 	// The expectation is that the string will contain at least 2 spaces | ||||
| 	diskIncorrectLun := make(map[string]interface{}, 0) | ||||
| 	diskIncorrectLun["location"] = " LUN 1" | ||||
|  | ||||
| 	diskNoIntegerLun := make(map[string]interface{}, 0) | ||||
| 	diskNoIntegerLun["location"] = "Integrated : Adapter 1 : Port 0 : Target 0 : LUN A" | ||||
|  | ||||
| 	lun := 42 | ||||
| 	invalidDiskNumberLun := make(map[string]interface{}, 0) | ||||
| 	invalidDiskNumberLun["location"] = "Integrated : Adapter 1 : Port 0 : Target 0 : LUN 42" | ||||
| 	invalidDiskNumberLun["number"] = "not a float" | ||||
|  | ||||
| 	validLun := make(map[string]interface{}, 0) | ||||
| 	validLun["location"] = "Integrated : Adapter 1 : Port 0 : Target 0 : LUN 42" | ||||
| 	validLun["number"] = 1.5 | ||||
|  | ||||
| 	noDiskFoundJson, _ := json.Marshal([]map[string]interface{}{diskNoLun, diskIncorrectLun, diskNoIntegerLun}) | ||||
| 	invaliDiskJson, _ := json.Marshal([]map[string]interface{}{invalidDiskNumberLun}) | ||||
| 	validJson, _ := json.Marshal([]map[string]interface{}{validLun}) | ||||
|  | ||||
| 	testCases := []struct { | ||||
| 		commandOutput  []byte | ||||
| 		commandError   error | ||||
| 		expectedOutput string | ||||
| 		expectedError  bool | ||||
| 		expectedErrMsg string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			commandOutput:  []byte("foolish output."), | ||||
| 			commandError:   errors.New("expected error."), | ||||
| 			expectedError:  true, | ||||
| 			expectedErrMsg: "expected error.", | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  []byte("too short"), | ||||
| 			expectedError:  true, | ||||
| 			expectedErrMsg: `Get-Disk output is too short, output: "too short"`, | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  []byte("not a json"), | ||||
| 			expectedError:  true, | ||||
| 			expectedErrMsg: `invalid character 'o' in literal null (expecting 'u')`, | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  noDiskFoundJson, | ||||
| 			expectedOutput: "", | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  invaliDiskJson, | ||||
| 			expectedError:  true, | ||||
| 			expectedErrMsg: fmt.Sprintf("LUN(%d) found, but could not get disk number, location: %q", lun, invalidDiskNumberLun["location"]), | ||||
| 		}, | ||||
| 		{ | ||||
| 			commandOutput:  validJson, | ||||
| 			expectedOutput: "/dev/disk1", | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tc := range testCases { | ||||
| 		fakeExec := newFakeExec(tc.commandOutput, tc.commandError) | ||||
| 		disk, err := findDiskByLun(lun, nil, fakeExec) | ||||
|  | ||||
| 		if tc.expectedError { | ||||
| 			if err == nil || err.Error() != tc.expectedErrMsg { | ||||
| 				t.Errorf("expected error message `%s` but got `%v`", tc.expectedErrMsg, err) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		require.NoError(t, err) | ||||
| 		assert.Equal(t, tc.expectedOutput, disk) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestFormatIfNotFormatted(t *testing.T) { | ||||
| 	fakeExec := newFakeExec([]byte{}, errors.New("expected error.")) | ||||
|  | ||||
| 	err := formatIfNotFormatted("fake disk number", "", fakeExec) | ||||
| 	expectedErrMsg := `wrong disk number format: "fake disk number", err: strconv.Atoi: parsing "fake disk number": invalid syntax` | ||||
| 	if err == nil || err.Error() != expectedErrMsg { | ||||
| 		t.Errorf("expected error message `%s` but got `%v`", expectedErrMsg, err) | ||||
| 	} | ||||
|  | ||||
| 	err = formatIfNotFormatted("1", "", fakeExec) | ||||
| 	expectedErrMsg = "expected error." | ||||
| 	if err == nil || err.Error() != expectedErrMsg { | ||||
| 		t.Errorf("expected error message `%s` but got `%v`", expectedErrMsg, err) | ||||
| 	} | ||||
|  | ||||
| 	fakeExec = newFakeExec([]byte{}, nil) | ||||
| 	err = formatIfNotFormatted("1", "", fakeExec) | ||||
| 	require.NoError(t, err) | ||||
| } | ||||
| @@ -0,0 +1,43 @@ | ||||
| //go:build !providerless && windows | ||||
| // +build !providerless,windows | ||||
|  | ||||
| /* | ||||
| Copyright 2022 The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| package vsphere_volume | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
|  | ||||
| func TestFormatIfNotFormatted(t *testing.T) { | ||||
| 	// If this volume has already been mounted then | ||||
| 	// its devicePath will have already been converted to a disk number, | ||||
| 	// meaning that the original path is returned. | ||||
| 	devPath, err := verifyDevicePath("foo") | ||||
| 	require.NoError(t, err) | ||||
| 	assert.Equal(t, "foo", devPath) | ||||
|  | ||||
| 	// Won't match any serial number, meaning that an error will be returned. | ||||
| 	devPath, err = verifyDevicePath(diskByIDPath + diskSCSIPrefix + "fake-serial") | ||||
| 	expectedErrMsg := `unable to find vSphere disk with serial fake-serial` | ||||
| 	if err == nil || err.Error() != expectedErrMsg { | ||||
| 		t.Errorf("expected error message `%s` but got `%v`", expectedErrMsg, err) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Prow Robot
					Kubernetes Prow Robot