diff --git a/pkg/scheduler/framework/runtime/framework_test.go b/pkg/scheduler/framework/runtime/framework_test.go index 5363b56b9f6..a6fc77c0bfa 100644 --- a/pkg/scheduler/framework/runtime/framework_test.go +++ b/pkg/scheduler/framework/runtime/framework_test.go @@ -2827,9 +2827,7 @@ func collectAndComparePluginMetrics(t *testing.T, wantExtensionPoint, wantPlugin if err != nil { t.Errorf("Failed to get %s value, err: %v", metrics.PluginExecutionDuration.Name, err) } - if value <= 0 { - t.Errorf("Expect latency to be greater than 0, got: %v", value) - } + checkLatency(t, value) } func collectAndCompareFrameworkMetrics(t *testing.T, wantExtensionPoint string, wantStatus framework.Code) { @@ -2847,9 +2845,7 @@ func collectAndCompareFrameworkMetrics(t *testing.T, wantExtensionPoint string, if err != nil { t.Errorf("Failed to get %s value, err: %v", metrics.FrameworkExtensionPointDuration.Name, err) } - if value <= 0 { - t.Errorf("Expect latency to be greater than 0, got: %v", value) - } + checkLatency(t, value) } func collectAndComparePermitWaitDuration(t *testing.T, wantRes string) { @@ -2870,9 +2866,7 @@ func collectAndComparePermitWaitDuration(t *testing.T, wantRes string) { if err != nil { t.Errorf("Failed to get %s value, err: %v", metrics.PermitWaitDuration.Name, err) } - if value <= 0 { - t.Errorf("Expect latency to be greater than 0, got: %v", value) - } + checkLatency(t, value) } } diff --git a/pkg/scheduler/framework/runtime/util_others_test.go b/pkg/scheduler/framework/runtime/util_others_test.go new file mode 100644 index 00000000000..af5f3d1af53 --- /dev/null +++ b/pkg/scheduler/framework/runtime/util_others_test.go @@ -0,0 +1,30 @@ +//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 runtime + +import ( + "testing" +) + +func checkLatency(t *testing.T, value float64) { + if value <= 0 { + t.Errorf("Expect latency to be greater than 0, got: %v", value) + } +} diff --git a/pkg/scheduler/framework/runtime/util_windows_test.go b/pkg/scheduler/framework/runtime/util_windows_test.go new file mode 100644 index 00000000000..ccb3bca3321 --- /dev/null +++ b/pkg/scheduler/framework/runtime/util_windows_test.go @@ -0,0 +1,30 @@ +//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 runtime + +import ( + "testing" +) + +func checkLatency(t *testing.T, value float64) { + // On Windows, time.Now() is not as precise, 2 consecutive calls may return the same timestamp, + // thus, the latency metric may be 0 (SinceInSeconds will return 0). + // See: https://github.com/golang/go/issues/8687 +} diff --git a/pkg/volume/rbd/rbd_test.go b/pkg/volume/rbd/rbd_test.go index 1c7fc245932..ae84ecab936 100644 --- a/pkg/volume/rbd/rbd_test.go +++ b/pkg/volume/rbd/rbd_test.go @@ -156,15 +156,6 @@ func (fake *fakeDiskManager) MakeGlobalVDPDName(rbd rbd) string { return makePDNameInternal(rbd.plugin.host, rbd.Pool, rbd.Image) } -func (fake *fakeDiskManager) AttachDisk(b rbdMounter) (string, error) { - fake.mutex.Lock() - defer fake.mutex.Unlock() - fake.rbdMapIndex++ - devicePath := fmt.Sprintf("/dev/rbd%d", fake.rbdMapIndex) - fake.rbdDevices[devicePath] = true - return devicePath, nil -} - func (fake *fakeDiskManager) DetachDisk(r *rbdPlugin, deviceMountPath string, device string) error { fake.mutex.Lock() defer fake.mutex.Unlock() @@ -292,7 +283,11 @@ func doTestPlugin(t *testing.T, c *testcase) { t.Errorf("Attacher.MountDevice() failed: %v", err) } } - checkMounterLog(t, fakeMounter, 1, mount.FakeAction{Action: "mount", Target: c.expectedDeviceMountPath, Source: devicePath, FSType: "ext4"}) + loggedSource, err := getLoggedSource(devicePath) + if err != nil { + t.Fatal(err) + } + checkMounterLog(t, fakeMounter, 1, mount.FakeAction{Action: "mount", Target: c.expectedDeviceMountPath, Source: loggedSource, FSType: "ext4"}) // mounter mounter, err := plug.(*rbdPlugin).newMounterInternal(c.spec, c.pod.UID, fdm, "secrets") @@ -317,7 +312,7 @@ func doTestPlugin(t *testing.T, c *testcase) { t.Errorf("SetUp() failed: %v", err) } } - checkMounterLog(t, fakeMounter, 2, mount.FakeAction{Action: "mount", Target: c.expectedPodMountPath, Source: devicePath, FSType: ""}) + checkMounterLog(t, fakeMounter, 2, mount.FakeAction{Action: "mount", Target: c.expectedPodMountPath, Source: loggedSource, FSType: ""}) // unmounter unmounter, err := plug.(*rbdPlugin).newUnmounterInternal(c.spec.Name(), c.pod.UID, fdm) @@ -374,6 +369,12 @@ func TestPlugin(t *testing.T) { t.Fatal(err) } + expectedDevicePath := "/dev/rbd1" + if runtime.GOOS == "windows" { + // Windows expects Disk Numbers. + expectedDevicePath = "1" + } + podUID := uuid.NewUUID() var cases []*testcase cases = append(cases, &testcase{ @@ -396,7 +397,7 @@ func TestPlugin(t *testing.T) { UID: podUID, }, }, - expectedDevicePath: "/dev/rbd1", + expectedDevicePath: expectedDevicePath, expectedDeviceMountPath: filepath.Join(tmpDir, "plugins/kubernetes.io/rbd/mounts/pool1-image-image1"), expectedPodMountPath: filepath.Join(tmpDir, "pods", string(podUID), "volumes/kubernetes.io~rbd/vol1"), }) @@ -425,7 +426,7 @@ func TestPlugin(t *testing.T) { UID: podUID, }, }, - expectedDevicePath: "/dev/rbd1", + expectedDevicePath: expectedDevicePath, expectedDeviceMountPath: filepath.Join(tmpDir, "plugins/kubernetes.io/rbd/mounts/pool2-image-image2"), expectedPodMountPath: filepath.Join(tmpDir, "pods", string(podUID), "volumes/kubernetes.io~rbd/vol2"), }) diff --git a/pkg/volume/rbd/rbd_unix_test.go b/pkg/volume/rbd/rbd_unix_test.go new file mode 100644 index 00000000000..4c7877be013 --- /dev/null +++ b/pkg/volume/rbd/rbd_unix_test.go @@ -0,0 +1,37 @@ +//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 rbd + +import ( + "fmt" +) + +func (fake *fakeDiskManager) AttachDisk(b rbdMounter) (string, error) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.rbdMapIndex++ + devicePath := fmt.Sprintf("/dev/rbd%d", fake.rbdMapIndex) + fake.rbdDevices[devicePath] = true + return devicePath, nil +} + +func getLoggedSource(devicePath string) (string, error) { + return devicePath, nil +} diff --git a/pkg/volume/rbd/rbd_windows_test.go b/pkg/volume/rbd/rbd_windows_test.go new file mode 100644 index 00000000000..208b332493c --- /dev/null +++ b/pkg/volume/rbd/rbd_windows_test.go @@ -0,0 +1,63 @@ +//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 rbd + +import ( + "fmt" + "os/exec" + "strconv" + "strings" +) + +func (fake *fakeDiskManager) AttachDisk(b rbdMounter) (string, error) { + fake.mutex.Lock() + defer fake.mutex.Unlock() + fake.rbdMapIndex++ + + // Windows expects Disk Numbers. + volIds, err := listVolumesOnDisk(strconv.Itoa(fake.rbdMapIndex)) + if err != nil { + return "", err + } + fake.rbdDevices[volIds[0]] = true + devicePath := strconv.Itoa(fake.rbdMapIndex) + return devicePath, nil +} + +// listVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID) on Windows. +func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) { + cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID) + output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + if err != nil { + return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err) + } + + volumeIds := strings.Split(strings.TrimSpace(string(output)), "\r\n") + return volumeIds, nil +} + +func getLoggedSource(devicePath string) (string, error) { + // Windows mounter is mounting based on the Disk's Unique ID. + volIds, err := listVolumesOnDisk(devicePath) + if err != nil { + return "", err + } + return volIds[0], nil +} diff --git a/pkg/volume/util/nested_volumes_test.go b/pkg/volume/util/nested_volumes_test.go index b136eaeaf75..b3da8b7628a 100644 --- a/pkg/volume/util/nested_volumes_test.go +++ b/pkg/volume/util/nested_volumes_test.go @@ -144,7 +144,7 @@ func TestGetNestedMountpoints(t *testing.T) { name: "Big Pod", err: false, volname: "vol1", - expected: sets.NewString("sub1/sub2/sub3", "sub1/sub2/sub4", "sub1/sub2/sub6", "sub"), + expected: sets.NewString(filepath.Join("sub1", "sub2", "sub3"), filepath.Join("sub1", "sub2", "sub4"), filepath.Join("sub1", "sub2", "sub6"), "sub"), pod: v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace,