k8s.io/kubernetes@v1.29.3/pkg/kubelet/runonce_test.go (about) 1 /* 2 Copyright 2014 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 kubelet 18 19 import ( 20 "context" 21 "os" 22 "path/filepath" 23 "testing" 24 "time" 25 26 "github.com/golang/mock/gomock" 27 cadvisorapi "github.com/google/cadvisor/info/v1" 28 cadvisorapiv2 "github.com/google/cadvisor/info/v2" 29 "k8s.io/mount-utils" 30 31 v1 "k8s.io/api/core/v1" 32 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 "k8s.io/apimachinery/pkg/types" 34 "k8s.io/client-go/kubernetes/fake" 35 "k8s.io/client-go/tools/record" 36 utiltesting "k8s.io/client-go/util/testing" 37 cadvisortest "k8s.io/kubernetes/pkg/kubelet/cadvisor/testing" 38 "k8s.io/kubernetes/pkg/kubelet/clustertrustbundle" 39 "k8s.io/kubernetes/pkg/kubelet/cm" 40 "k8s.io/kubernetes/pkg/kubelet/configmap" 41 kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" 42 containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" 43 "k8s.io/kubernetes/pkg/kubelet/eviction" 44 kubepod "k8s.io/kubernetes/pkg/kubelet/pod" 45 podtest "k8s.io/kubernetes/pkg/kubelet/pod/testing" 46 "k8s.io/kubernetes/pkg/kubelet/secret" 47 "k8s.io/kubernetes/pkg/kubelet/server/stats" 48 "k8s.io/kubernetes/pkg/kubelet/status" 49 statustest "k8s.io/kubernetes/pkg/kubelet/status/testing" 50 kubeletutil "k8s.io/kubernetes/pkg/kubelet/util" 51 "k8s.io/kubernetes/pkg/kubelet/volumemanager" 52 "k8s.io/kubernetes/pkg/volume" 53 volumetest "k8s.io/kubernetes/pkg/volume/testing" 54 "k8s.io/kubernetes/pkg/volume/util/hostutil" 55 "k8s.io/utils/clock" 56 ) 57 58 func TestRunOnce(t *testing.T) { 59 ctx := context.Background() 60 mockCtrl := gomock.NewController(t) 61 defer mockCtrl.Finish() 62 63 cadvisor := cadvisortest.NewMockInterface(mockCtrl) 64 cadvisor.EXPECT().MachineInfo().Return(&cadvisorapi.MachineInfo{}, nil).AnyTimes() 65 cadvisor.EXPECT().ImagesFsInfo().Return(cadvisorapiv2.FsInfo{ 66 Usage: 400, 67 Capacity: 1000, 68 Available: 600, 69 }, nil).AnyTimes() 70 cadvisor.EXPECT().RootFsInfo().Return(cadvisorapiv2.FsInfo{ 71 Usage: 9, 72 Capacity: 10, 73 }, nil).AnyTimes() 74 fakeSecretManager := secret.NewFakeManager() 75 fakeConfigMapManager := configmap.NewFakeManager() 76 clusterTrustBundleManager := &clustertrustbundle.NoopManager{} 77 podManager := kubepod.NewBasicPodManager() 78 fakeRuntime := &containertest.FakeRuntime{} 79 podStartupLatencyTracker := kubeletutil.NewPodStartupLatencyTracker() 80 basePath, err := utiltesting.MkTmpdir("kubelet") 81 if err != nil { 82 t.Fatalf("can't make a temp rootdir %v", err) 83 } 84 defer os.RemoveAll(basePath) 85 kb := &Kubelet{ 86 rootDirectory: filepath.Clean(basePath), 87 recorder: &record.FakeRecorder{}, 88 cadvisor: cadvisor, 89 nodeLister: testNodeLister{}, 90 statusManager: status.NewManager(nil, podManager, &statustest.FakePodDeletionSafetyProvider{}, podStartupLatencyTracker, basePath), 91 mirrorPodClient: podtest.NewFakeMirrorClient(), 92 podManager: podManager, 93 podWorkers: &fakePodWorkers{}, 94 os: &containertest.FakeOS{}, 95 containerRuntime: fakeRuntime, 96 reasonCache: NewReasonCache(), 97 clock: clock.RealClock{}, 98 kubeClient: &fake.Clientset{}, 99 hostname: testKubeletHostname, 100 nodeName: testKubeletHostname, 101 runtimeState: newRuntimeState(time.Second), 102 hostutil: hostutil.NewFakeHostUtil(nil), 103 } 104 kb.containerManager = cm.NewStubContainerManager() 105 106 plug := &volumetest.FakeVolumePlugin{PluginName: "fake", Host: nil} 107 kb.volumePluginMgr, err = 108 NewInitializedVolumePluginMgr(kb, fakeSecretManager, fakeConfigMapManager, nil, clusterTrustBundleManager, []volume.VolumePlugin{plug}, nil /* prober */) 109 if err != nil { 110 t.Fatalf("failed to initialize VolumePluginMgr: %v", err) 111 } 112 kb.volumeManager = volumemanager.NewVolumeManager( 113 true, 114 kb.nodeName, 115 kb.podManager, 116 kb.podWorkers, 117 kb.kubeClient, 118 kb.volumePluginMgr, 119 fakeRuntime, 120 kb.mounter, 121 kb.hostutil, 122 kb.getPodsDir(), 123 kb.recorder, 124 false, /* keepTerminatedPodVolumes */ 125 volumetest.NewBlockVolumePathHandler()) 126 127 // TODO: Factor out "stats.Provider" from Kubelet so we don't have a cyclic dependency 128 volumeStatsAggPeriod := time.Second * 10 129 kb.resourceAnalyzer = stats.NewResourceAnalyzer(kb, volumeStatsAggPeriod, kb.recorder) 130 nodeRef := &v1.ObjectReference{ 131 Kind: "Node", 132 Name: string(kb.nodeName), 133 UID: types.UID(kb.nodeName), 134 Namespace: "", 135 } 136 fakeKillPodFunc := func(pod *v1.Pod, evict bool, gracePeriodOverride *int64, fn func(*v1.PodStatus)) error { 137 return nil 138 } 139 evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock, kb.supportLocalStorageCapacityIsolation()) 140 141 kb.evictionManager = evictionManager 142 kb.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler) 143 kb.mounter = mount.NewFakeMounter(nil) 144 if err := kb.setupDataDirs(); err != nil { 145 t.Errorf("Failed to init data dirs: %v", err) 146 } 147 148 pods := []*v1.Pod{ 149 { 150 ObjectMeta: metav1.ObjectMeta{ 151 UID: "12345678", 152 Name: "foo", 153 Namespace: "new", 154 }, 155 Spec: v1.PodSpec{ 156 Containers: []v1.Container{ 157 {Name: "bar"}, 158 }, 159 }, 160 }, 161 } 162 podManager.SetPods(pods) 163 // The original test here is totally meaningless, because fakeruntime will always return an empty podStatus. While 164 // the original logic of isPodRunning happens to return true when podstatus is empty, so the test can always pass. 165 // Now the logic in isPodRunning is changed, to let the test pass, we set the podstatus directly in fake runtime. 166 // This is also a meaningless test, because the isPodRunning will also always return true after setting this. However, 167 // because runonce is never used in kubernetes now, we should deprioritize the cleanup work. 168 // TODO(random-liu) Fix the test, make it meaningful. 169 fakeRuntime.PodStatus = kubecontainer.PodStatus{ 170 ContainerStatuses: []*kubecontainer.Status{ 171 { 172 Name: "bar", 173 State: kubecontainer.ContainerStateRunning, 174 }, 175 }, 176 } 177 results, err := kb.runOnce(ctx, pods, time.Millisecond) 178 if err != nil { 179 t.Errorf("unexpected error: %v", err) 180 } 181 if results[0].Err != nil { 182 t.Errorf("unexpected run pod error: %v", results[0].Err) 183 } 184 if results[0].Pod.Name != "foo" { 185 t.Errorf("unexpected pod: %q", results[0].Pod.Name) 186 } 187 }