k8s.io/kubernetes@v1.29.3/test/e2e/apimachinery/generated_clientset.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 apimachinery
    18  
    19  import (
    20  	"context"
    21  	"strconv"
    22  	"time"
    23  
    24  	batchv1 "k8s.io/api/batch/v1"
    25  	v1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/labels"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  	"k8s.io/apimachinery/pkg/util/intstr"
    30  	"k8s.io/apimachinery/pkg/util/uuid"
    31  	"k8s.io/apimachinery/pkg/watch"
    32  	"k8s.io/kubernetes/test/e2e/framework"
    33  	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
    34  	imageutils "k8s.io/kubernetes/test/utils/image"
    35  	admissionapi "k8s.io/pod-security-admission/api"
    36  
    37  	"github.com/onsi/ginkgo/v2"
    38  	"github.com/onsi/gomega"
    39  )
    40  
    41  func testingPod(name, value string) v1.Pod {
    42  	return v1.Pod{
    43  		ObjectMeta: metav1.ObjectMeta{
    44  			Name: name,
    45  			Labels: map[string]string{
    46  				"name": "foo",
    47  				"time": value,
    48  			},
    49  		},
    50  		Spec: v1.PodSpec{
    51  			Containers: []v1.Container{
    52  				{
    53  					Name:  "nginx",
    54  					Image: imageutils.GetE2EImage(imageutils.Nginx),
    55  					Ports: []v1.ContainerPort{{ContainerPort: 80}},
    56  					LivenessProbe: &v1.Probe{
    57  						ProbeHandler: v1.ProbeHandler{
    58  							HTTPGet: &v1.HTTPGetAction{
    59  								Path: "/index.html",
    60  								Port: intstr.FromInt32(8080),
    61  							},
    62  						},
    63  						InitialDelaySeconds: 30,
    64  					},
    65  				},
    66  			},
    67  		},
    68  	}
    69  }
    70  
    71  func observeCreation(w watch.Interface) {
    72  	select {
    73  	case event := <-w.ResultChan():
    74  		if event.Type != watch.Added {
    75  			framework.Failf("Failed to observe the creation: %v", event)
    76  		}
    77  	case <-time.After(30 * time.Second):
    78  		framework.Failf("Timeout while waiting for observing the creation")
    79  	}
    80  }
    81  
    82  func observerUpdate(w watch.Interface, expectedUpdate func(runtime.Object) bool) {
    83  	timer := time.After(30 * time.Second)
    84  	updated := false
    85  	timeout := false
    86  	for !updated && !timeout {
    87  		select {
    88  		case event := <-w.ResultChan():
    89  			if event.Type == watch.Modified {
    90  				if expectedUpdate(event.Object) {
    91  					updated = true
    92  				}
    93  			}
    94  		case <-timer:
    95  			timeout = true
    96  		}
    97  	}
    98  	if !updated {
    99  		framework.Failf("Failed to observe pod update")
   100  	}
   101  }
   102  
   103  var _ = SIGDescribe("Generated clientset", func() {
   104  	f := framework.NewDefaultFramework("clientset")
   105  	f.NamespacePodSecurityEnforceLevel = admissionapi.LevelBaseline
   106  	ginkgo.It("should create pods, set the deletionTimestamp and deletionGracePeriodSeconds of the pod", func(ctx context.Context) {
   107  		podClient := f.ClientSet.CoreV1().Pods(f.Namespace.Name)
   108  		ginkgo.By("constructing the pod")
   109  		name := "pod" + string(uuid.NewUUID())
   110  		value := strconv.Itoa(time.Now().Nanosecond())
   111  		podCopy := testingPod(name, value)
   112  		pod := &podCopy
   113  		ginkgo.By("setting up watch")
   114  		selector := labels.SelectorFromSet(labels.Set(map[string]string{"time": value})).String()
   115  		options := metav1.ListOptions{LabelSelector: selector}
   116  		pods, err := podClient.List(ctx, options)
   117  		if err != nil {
   118  			framework.Failf("Failed to query for pods: %v", err)
   119  		}
   120  		gomega.Expect(pods.Items).To(gomega.BeEmpty())
   121  		options = metav1.ListOptions{
   122  			LabelSelector:   selector,
   123  			ResourceVersion: pods.ListMeta.ResourceVersion,
   124  		}
   125  		w, err := podClient.Watch(ctx, options)
   126  		if err != nil {
   127  			framework.Failf("Failed to set up watch: %v", err)
   128  		}
   129  
   130  		ginkgo.By("creating the pod")
   131  		pod, err = podClient.Create(ctx, pod, metav1.CreateOptions{})
   132  		if err != nil {
   133  			framework.Failf("Failed to create pod: %v", err)
   134  		}
   135  
   136  		ginkgo.By("verifying the pod is in kubernetes")
   137  		options = metav1.ListOptions{
   138  			LabelSelector:   selector,
   139  			ResourceVersion: pod.ResourceVersion,
   140  		}
   141  		pods, err = podClient.List(ctx, options)
   142  		if err != nil {
   143  			framework.Failf("Failed to query for pods: %v", err)
   144  		}
   145  		gomega.Expect(pods.Items).To(gomega.HaveLen(1))
   146  
   147  		ginkgo.By("verifying pod creation was observed")
   148  		observeCreation(w)
   149  
   150  		// We need to wait for the pod to be scheduled, otherwise the deletion
   151  		// will be carried out immediately rather than gracefully.
   152  		framework.ExpectNoError(e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name))
   153  
   154  		ginkgo.By("deleting the pod gracefully")
   155  		gracePeriod := int64(31)
   156  		if err := podClient.Delete(ctx, pod.Name, *metav1.NewDeleteOptions(gracePeriod)); err != nil {
   157  			framework.Failf("Failed to delete pod: %v", err)
   158  		}
   159  
   160  		ginkgo.By("verifying the deletionTimestamp and deletionGracePeriodSeconds of the pod is set")
   161  		observerUpdate(w, func(obj runtime.Object) bool {
   162  			pod := obj.(*v1.Pod)
   163  			return pod.ObjectMeta.DeletionTimestamp != nil && *pod.ObjectMeta.DeletionGracePeriodSeconds == gracePeriod
   164  		})
   165  	})
   166  })
   167  
   168  func newTestingCronJob(name string, value string) *batchv1.CronJob {
   169  	parallelism := int32(1)
   170  	completions := int32(1)
   171  	return &batchv1.CronJob{
   172  		ObjectMeta: metav1.ObjectMeta{
   173  			Name: name,
   174  			Labels: map[string]string{
   175  				"time": value,
   176  			},
   177  		},
   178  		Spec: batchv1.CronJobSpec{
   179  			Schedule:          "*/1 * * * ?",
   180  			ConcurrencyPolicy: batchv1.AllowConcurrent,
   181  			JobTemplate: batchv1.JobTemplateSpec{
   182  				Spec: batchv1.JobSpec{
   183  					Parallelism: &parallelism,
   184  					Completions: &completions,
   185  					Template: v1.PodTemplateSpec{
   186  						Spec: v1.PodSpec{
   187  							RestartPolicy: v1.RestartPolicyOnFailure,
   188  							Volumes: []v1.Volume{
   189  								{
   190  									Name: "data",
   191  									VolumeSource: v1.VolumeSource{
   192  										EmptyDir: &v1.EmptyDirVolumeSource{},
   193  									},
   194  								},
   195  							},
   196  							Containers: []v1.Container{
   197  								{
   198  									Name:  "c",
   199  									Image: imageutils.GetE2EImage(imageutils.BusyBox),
   200  									VolumeMounts: []v1.VolumeMount{
   201  										{
   202  											MountPath: "/data",
   203  											Name:      "data",
   204  										},
   205  									},
   206  								},
   207  							},
   208  						},
   209  					},
   210  				},
   211  			},
   212  		},
   213  	}
   214  }
   215  
   216  var _ = SIGDescribe("Generated clientset", func() {
   217  	f := framework.NewDefaultFramework("clientset")
   218  	f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged
   219  
   220  	ginkgo.It("should create v1 cronJobs, delete cronJobs, watch cronJobs", func(ctx context.Context) {
   221  		cronJobClient := f.ClientSet.BatchV1().CronJobs(f.Namespace.Name)
   222  		ginkgo.By("constructing the cronJob")
   223  		name := "cronjob" + string(uuid.NewUUID())
   224  		value := strconv.Itoa(time.Now().Nanosecond())
   225  		cronJob := newTestingCronJob(name, value)
   226  		ginkgo.By("setting up watch")
   227  		selector := labels.SelectorFromSet(labels.Set(map[string]string{"time": value})).String()
   228  		options := metav1.ListOptions{LabelSelector: selector}
   229  		cronJobs, err := cronJobClient.List(ctx, options)
   230  		if err != nil {
   231  			framework.Failf("Failed to query for cronJobs: %v", err)
   232  		}
   233  		gomega.Expect(cronJobs.Items).To(gomega.BeEmpty())
   234  		options = metav1.ListOptions{
   235  			LabelSelector:   selector,
   236  			ResourceVersion: cronJobs.ListMeta.ResourceVersion,
   237  		}
   238  		w, err := cronJobClient.Watch(ctx, options)
   239  		if err != nil {
   240  			framework.Failf("Failed to set up watch: %v", err)
   241  		}
   242  
   243  		ginkgo.By("creating the cronJob")
   244  		cronJob, err = cronJobClient.Create(ctx, cronJob, metav1.CreateOptions{})
   245  		if err != nil {
   246  			framework.Failf("Failed to create cronJob: %v", err)
   247  		}
   248  
   249  		ginkgo.By("verifying the cronJob is in kubernetes")
   250  		options = metav1.ListOptions{
   251  			LabelSelector:   selector,
   252  			ResourceVersion: cronJob.ResourceVersion,
   253  		}
   254  		cronJobs, err = cronJobClient.List(ctx, options)
   255  		if err != nil {
   256  			framework.Failf("Failed to query for cronJobs: %v", err)
   257  		}
   258  		gomega.Expect(cronJobs.Items).To(gomega.HaveLen(1))
   259  
   260  		ginkgo.By("verifying cronJob creation was observed")
   261  		observeCreation(w)
   262  
   263  		ginkgo.By("deleting the cronJob")
   264  		// Use DeletePropagationBackground so the CronJob is really gone when the call returns.
   265  		propagationPolicy := metav1.DeletePropagationBackground
   266  		if err := cronJobClient.Delete(ctx, cronJob.Name, metav1.DeleteOptions{PropagationPolicy: &propagationPolicy}); err != nil {
   267  			framework.Failf("Failed to delete cronJob: %v", err)
   268  		}
   269  
   270  		options = metav1.ListOptions{LabelSelector: selector}
   271  		cronJobs, err = cronJobClient.List(ctx, options)
   272  		if err != nil {
   273  			framework.Failf("Failed to list cronJobs to verify deletion: %v", err)
   274  		}
   275  		gomega.Expect(cronJobs.Items).To(gomega.BeEmpty())
   276  	})
   277  })