mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Merge pull request #110263 from claudiubelu/unittests
unittests: Fixes unit tests for Windows
This commit is contained in:
commit
244c035b87
@ -351,6 +351,13 @@ func loadConfigFile(name string) (*kubeletconfiginternal.KubeletConfiguration, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(errFmt, name, err)
|
return nil, fmt.Errorf(errFmt, name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EvictionHard may be nil if it was not set in kubelet's config file.
|
||||||
|
// EvictionHard can have OS-specific fields, which is why there's no default value for it.
|
||||||
|
// See: https://github.com/kubernetes/kubernetes/pull/110263
|
||||||
|
if kc.EvictionHard == nil {
|
||||||
|
kc.EvictionHard = eviction.DefaultEvictionHard
|
||||||
|
}
|
||||||
return kc, err
|
return kc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/cluster/ports"
|
"k8s.io/kubernetes/pkg/cluster/ports"
|
||||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1"
|
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1"
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/eviction"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
utilpointer "k8s.io/utils/pointer"
|
utilpointer "k8s.io/utils/pointer"
|
||||||
@ -91,7 +92,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
|||||||
obj.KubeAPIQPS = 5
|
obj.KubeAPIQPS = 5
|
||||||
obj.KubeAPIBurst = 10
|
obj.KubeAPIBurst = 10
|
||||||
obj.HairpinMode = v1beta1.PromiscuousBridge
|
obj.HairpinMode = v1beta1.PromiscuousBridge
|
||||||
obj.EvictionHard = kubeletconfigv1beta1.DefaultEvictionHard
|
obj.EvictionHard = eviction.DefaultEvictionHard
|
||||||
obj.EvictionPressureTransitionPeriod = metav1.Duration{Duration: 5 * time.Minute}
|
obj.EvictionPressureTransitionPeriod = metav1.Duration{Duration: 5 * time.Minute}
|
||||||
obj.MakeIPTablesUtilChains = true
|
obj.MakeIPTablesUtilChains = true
|
||||||
obj.IPTablesMasqueradeBit = kubeletconfigv1beta1.DefaultIPTablesMasqueradeBit
|
obj.IPTablesMasqueradeBit = kubeletconfigv1beta1.DefaultIPTablesMasqueradeBit
|
||||||
|
@ -32,11 +32,6 @@ enforceNodeAllocatable:
|
|||||||
- pods
|
- pods
|
||||||
eventBurst: 10
|
eventBurst: 10
|
||||||
eventRecordQPS: 5
|
eventRecordQPS: 5
|
||||||
evictionHard:
|
|
||||||
imagefs.available: 15%
|
|
||||||
memory.available: 100Mi
|
|
||||||
nodefs.available: 10%
|
|
||||||
nodefs.inodesFree: 5%
|
|
||||||
evictionPressureTransitionPeriod: 5m0s
|
evictionPressureTransitionPeriod: 5m0s
|
||||||
failSwapOn: true
|
failSwapOn: true
|
||||||
fileCheckFrequency: 20s
|
fileCheckFrequency: 20s
|
||||||
|
@ -32,11 +32,6 @@ enforceNodeAllocatable:
|
|||||||
- pods
|
- pods
|
||||||
eventBurst: 10
|
eventBurst: 10
|
||||||
eventRecordQPS: 5
|
eventRecordQPS: 5
|
||||||
evictionHard:
|
|
||||||
imagefs.available: 15%
|
|
||||||
memory.available: 100Mi
|
|
||||||
nodefs.available: 10%
|
|
||||||
nodefs.inodesFree: 5%
|
|
||||||
evictionPressureTransitionPeriod: 5m0s
|
evictionPressureTransitionPeriod: 5m0s
|
||||||
failSwapOn: true
|
failSwapOn: true
|
||||||
fileCheckFrequency: 20s
|
fileCheckFrequency: 20s
|
||||||
|
@ -289,6 +289,7 @@ type KubeletConfiguration struct {
|
|||||||
// serializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
|
// serializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
|
||||||
SerializeImagePulls bool
|
SerializeImagePulls bool
|
||||||
// Map of signal names to quantities that defines hard eviction thresholds. For example: {"memory.available": "300Mi"}.
|
// Map of signal names to quantities that defines hard eviction thresholds. For example: {"memory.available": "300Mi"}.
|
||||||
|
// Some default signals are Linux only: nodefs.inodesFree
|
||||||
EvictionHard map[string]string
|
EvictionHard map[string]string
|
||||||
// Map of signal names to quantities that defines soft eviction thresholds. For example: {"memory.available": "300Mi"}.
|
// Map of signal names to quantities that defines soft eviction thresholds. For example: {"memory.available": "300Mi"}.
|
||||||
EvictionSoft map[string]string
|
EvictionSoft map[string]string
|
||||||
|
@ -208,9 +208,6 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura
|
|||||||
if obj.SerializeImagePulls == nil {
|
if obj.SerializeImagePulls == nil {
|
||||||
obj.SerializeImagePulls = utilpointer.BoolPtr(true)
|
obj.SerializeImagePulls = utilpointer.BoolPtr(true)
|
||||||
}
|
}
|
||||||
if obj.EvictionHard == nil {
|
|
||||||
obj.EvictionHard = DefaultEvictionHard
|
|
||||||
}
|
|
||||||
if obj.EvictionPressureTransitionPeriod == zeroDuration {
|
if obj.EvictionPressureTransitionPeriod == zeroDuration {
|
||||||
obj.EvictionPressureTransitionPeriod = metav1.Duration{Duration: 5 * time.Minute}
|
obj.EvictionPressureTransitionPeriod = metav1.Duration{Duration: 5 * time.Minute}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
|
|||||||
KubeAPIQPS: utilpointer.Int32Ptr(5),
|
KubeAPIQPS: utilpointer.Int32Ptr(5),
|
||||||
KubeAPIBurst: 10,
|
KubeAPIBurst: 10,
|
||||||
SerializeImagePulls: utilpointer.BoolPtr(true),
|
SerializeImagePulls: utilpointer.BoolPtr(true),
|
||||||
EvictionHard: DefaultEvictionHard,
|
EvictionHard: nil,
|
||||||
EvictionPressureTransitionPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
EvictionPressureTransitionPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
||||||
EnableControllerAttachDetach: utilpointer.BoolPtr(true),
|
EnableControllerAttachDetach: utilpointer.BoolPtr(true),
|
||||||
MakeIPTablesUtilChains: utilpointer.BoolPtr(true),
|
MakeIPTablesUtilChains: utilpointer.BoolPtr(true),
|
||||||
@ -698,7 +698,7 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
|
|||||||
KubeAPIQPS: utilpointer.Int32Ptr(5),
|
KubeAPIQPS: utilpointer.Int32Ptr(5),
|
||||||
KubeAPIBurst: 10,
|
KubeAPIBurst: 10,
|
||||||
SerializeImagePulls: utilpointer.BoolPtr(true),
|
SerializeImagePulls: utilpointer.BoolPtr(true),
|
||||||
EvictionHard: DefaultEvictionHard,
|
EvictionHard: nil,
|
||||||
EvictionPressureTransitionPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
EvictionPressureTransitionPeriod: metav1.Duration{Duration: 5 * time.Minute},
|
||||||
EnableControllerAttachDetach: utilpointer.BoolPtr(true),
|
EnableControllerAttachDetach: utilpointer.BoolPtr(true),
|
||||||
MakeIPTablesUtilChains: utilpointer.BoolPtr(true),
|
MakeIPTablesUtilChains: utilpointer.BoolPtr(true),
|
||||||
|
25
pkg/kubelet/apis/config/validation/validation_others_test.go
Normal file
25
pkg/kubelet/apis/config/validation/validation_others_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//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 validation_test
|
||||||
|
|
||||||
|
var (
|
||||||
|
cgroupsPerQOS = true
|
||||||
|
enforceNodeAllocatable = []string{"pods", "system-reserved", "kube-reserved"}
|
||||||
|
)
|
@ -34,8 +34,8 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
successConfig = kubeletconfig.KubeletConfiguration{
|
successConfig = kubeletconfig.KubeletConfiguration{
|
||||||
CgroupsPerQOS: true,
|
CgroupsPerQOS: cgroupsPerQOS,
|
||||||
EnforceNodeAllocatable: []string{"pods", "system-reserved", "kube-reserved"},
|
EnforceNodeAllocatable: enforceNodeAllocatable,
|
||||||
SystemReservedCgroup: "/system.slice",
|
SystemReservedCgroup: "/system.slice",
|
||||||
KubeReservedCgroup: "/kubelet.service",
|
KubeReservedCgroup: "/kubelet.service",
|
||||||
SystemCgroups: "",
|
SystemCgroups: "",
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
//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 validation_test
|
||||||
|
|
||||||
|
var (
|
||||||
|
// These config options are not supported on Windows.
|
||||||
|
cgroupsPerQOS = false
|
||||||
|
enforceNodeAllocatable = []string{}
|
||||||
|
)
|
@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -104,6 +105,8 @@ users:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
// os.CreateTemp also opens the file, and removing it without closing it will result in a failure.
|
||||||
|
defer filevalid.Close()
|
||||||
os.WriteFile(filevalid.Name(), testDataValid, os.FileMode(0755))
|
os.WriteFile(filevalid.Name(), testDataValid, os.FileMode(0755))
|
||||||
|
|
||||||
testDataInvalid := []byte(`
|
testDataInvalid := []byte(`
|
||||||
@ -144,6 +147,7 @@ users:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer fileinvalid.Close()
|
||||||
os.WriteFile(fileinvalid.Name(), testDataInvalid, os.FileMode(0755))
|
os.WriteFile(fileinvalid.Name(), testDataInvalid, os.FileMode(0755))
|
||||||
|
|
||||||
testDatabootstrap := []byte(`
|
testDatabootstrap := []byte(`
|
||||||
@ -181,6 +185,7 @@ users:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
defer fileboot.Close()
|
||||||
os.WriteFile(fileboot.Name(), testDatabootstrap, os.FileMode(0755))
|
os.WriteFile(fileboot.Name(), testDatabootstrap, os.FileMode(0755))
|
||||||
|
|
||||||
dir, err := os.MkdirTemp(fileDir, "k8s-test-certstore-current")
|
dir, err := os.MkdirTemp(fileDir, "k8s-test-certstore-current")
|
||||||
@ -209,16 +214,16 @@ users:
|
|||||||
expectedCertConfig: &restclient.Config{
|
expectedCertConfig: &restclient.Config{
|
||||||
Host: "https://cluster-b.com",
|
Host: "https://cluster-b.com",
|
||||||
TLSClientConfig: restclient.TLSClientConfig{
|
TLSClientConfig: restclient.TLSClientConfig{
|
||||||
CertFile: fileDir + "/mycertvalid.crt",
|
CertFile: filepath.Join(fileDir, "mycertvalid.crt"),
|
||||||
KeyFile: fileDir + "/mycertvalid.key",
|
KeyFile: filepath.Join(fileDir, "mycertvalid.key"),
|
||||||
},
|
},
|
||||||
BearerToken: "",
|
BearerToken: "",
|
||||||
},
|
},
|
||||||
expectedClientConfig: &restclient.Config{
|
expectedClientConfig: &restclient.Config{
|
||||||
Host: "https://cluster-b.com",
|
Host: "https://cluster-b.com",
|
||||||
TLSClientConfig: restclient.TLSClientConfig{
|
TLSClientConfig: restclient.TLSClientConfig{
|
||||||
CertFile: fileDir + "/mycertvalid.crt",
|
CertFile: filepath.Join(fileDir, "mycertvalid.crt"),
|
||||||
KeyFile: fileDir + "/mycertvalid.key",
|
KeyFile: filepath.Join(fileDir, "mycertvalid.key"),
|
||||||
},
|
},
|
||||||
BearerToken: "",
|
BearerToken: "",
|
||||||
},
|
},
|
||||||
@ -231,16 +236,16 @@ users:
|
|||||||
expectedCertConfig: &restclient.Config{
|
expectedCertConfig: &restclient.Config{
|
||||||
Host: "https://cluster-b.com",
|
Host: "https://cluster-b.com",
|
||||||
TLSClientConfig: restclient.TLSClientConfig{
|
TLSClientConfig: restclient.TLSClientConfig{
|
||||||
CertFile: fileDir + "/mycertvalid.crt",
|
CertFile: filepath.Join(fileDir, "mycertvalid.crt"),
|
||||||
KeyFile: fileDir + "/mycertvalid.key",
|
KeyFile: filepath.Join(fileDir, "mycertvalid.key"),
|
||||||
},
|
},
|
||||||
BearerToken: "",
|
BearerToken: "",
|
||||||
},
|
},
|
||||||
expectedClientConfig: &restclient.Config{
|
expectedClientConfig: &restclient.Config{
|
||||||
Host: "https://cluster-b.com",
|
Host: "https://cluster-b.com",
|
||||||
TLSClientConfig: restclient.TLSClientConfig{
|
TLSClientConfig: restclient.TLSClientConfig{
|
||||||
CertFile: fileDir + "/mycertvalid.crt",
|
CertFile: filepath.Join(fileDir, "mycertvalid.crt"),
|
||||||
KeyFile: fileDir + "/mycertvalid.key",
|
KeyFile: filepath.Join(fileDir, "mycertvalid.key"),
|
||||||
},
|
},
|
||||||
BearerToken: "",
|
BearerToken: "",
|
||||||
},
|
},
|
||||||
|
@ -627,7 +627,7 @@ func TestCPUManagerGenerate(t *testing.T) {
|
|||||||
if testCase.isTopologyBroken {
|
if testCase.isTopologyBroken {
|
||||||
machineInfo = &cadvisorapi.MachineInfo{}
|
machineInfo = &cadvisorapi.MachineInfo{}
|
||||||
}
|
}
|
||||||
sDir, err := os.MkdirTemp("/tmp/", "cpu_manager_test")
|
sDir, err := os.MkdirTemp("", "cpu_manager_test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("cannot create state file: %s", err.Error())
|
t.Errorf("cannot create state file: %s", err.Error())
|
||||||
}
|
}
|
||||||
@ -1347,7 +1347,7 @@ func TestCPUManagerHandlePolicyOptions(t *testing.T) {
|
|||||||
t.Run(testCase.description, func(t *testing.T) {
|
t.Run(testCase.description, func(t *testing.T) {
|
||||||
machineInfo := &mockedMachineInfo
|
machineInfo := &mockedMachineInfo
|
||||||
nodeAllocatableReservation := v1.ResourceList{}
|
nodeAllocatableReservation := v1.ResourceList{}
|
||||||
sDir, err := os.MkdirTemp("/tmp/", "cpu_manager_test")
|
sDir, err := os.MkdirTemp("", "cpu_manager_test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("cannot create state file: %s", err.Error())
|
t.Errorf("cannot create state file: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package devicemanager
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
@ -71,7 +72,7 @@ func esocketName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewEndpoint(t *testing.T) {
|
func TestNewEndpoint(t *testing.T) {
|
||||||
socket := path.Join("/tmp", esocketName())
|
socket := path.Join(os.TempDir(), esocketName())
|
||||||
|
|
||||||
devs := []*pluginapi.Device{
|
devs := []*pluginapi.Device{
|
||||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||||
@ -82,7 +83,7 @@ func TestNewEndpoint(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRun(t *testing.T) {
|
func TestRun(t *testing.T) {
|
||||||
socket := path.Join("/tmp", esocketName())
|
socket := path.Join(os.TempDir(), esocketName())
|
||||||
|
|
||||||
devs := []*pluginapi.Device{
|
devs := []*pluginapi.Device{
|
||||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||||
@ -147,7 +148,7 @@ func TestRun(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAllocate(t *testing.T) {
|
func TestAllocate(t *testing.T) {
|
||||||
socket := path.Join("/tmp", esocketName())
|
socket := path.Join(os.TempDir(), esocketName())
|
||||||
devs := []*pluginapi.Device{
|
devs := []*pluginapi.Device{
|
||||||
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
{ID: "ADeviceId", Health: pluginapi.Healthy},
|
||||||
}
|
}
|
||||||
@ -200,7 +201,7 @@ func TestAllocate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPreferredAllocation(t *testing.T) {
|
func TestGetPreferredAllocation(t *testing.T) {
|
||||||
socket := path.Join("/tmp", esocketName())
|
socket := path.Join(os.TempDir(), esocketName())
|
||||||
callbackCount := 0
|
callbackCount := 0
|
||||||
callbackChan := make(chan int)
|
callbackChan := make(chan int)
|
||||||
p, e := esetup(t, []*pluginapi.Device{}, socket, "mock", func(n string, d []pluginapi.Device) {
|
p, e := esetup(t, []*pluginapi.Device{}, socket, "mock", func(n string, d []pluginapi.Device) {
|
||||||
|
@ -1981,7 +1981,7 @@ func TestNewManager(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
t.Run(testCase.description, func(t *testing.T) {
|
t.Run(testCase.description, func(t *testing.T) {
|
||||||
stateFileDirectory, err := os.MkdirTemp("/tmp/", "memory_manager_tests")
|
stateFileDirectory, err := os.MkdirTemp("", "memory_manager_tests")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Cannot create state file: %s", err.Error())
|
t.Errorf("Cannot create state file: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1beta1
|
package eviction
|
||||||
|
|
||||||
// DefaultEvictionHard includes default options for hard eviction.
|
// DefaultEvictionHard includes default options for hard eviction.
|
||||||
var DefaultEvictionHard = map[string]string{
|
var DefaultEvictionHard = map[string]string{
|
@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package v1beta1
|
package eviction
|
||||||
|
|
||||||
// DefaultEvictionHard includes default options for hard eviction.
|
// DefaultEvictionHard includes default options for hard eviction.
|
||||||
var DefaultEvictionHard = map[string]string{
|
var DefaultEvictionHard = map[string]string{
|
@ -462,7 +462,9 @@ func TestFreeSpaceRemoveByLeastRecentlyUsed(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, manager.imageRecordsLen(), 2)
|
require.Equal(t, manager.imageRecordsLen(), 2)
|
||||||
|
|
||||||
spaceFreed, err := manager.freeSpace(1024, time.Now())
|
// We're setting the delete time one minute in the future, so the time the image
|
||||||
|
// was first detected and the delete time are different.
|
||||||
|
spaceFreed, err := manager.freeSpace(1024, time.Now().Add(time.Minute))
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.EqualValues(1024, spaceFreed)
|
assert.EqualValues(1024, spaceFreed)
|
||||||
|
@ -17,9 +17,12 @@ limitations under the License.
|
|||||||
package kubelet
|
package kubelet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/hostutil"
|
"k8s.io/kubernetes/pkg/volume/util/hostutil"
|
||||||
@ -84,7 +87,11 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||||||
|
|
||||||
fhu := hostutil.NewFakeHostUtil(nil)
|
fhu := hostutil.NewFakeHostUtil(nil)
|
||||||
fsp := &subpath.FakeSubpath{}
|
fsp := &subpath.FakeSubpath{}
|
||||||
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", []string{""}, podVolumes, fhu, fsp, nil)
|
podDir, err := os.MkdirTemp("", "test-rotate-logs")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.RemoveAll(podDir)
|
||||||
|
mounts, _, err := makeMounts(&pod, podDir, &container, "fakepodname", "", []string{""}, podVolumes, fhu, fsp, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
expectedMounts := []kubecontainer.Mount{
|
expectedMounts := []kubecontainer.Mount{
|
||||||
{
|
{
|
||||||
@ -136,6 +143,13 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||||||
ReadOnly: false,
|
ReadOnly: false,
|
||||||
SELinuxRelabel: false,
|
SELinuxRelabel: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "k8s-managed-etc-hosts",
|
||||||
|
ContainerPath: `C:\Windows\System32\drivers\etc\hosts`,
|
||||||
|
HostPath: filepath.Join(podDir, "etc-hosts"),
|
||||||
|
ReadOnly: false,
|
||||||
|
SELinuxRelabel: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
assert.Equal(t, expectedMounts, mounts, "mounts of container %+v", container)
|
assert.Equal(t, expectedMounts, mounts, "mounts of container %+v", container)
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,11 @@ func (f *file) write(fs utilfs.Filesystem, dir string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = handle.Write([]byte(f.data))
|
_, err = handle.Write([]byte(f.data))
|
||||||
if err != nil {
|
// The file should always be closed, not just in error cases.
|
||||||
if cerr := handle.Close(); cerr != nil {
|
if cerr := handle.Close(); cerr != nil {
|
||||||
return fmt.Errorf("error %v closing file after error: %v", cerr, err)
|
return fmt.Errorf("error closing file: %v", cerr)
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -195,12 +196,12 @@ func TestHelpers(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "missing file",
|
desc: "missing file",
|
||||||
expects: []file{{name: "foo", data: "bar"}},
|
expects: []file{{name: "foo", data: "bar"}},
|
||||||
err: "no such file or directory",
|
err: missingFileError,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "missing directory",
|
desc: "missing directory",
|
||||||
expects: []file{{name: "foo/bar", mode: os.ModeDir}},
|
expects: []file{{name: "foo/bar", mode: os.ModeDir}},
|
||||||
err: "no such file or directory",
|
err: missingFolderError,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
@ -312,7 +313,7 @@ func TestReplaceFile(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
desc: "neither parent nor file exists",
|
desc: "neither parent nor file exists",
|
||||||
err: "no such file or directory",
|
err: missingFileError,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
|
25
pkg/kubelet/kubeletconfig/util/files/files_unix_test.go
Normal file
25
pkg/kubelet/kubeletconfig/util/files/files_unix_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//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 files
|
||||||
|
|
||||||
|
const (
|
||||||
|
missingFileError = "no such file or directory"
|
||||||
|
missingFolderError = "no such file or directory"
|
||||||
|
)
|
25
pkg/kubelet/kubeletconfig/util/files/files_windows_test.go
Normal file
25
pkg/kubelet/kubeletconfig/util/files/files_windows_test.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//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 files
|
||||||
|
|
||||||
|
const (
|
||||||
|
missingFileError = "The system cannot find the file specified."
|
||||||
|
missingFolderError = "The system cannot find the path specified."
|
||||||
|
)
|
@ -70,6 +70,7 @@ func TestRemoveContainer(t *testing.T) {
|
|||||||
fakeOS := m.osInterface.(*containertest.FakeOS)
|
fakeOS := m.osInterface.(*containertest.FakeOS)
|
||||||
fakeOS.GlobFn = func(pattern, path string) bool {
|
fakeOS.GlobFn = func(pattern, path string) bool {
|
||||||
pattern = strings.Replace(pattern, "*", ".*", -1)
|
pattern = strings.Replace(pattern, "*", ".*", -1)
|
||||||
|
pattern = strings.Replace(pattern, "\\", "\\\\", -1)
|
||||||
return regexp.MustCompile(pattern).MatchString(path)
|
return regexp.MustCompile(pattern).MatchString(path)
|
||||||
}
|
}
|
||||||
expectedContainerLogPath := filepath.Join(podLogsRootDirectory, "new_bar_12345678", "foo", "0.log")
|
expectedContainerLogPath := filepath.Join(podLogsRootDirectory, "new_bar_12345678", "foo", "0.log")
|
||||||
|
@ -328,6 +328,7 @@ func TestCompressLog(t *testing.T) {
|
|||||||
testContent := "test log content"
|
testContent := "test log content"
|
||||||
_, err = testFile.Write([]byte(testContent))
|
_, err = testFile.Write([]byte(testContent))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
testFile.Close()
|
||||||
|
|
||||||
testLog := testFile.Name()
|
testLog := testFile.Name()
|
||||||
c := &containerLogManager{osInterface: container.RealOS{}}
|
c := &containerLogManager{osInterface: container.RealOS{}}
|
||||||
@ -388,6 +389,7 @@ func TestRotateLatestLog(t *testing.T) {
|
|||||||
}
|
}
|
||||||
testFile, err := os.CreateTemp(dir, "test-rotate-latest-log")
|
testFile, err := os.CreateTemp(dir, "test-rotate-latest-log")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
testFile.Close()
|
||||||
defer testFile.Close()
|
defer testFile.Close()
|
||||||
testLog := testFile.Name()
|
testLog := testFile.Name()
|
||||||
rotatedLog := fmt.Sprintf("%s.%s", testLog, now.Format(timestampFormat))
|
rotatedLog := fmt.Sprintf("%s.%s", testLog, now.Format(timestampFormat))
|
||||||
|
@ -67,12 +67,14 @@ func TestSummaryProvider(t *testing.T) {
|
|||||||
mockStatsProvider.EXPECT().RlimitStats().Return(nil, nil).AnyTimes()
|
mockStatsProvider.EXPECT().RlimitStats().Return(nil, nil).AnyTimes()
|
||||||
mockStatsProvider.EXPECT().GetCgroupStats("/", true).Return(cgroupStatsMap["/"].cs, cgroupStatsMap["/"].ns, nil).AnyTimes()
|
mockStatsProvider.EXPECT().GetCgroupStats("/", true).Return(cgroupStatsMap["/"].cs, cgroupStatsMap["/"].ns, nil).AnyTimes()
|
||||||
|
|
||||||
provider := NewSummaryProvider(mockStatsProvider)
|
kubeletCreationTime := metav1.Now()
|
||||||
|
systemBootTime := metav1.Now()
|
||||||
|
provider := summaryProviderImpl{kubeletCreationTime: kubeletCreationTime, systemBootTime: systemBootTime, provider: mockStatsProvider}
|
||||||
summary, err := provider.Get(true)
|
summary, err := provider.Get(true)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
assert.Equal(summary.Node.NodeName, "test-node")
|
assert.Equal(summary.Node.NodeName, "test-node")
|
||||||
assert.Equal(summary.Node.StartTime, cgroupStatsMap["/"].cs.StartTime)
|
assert.Equal(summary.Node.StartTime, systemBootTime)
|
||||||
assert.Equal(summary.Node.CPU, cgroupStatsMap["/"].cs.CPU)
|
assert.Equal(summary.Node.CPU, cgroupStatsMap["/"].cs.CPU)
|
||||||
assert.Equal(summary.Node.Memory, cgroupStatsMap["/"].cs.Memory)
|
assert.Equal(summary.Node.Memory, cgroupStatsMap["/"].cs.Memory)
|
||||||
assert.Equal(summary.Node.Network, cgroupStatsMap["/"].ns)
|
assert.Equal(summary.Node.Network, cgroupStatsMap["/"].ns)
|
||||||
|
@ -1319,7 +1319,11 @@ func TestDoNotDeleteMirrorPods(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateLastTransitionTime(t *testing.T) {
|
func TestUpdateLastTransitionTime(t *testing.T) {
|
||||||
old := metav1.Now()
|
// On Windows, time.Now() is not as precise, which means that 2 consecutive calls may
|
||||||
|
// return the same timestamp. This test expects the old timestamp to be updated with a
|
||||||
|
// newer one, so we set the old timestamp to one second in the past.
|
||||||
|
// See: https://github.com/golang/go/issues/8687
|
||||||
|
old := metav1.NewTime(time.Now().Add(-time.Second))
|
||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
condition *v1.PodCondition
|
condition *v1.PodCondition
|
||||||
oldCondition *v1.PodCondition
|
oldCondition *v1.PodCondition
|
||||||
|
Loading…
Reference in New Issue
Block a user