k8s.io/kubernetes@v1.29.3/test/e2e/node/examples.go (about) 1 /* 2 Copyright 2015 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 node 18 19 import ( 20 "context" 21 "fmt" 22 "path/filepath" 23 "sync" 24 "time" 25 26 rbacv1 "k8s.io/api/rbac/v1" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 "k8s.io/apimachinery/pkg/runtime/schema" 29 "k8s.io/apiserver/pkg/authentication/serviceaccount" 30 clientset "k8s.io/client-go/kubernetes" 31 podutil "k8s.io/kubernetes/pkg/api/v1/pod" 32 commonutils "k8s.io/kubernetes/test/e2e/common" 33 "k8s.io/kubernetes/test/e2e/feature" 34 "k8s.io/kubernetes/test/e2e/framework" 35 e2eauth "k8s.io/kubernetes/test/e2e/framework/auth" 36 e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl" 37 e2epod "k8s.io/kubernetes/test/e2e/framework/pod" 38 e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output" 39 e2etestfiles "k8s.io/kubernetes/test/e2e/framework/testfiles" 40 admissionapi "k8s.io/pod-security-admission/api" 41 42 "github.com/onsi/ginkgo/v2" 43 ) 44 45 const ( 46 serverStartTimeout = framework.PodStartTimeout + 3*time.Minute 47 ) 48 49 var _ = SIGDescribe(feature.Example, func() { 50 f := framework.NewDefaultFramework("examples") 51 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline 52 53 var c clientset.Interface 54 var ns string 55 ginkgo.BeforeEach(func(ctx context.Context) { 56 c = f.ClientSet 57 ns = f.Namespace.Name 58 59 // this test wants powerful permissions. Since the namespace names are unique, we can leave this 60 // lying around so we don't have to race any caches 61 err := e2eauth.BindClusterRoleInNamespace(ctx, c.RbacV1(), "edit", f.Namespace.Name, 62 rbacv1.Subject{Kind: rbacv1.ServiceAccountKind, Namespace: f.Namespace.Name, Name: "default"}) 63 framework.ExpectNoError(err) 64 65 err = e2eauth.WaitForAuthorizationUpdate(ctx, c.AuthorizationV1(), 66 serviceaccount.MakeUsername(f.Namespace.Name, "default"), 67 f.Namespace.Name, "create", schema.GroupResource{Resource: "pods"}, true) 68 framework.ExpectNoError(err) 69 }) 70 71 ginkgo.Describe("Liveness", func() { 72 ginkgo.It("liveness pods should be automatically restarted", func(ctx context.Context) { 73 test := "test/fixtures/doc-yaml/user-guide/liveness" 74 execYaml := readFile(test, "exec-liveness.yaml.in") 75 httpYaml := readFile(test, "http-liveness.yaml.in") 76 77 e2ekubectl.RunKubectlOrDieInput(ns, execYaml, "create", "-f", "-") 78 e2ekubectl.RunKubectlOrDieInput(ns, httpYaml, "create", "-f", "-") 79 80 // Since both containers start rapidly, we can easily run this test in parallel. 81 var wg sync.WaitGroup 82 passed := true 83 checkRestart := func(podName string, timeout time.Duration) { 84 err := e2epod.WaitForPodNameRunningInNamespace(ctx, c, podName, ns) 85 framework.ExpectNoError(err) 86 for t := time.Now(); time.Since(t) < timeout; time.Sleep(framework.Poll) { 87 pod, err := c.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{}) 88 framework.ExpectNoError(err, fmt.Sprintf("getting pod %s", podName)) 89 stat := podutil.GetExistingContainerStatus(pod.Status.ContainerStatuses, podName) 90 framework.Logf("Pod: %s, restart count:%d", stat.Name, stat.RestartCount) 91 if stat.RestartCount > 0 { 92 framework.Logf("Saw %v restart, succeeded...", podName) 93 wg.Done() 94 return 95 } 96 } 97 framework.Logf("Failed waiting for %v restart! ", podName) 98 passed = false 99 wg.Done() 100 } 101 102 ginkgo.By("Check restarts") 103 104 // Start the "actual test", and wait for both pods to complete. 105 // If 2 fail: Something is broken with the test (or maybe even with liveness). 106 // If 1 fails: Its probably just an error in the examples/ files themselves. 107 wg.Add(2) 108 for _, c := range []string{"liveness-http", "liveness-exec"} { 109 go checkRestart(c, 2*time.Minute) 110 } 111 wg.Wait() 112 if !passed { 113 framework.Failf("At least one liveness example failed. See the logs above.") 114 } 115 }) 116 }) 117 118 ginkgo.Describe("Secret", func() { 119 ginkgo.It("should create a pod that reads a secret", func(ctx context.Context) { 120 test := "test/fixtures/doc-yaml/user-guide/secrets" 121 secretYaml := readFile(test, "secret.yaml") 122 podYaml := readFile(test, "secret-pod.yaml.in") 123 124 podName := "secret-test-pod" 125 126 ginkgo.By("creating secret and pod") 127 e2ekubectl.RunKubectlOrDieInput(ns, secretYaml, "create", "-f", "-") 128 e2ekubectl.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") 129 err := e2epod.WaitForPodNoLongerRunningInNamespace(ctx, c, podName, ns) 130 framework.ExpectNoError(err) 131 132 ginkgo.By("checking if secret was read correctly") 133 _, err = e2eoutput.LookForStringInLog(ns, "secret-test-pod", "test-container", "value-1", serverStartTimeout) 134 framework.ExpectNoError(err) 135 }) 136 }) 137 138 ginkgo.Describe("Downward API", func() { 139 ginkgo.It("should create a pod that prints his name and namespace", func(ctx context.Context) { 140 test := "test/fixtures/doc-yaml/user-guide/downward-api" 141 podYaml := readFile(test, "dapi-pod.yaml.in") 142 podName := "dapi-test-pod" 143 144 ginkgo.By("creating the pod") 145 e2ekubectl.RunKubectlOrDieInput(ns, podYaml, "create", "-f", "-") 146 err := e2epod.WaitForPodNoLongerRunningInNamespace(ctx, c, podName, ns) 147 framework.ExpectNoError(err) 148 149 ginkgo.By("checking if name and namespace were passed correctly") 150 _, err = e2eoutput.LookForStringInLog(ns, podName, "test-container", fmt.Sprintf("MY_POD_NAMESPACE=%v", ns), serverStartTimeout) 151 framework.ExpectNoError(err) 152 _, err = e2eoutput.LookForStringInLog(ns, podName, "test-container", fmt.Sprintf("MY_POD_NAME=%v", podName), serverStartTimeout) 153 framework.ExpectNoError(err) 154 }) 155 }) 156 }) 157 158 func readFile(test, file string) string { 159 from := filepath.Join(test, file) 160 data, err := e2etestfiles.Read(from) 161 if err != nil { 162 framework.Fail(err.Error()) 163 } 164 return commonutils.SubstituteImageName(string(data)) 165 }