...

Source file src/k8s.io/kubernetes/test/e2e/framework/job/fixtures.go

Documentation: k8s.io/kubernetes/test/e2e/framework/job

     1  /*
     2  Copyright 2019 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 job
    18  
    19  import (
    20  	batchv1 "k8s.io/api/batch/v1"
    21  	v1 "k8s.io/api/core/v1"
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  	"k8s.io/apimachinery/pkg/util/rand"
    24  	"k8s.io/kubernetes/test/e2e/framework"
    25  	imageutils "k8s.io/kubernetes/test/utils/image"
    26  	"k8s.io/utils/ptr"
    27  )
    28  
    29  // NewTestJob returns a Job which does one of several testing behaviors. notTerminate starts a Job that will run
    30  // effectively forever. fail starts a Job that will fail immediately. succeed starts a Job that will succeed
    31  // immediately. randomlySucceedOrFail starts a Job that will succeed or fail randomly. failOnce fails the Job the
    32  // first time it is run and succeeds subsequently. name is the Name of the Job. RestartPolicy indicates the restart
    33  // policy of the containers in which the Pod is running. Parallelism is the Job's parallelism, and completions is the
    34  // Job's required number of completions.
    35  func NewTestJob(behavior, name string, rPol v1.RestartPolicy, parallelism, completions int32, activeDeadlineSeconds *int64, backoffLimit int32) *batchv1.Job {
    36  	anyNode := ""
    37  	return NewTestJobOnNode(behavior, name, rPol, parallelism, completions, activeDeadlineSeconds, backoffLimit, anyNode)
    38  }
    39  
    40  // NewTestJobOnNode is similar to NewTestJob but supports specifying a Node on which the Job's Pods will run.
    41  // Empty nodeName means no node selection constraints.
    42  func NewTestJobOnNode(behavior, name string, rPol v1.RestartPolicy, parallelism, completions int32, activeDeadlineSeconds *int64, backoffLimit int32, nodeName string) *batchv1.Job {
    43  	manualSelector := false
    44  	job := &batchv1.Job{
    45  		ObjectMeta: metav1.ObjectMeta{
    46  			Name: name,
    47  		},
    48  		TypeMeta: metav1.TypeMeta{
    49  			Kind: "Job",
    50  		},
    51  		Spec: batchv1.JobSpec{
    52  			ActiveDeadlineSeconds: activeDeadlineSeconds,
    53  			Parallelism:           &parallelism,
    54  			Completions:           &completions,
    55  			BackoffLimit:          &backoffLimit,
    56  			ManualSelector:        &manualSelector,
    57  			Template: v1.PodTemplateSpec{
    58  				ObjectMeta: metav1.ObjectMeta{
    59  					Labels: map[string]string{JobSelectorKey: name},
    60  				},
    61  				Spec: v1.PodSpec{
    62  					RestartPolicy: rPol,
    63  					Volumes: []v1.Volume{
    64  						{
    65  							Name: "data",
    66  							VolumeSource: v1.VolumeSource{
    67  								EmptyDir: &v1.EmptyDirVolumeSource{},
    68  							},
    69  						},
    70  					},
    71  					Containers: []v1.Container{
    72  						{
    73  							Name:    "c",
    74  							Image:   framework.BusyBoxImage,
    75  							Command: []string{},
    76  							VolumeMounts: []v1.VolumeMount{
    77  								{
    78  									MountPath: "/data",
    79  									Name:      "data",
    80  								},
    81  							},
    82  							SecurityContext: &v1.SecurityContext{},
    83  						},
    84  					},
    85  				},
    86  			},
    87  		},
    88  	}
    89  	if len(nodeName) > 0 {
    90  		job.Spec.Template.Spec.NodeSelector = map[string]string{
    91  			"kubernetes.io/hostname": nodeName,
    92  		}
    93  	}
    94  	switch behavior {
    95  	case "neverTerminate":
    96  		// this job is being used in an upgrade job see test/e2e/upgrades/apps/job.go
    97  		// it should never be optimized, as it always has to restart during an upgrade
    98  		// and continue running
    99  		job.Spec.Template.Spec.Containers[0].Command = []string{"sleep", "1000000"}
   100  		job.Spec.Template.Spec.TerminationGracePeriodSeconds = ptr.To(int64(1))
   101  	case "notTerminate":
   102  		job.Spec.Template.Spec.Containers[0].Image = imageutils.GetPauseImageName()
   103  	case "fail":
   104  		job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit 1"}
   105  	case "failOddSucceedEven":
   106  		job.Spec.Template.Spec.Containers[0].Command = []string{"sh", "-c"}
   107  		job.Spec.Template.Spec.Containers[0].Args = []string{`
   108  			if [ $(expr ${JOB_COMPLETION_INDEX} % 2) -ne 0 ]; then
   109  				exit 1
   110  			else
   111  				exit 0
   112  			fi
   113  			`,
   114  		}
   115  	case "succeed":
   116  		job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit 0"}
   117  	case "randomlySucceedOrFail":
   118  		// Bash's $RANDOM generates pseudorandom int in range 0 - 32767.
   119  		// Dividing by 16384 gives roughly 50/50 chance of success.
   120  		job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit $(( $RANDOM / 16384 ))"}
   121  	case "failOnce":
   122  		// Fail the first the container of the pod is run, and
   123  		// succeed the second time. Checks for file on a data volume.
   124  		// If present, succeed.  If not, create but fail.
   125  		// If RestartPolicy is Never, the nodeName should be set to
   126  		// ensure all job pods run on a single node and the volume
   127  		// will be mounted from a hostPath instead.
   128  		setupHostPathDirectory(job)
   129  		job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "if [[ -r /data/foo ]] ; then exit 0 ; else touch /data/foo ; exit 1 ; fi"}
   130  	case "notTerminateOnce":
   131  		// Do not terminate the 0-indexed pod in the first run and
   132  		// succeed the second time. Fail the non-0-indexed pods until
   133  		// the marker file is created by the 0-indexed pod. The fact that
   134  		// the non-0-indexed pods are succeeded is used to determine that the
   135  		// 0th indexed pod already created the marker file.
   136  		setupHostPathDirectory(job)
   137  		job.Spec.Template.Spec.TerminationGracePeriodSeconds = ptr.To(int64(1))
   138  		job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "if [[ -r /data/foo ]] ; then exit 0 ; elif [[ $JOB_COMPLETION_INDEX -eq 0 ]] ; then touch /data/foo ; sleep 1000000 ; else exit 1 ; fi"}
   139  	}
   140  	return job
   141  }
   142  
   143  // setup host path directory to pass information between pod restarts
   144  func setupHostPathDirectory(job *batchv1.Job) {
   145  	if _, nodeNameSpecified := job.Spec.Template.Spec.NodeSelector["kubernetes.io/hostname"]; nodeNameSpecified {
   146  		randomDir := "/tmp/job-e2e/" + rand.String(10)
   147  		hostPathType := v1.HostPathDirectoryOrCreate
   148  		job.Spec.Template.Spec.Volumes[0].VolumeSource = v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{Path: randomDir, Type: &hostPathType}}
   149  		// Tests involving r/w operations on hostPath volume needs to run in
   150  		// privileged mode for SELinux enabled distro, while Windows platform
   151  		// neither supports nor needs privileged mode.
   152  		privileged := !framework.NodeOSDistroIs("windows")
   153  		job.Spec.Template.Spec.Containers[0].SecurityContext.Privileged = &privileged
   154  	}
   155  }
   156  

View as plain text