volcano.sh/volcano@v1.9.0/test/e2e/vcctl/command.go (about)

     1  /*
     2  Copyright 2021 The Volcano 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 vcctl
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"fmt"
    23  
    24  	. "github.com/onsi/ginkgo/v2"
    25  	. "github.com/onsi/gomega"
    26  
    27  	v1 "k8s.io/api/core/v1"
    28  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  
    31  	jobcli "volcano.sh/volcano/pkg/cli/job"
    32  	jobctl "volcano.sh/volcano/pkg/controllers/job"
    33  
    34  	e2eutil "volcano.sh/volcano/test/e2e/util"
    35  )
    36  
    37  var _ = Describe("Job E2E Test: Test Job Command", func() {
    38  	It("List running jobs", func() {
    39  		var outBuffer bytes.Buffer
    40  		jobName := "test-job"
    41  		ctx := e2eutil.InitTestContext(e2eutil.Options{})
    42  		defer e2eutil.CleanupTestContext(ctx)
    43  		rep := e2eutil.ClusterSize(ctx, e2eutil.OneCPU)
    44  
    45  		job := e2eutil.CreateJob(ctx, &e2eutil.JobSpec{
    46  			Namespace: ctx.Namespace,
    47  			Name:      jobName,
    48  			Tasks: []e2eutil.TaskSpec{
    49  				{
    50  					Img: e2eutil.DefaultNginxImage,
    51  					Req: e2eutil.OneCPU,
    52  					Min: rep,
    53  					Rep: rep,
    54  				},
    55  			},
    56  		})
    57  		// Pod is running
    58  		err := e2eutil.WaitJobReady(ctx, job)
    59  		Expect(err).NotTo(HaveOccurred())
    60  		// Job Status is running
    61  		err = e2eutil.WaitJobStateReady(ctx, job)
    62  		Expect(err).NotTo(HaveOccurred())
    63  		// Command outputs are identical
    64  		outputs := ListJobs(ctx.Namespace)
    65  		jobs, err := ctx.Vcclient.BatchV1alpha1().Jobs(ctx.Namespace).List(context.TODO(), metav1.ListOptions{})
    66  		Expect(err).NotTo(HaveOccurred())
    67  		jobcli.PrintJobs(jobs, &outBuffer)
    68  		Expect(outputs).To(Equal(outBuffer.String()), "List command result should be:\n %s",
    69  			outBuffer.String())
    70  	})
    71  
    72  	It("Suspend running job&Resume aborted job", func() {
    73  		jobName := "test-suspend-running-job"
    74  		taskName := "long-live-task"
    75  		ctx := e2eutil.InitTestContext(e2eutil.Options{})
    76  		defer e2eutil.CleanupTestContext(ctx)
    77  
    78  		job := e2eutil.CreateJob(ctx, &e2eutil.JobSpec{
    79  			Namespace: ctx.Namespace,
    80  			Name:      jobName,
    81  			Tasks: []e2eutil.TaskSpec{
    82  				{
    83  					Name: taskName,
    84  					Img:  e2eutil.DefaultNginxImage,
    85  					Min:  1,
    86  					Rep:  1,
    87  				},
    88  			},
    89  		})
    90  		// Job is running
    91  		err := e2eutil.WaitJobReady(ctx, job)
    92  		Expect(err).NotTo(HaveOccurred())
    93  		err = e2eutil.WaitJobStateReady(ctx, job)
    94  		Expect(err).NotTo(HaveOccurred())
    95  
    96  		// Suspend job and wait status change
    97  		SuspendJob(jobName, ctx.Namespace)
    98  		err = e2eutil.WaitJobStateAborted(ctx, job)
    99  		Expect(err).NotTo(HaveOccurred())
   100  
   101  		// Pod is gone
   102  		podName := jobctl.MakePodName(jobName, taskName, 0)
   103  		err = e2eutil.WaitPodGone(ctx, podName, job.Namespace)
   104  		Expect(err).NotTo(HaveOccurred())
   105  
   106  		// Resume job
   107  		ResumeJob(jobName, ctx.Namespace)
   108  
   109  		// Job is running again
   110  		err = e2eutil.WaitJobReady(ctx, job)
   111  		Expect(err).NotTo(HaveOccurred())
   112  		err = e2eutil.WaitJobStateReady(ctx, job)
   113  		Expect(err).NotTo(HaveOccurred())
   114  
   115  	})
   116  
   117  	It("Suspend pending job", func() {
   118  		ctx := e2eutil.InitTestContext(e2eutil.Options{})
   119  		defer e2eutil.CleanupTestContext(ctx)
   120  		rep := e2eutil.ClusterSize(ctx, e2eutil.OneCPU)
   121  
   122  		jobName := "test-suspend-pending-job"
   123  		taskName := "long-live-task"
   124  
   125  		job := e2eutil.CreateJob(ctx, &e2eutil.JobSpec{
   126  			Namespace: ctx.Namespace,
   127  			Name:      jobName,
   128  			Tasks: []e2eutil.TaskSpec{
   129  				{
   130  					Name: taskName,
   131  					Img:  e2eutil.DefaultNginxImage,
   132  					Req:  e2eutil.CPUResource(fmt.Sprintf("%dm", 1000*rep)),
   133  					Min:  1,
   134  					Rep:  1,
   135  				},
   136  			},
   137  		})
   138  
   139  		// Job is pending
   140  		err := e2eutil.WaitJobPending(ctx, job)
   141  		Expect(err).NotTo(HaveOccurred())
   142  		err = e2eutil.WaitJobStatePending(ctx, job)
   143  		Expect(err).NotTo(HaveOccurred())
   144  
   145  		// Suspend job and wait status change
   146  		SuspendJob(jobName, ctx.Namespace)
   147  		err = e2eutil.WaitJobStateAborted(ctx, job)
   148  		Expect(err).NotTo(HaveOccurred())
   149  
   150  		// Pod is gone
   151  		podName := jobctl.MakePodName(jobName, taskName, 0)
   152  		_, err = ctx.Kubeclient.CoreV1().Pods(ctx.Namespace).Get(context.TODO(), podName, metav1.GetOptions{})
   153  		Expect(apierrors.IsNotFound(err)).To(BeTrue(),
   154  			"Job related pod should be deleted when job aborted.")
   155  	})
   156  
   157  	It("delete a job with all nodes taints", func() {
   158  
   159  		jobName := "test-del-job"
   160  		ctx := e2eutil.InitTestContext(e2eutil.Options{})
   161  		defer e2eutil.CleanupTestContext(ctx)
   162  		rep := e2eutil.ClusterSize(ctx, e2eutil.OneCPU)
   163  
   164  		taints := []v1.Taint{
   165  			{
   166  				Key:    "test-taint-key",
   167  				Value:  "test-taint-val",
   168  				Effect: v1.TaintEffectNoSchedule,
   169  			},
   170  		}
   171  
   172  		err := e2eutil.TaintAllNodes(ctx, taints)
   173  		Expect(err).NotTo(HaveOccurred())
   174  
   175  		job := e2eutil.CreateJob(ctx, &e2eutil.JobSpec{
   176  			Namespace: ctx.Namespace,
   177  			Name:      jobName,
   178  			Tasks: []e2eutil.TaskSpec{
   179  				{
   180  					Img: e2eutil.DefaultNginxImage,
   181  					Req: e2eutil.OneCPU,
   182  					Min: rep / 2,
   183  					Rep: rep,
   184  				},
   185  			},
   186  		})
   187  
   188  		err = e2eutil.WaitJobPending(ctx, job)
   189  		Expect(err).NotTo(HaveOccurred())
   190  
   191  		err = e2eutil.RemoveTaintsFromAllNodes(ctx, taints)
   192  		Expect(err).NotTo(HaveOccurred())
   193  
   194  		// Pod is running
   195  		err = e2eutil.WaitJobReady(ctx, job)
   196  		Expect(err).NotTo(HaveOccurred())
   197  		// Job Status is running
   198  		err = e2eutil.WaitJobStateReady(ctx, job)
   199  		Expect(err).NotTo(HaveOccurred())
   200  
   201  		_, err = ctx.Vcclient.BatchV1alpha1().Jobs(ctx.Namespace).Get(context.TODO(), jobName, metav1.GetOptions{})
   202  		Expect(err).NotTo(HaveOccurred())
   203  
   204  		// Delete job
   205  		DeleteJob(jobName, ctx.Namespace)
   206  
   207  		_, err = ctx.Vcclient.BatchV1alpha1().Jobs(ctx.Namespace).Get(context.TODO(), jobName, metav1.GetOptions{})
   208  		Expect(apierrors.IsNotFound(err)).To(BeTrue(),
   209  			"Job should be deleted on vcctl job delete.")
   210  	})
   211  })