volcano.sh/volcano@v1.9.0/pkg/controllers/job/job_controller_actions_test.go (about)

     1  /*
     2  Copyright 2019 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 job
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"fmt"
    23  	"github.com/agiledragon/gomonkey/v2"
    24  	v1 "k8s.io/api/core/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"reflect"
    27  	"testing"
    28  
    29  	"volcano.sh/apis/pkg/apis/batch/v1alpha1"
    30  	schedulingapi "volcano.sh/apis/pkg/apis/scheduling/v1beta1"
    31  	"volcano.sh/volcano/pkg/controllers/apis"
    32  	"volcano.sh/volcano/pkg/controllers/job/state"
    33  )
    34  
    35  func TestKillJobFunc(t *testing.T) {
    36  	namespace := "test"
    37  
    38  	testcases := []struct {
    39  		Name           string
    40  		Job            *v1alpha1.Job
    41  		PodGroup       *schedulingapi.PodGroup
    42  		PodRetainPhase state.PhaseMap
    43  		UpdateStatus   state.UpdateStatusFn
    44  		JobInfo        *apis.JobInfo
    45  		Services       []v1.Service
    46  		ConfigMaps     []v1.ConfigMap
    47  		Secrets        []v1.Secret
    48  		Pods           map[string]*v1.Pod
    49  		Plugins        []string
    50  		ExpectVal      error
    51  	}{
    52  		{
    53  			Name: "KillJob success Case",
    54  			Job: &v1alpha1.Job{
    55  				ObjectMeta: metav1.ObjectMeta{
    56  					Name:            "job1",
    57  					Namespace:       namespace,
    58  					UID:             "e7f18111-1cec-11ea-b688-fa163ec79500",
    59  					ResourceVersion: "100",
    60  				},
    61  			},
    62  			PodGroup: &schedulingapi.PodGroup{
    63  				ObjectMeta: metav1.ObjectMeta{
    64  					Name:      "job1-e7f18111-1cec-11ea-b688-fa163ec79500",
    65  					Namespace: namespace,
    66  				},
    67  			},
    68  			PodRetainPhase: state.PodRetainPhaseNone,
    69  			UpdateStatus:   nil,
    70  			JobInfo: &apis.JobInfo{
    71  				Namespace: namespace,
    72  				Name:      "jobinfo1",
    73  				Pods: map[string]map[string]*v1.Pod{
    74  					"task1": {
    75  						"pod1": buildPod(namespace, "pod1", v1.PodRunning, nil),
    76  						"pod2": buildPod(namespace, "pod2", v1.PodRunning, nil),
    77  					},
    78  				},
    79  			},
    80  			Services: []v1.Service{
    81  				{
    82  					ObjectMeta: metav1.ObjectMeta{
    83  						Name:      "job1",
    84  						Namespace: namespace,
    85  					},
    86  				},
    87  			},
    88  			Secrets: []v1.Secret{
    89  				{
    90  					ObjectMeta: metav1.ObjectMeta{
    91  						Name:      "job1-e7f18111-1cec-11ea-b688-fa163ec79500-ssh",
    92  						Namespace: namespace,
    93  					},
    94  				},
    95  			},
    96  			Pods: map[string]*v1.Pod{
    97  				"pod1": buildPod(namespace, "pod1", v1.PodRunning, nil),
    98  				"pod2": buildPod(namespace, "pod2", v1.PodRunning, nil),
    99  			},
   100  			Plugins:   []string{"svc", "ssh", "env"},
   101  			ExpectVal: nil,
   102  		},
   103  	}
   104  
   105  	for i, testcase := range testcases {
   106  
   107  		t.Run(testcase.Name, func(t *testing.T) {
   108  			fakeController := newFakeController()
   109  			jobPlugins := make(map[string][]string)
   110  
   111  			for _, service := range testcase.Services {
   112  				_, err := fakeController.kubeClient.CoreV1().Services(namespace).Create(context.TODO(), &service, metav1.CreateOptions{})
   113  				if err != nil {
   114  					t.Error("Error While Creating Service")
   115  				}
   116  			}
   117  
   118  			for _, secret := range testcase.Secrets {
   119  				_, err := fakeController.kubeClient.CoreV1().Secrets(namespace).Create(context.TODO(), &secret, metav1.CreateOptions{})
   120  				if err != nil {
   121  					t.Error("Error While Creating Secret.")
   122  				}
   123  			}
   124  
   125  			for _, pod := range testcase.Pods {
   126  				_, err := fakeController.kubeClient.CoreV1().Pods(namespace).Create(context.TODO(), pod, metav1.CreateOptions{})
   127  				if err != nil {
   128  					t.Error("Error While Creating ConfigMaps")
   129  				}
   130  			}
   131  
   132  			_, err := fakeController.vcClient.BatchV1alpha1().Jobs(namespace).Create(context.TODO(), testcase.Job, metav1.CreateOptions{})
   133  			if err != nil {
   134  				t.Error("Error While Creating Jobs")
   135  			}
   136  			err = fakeController.cache.Add(testcase.Job)
   137  			if err != nil {
   138  				t.Error("Error While Adding Job in cache")
   139  			}
   140  
   141  			for _, plugin := range testcase.Plugins {
   142  				jobPlugins[plugin] = make([]string, 0)
   143  			}
   144  
   145  			testcase.JobInfo.Job = testcase.Job
   146  			testcase.JobInfo.Job.Spec.Plugins = jobPlugins
   147  
   148  			testcase.JobInfo.Job.Status.ControlledResources = map[string]string{}
   149  			for _, name := range testcase.Plugins {
   150  				testcase.JobInfo.Job.Status.ControlledResources["plugin-"+name] = name
   151  			}
   152  
   153  			err = fakeController.killJob(testcase.JobInfo, testcase.PodRetainPhase, testcase.UpdateStatus)
   154  			if err != nil {
   155  				t.Errorf("Case %d (%s): expected: No Error, but got error %v.", i, testcase.Name, err)
   156  			}
   157  
   158  			for _, plugin := range testcase.Plugins {
   159  
   160  				if plugin == "svc" {
   161  					_, err = fakeController.kubeClient.CoreV1().Services(namespace).Get(context.TODO(), testcase.Job.Name, metav1.GetOptions{})
   162  					if err == nil {
   163  						t.Errorf("Case %d (%s): expected: Service to be deleted, but not deleted.", i, testcase.Name)
   164  					}
   165  				}
   166  
   167  				if plugin == "ssh" {
   168  					_, err := fakeController.kubeClient.CoreV1().ConfigMaps(namespace).Get(context.TODO(),
   169  						fmt.Sprintf("%s-%s-%s", testcase.Job.Name, testcase.Job.UID, "ssh"), metav1.GetOptions{})
   170  					if err == nil {
   171  						t.Errorf("Case %d (%s): expected: Secret to be deleted, but not deleted.", i, testcase.Name)
   172  					}
   173  				}
   174  			}
   175  		})
   176  	}
   177  }
   178  
   179  func TestSyncJobFunc(t *testing.T) {
   180  	namespace := "test"
   181  
   182  	testcases := []struct {
   183  		Name           string
   184  		Job            *v1alpha1.Job
   185  		PodGroup       *schedulingapi.PodGroup
   186  		PodRetainPhase state.PhaseMap
   187  		UpdateStatus   state.UpdateStatusFn
   188  		JobInfo        *apis.JobInfo
   189  		Pods           map[string]*v1.Pod
   190  		Plugins        []string
   191  		TotalNumPods   int
   192  		ExpectVal      error
   193  	}{
   194  		{
   195  			Name: "SyncJob success Case",
   196  			Job: &v1alpha1.Job{
   197  				ObjectMeta: metav1.ObjectMeta{
   198  					Name:            "job1",
   199  					Namespace:       namespace,
   200  					ResourceVersion: "100",
   201  					UID:             "e7f18111-1cec-11ea-b688-fa163ec79500",
   202  				},
   203  				Spec: v1alpha1.JobSpec{
   204  					Tasks: []v1alpha1.TaskSpec{
   205  						{
   206  							Name:     "task1",
   207  							Replicas: 6,
   208  							Template: v1.PodTemplateSpec{
   209  								ObjectMeta: metav1.ObjectMeta{
   210  									Name:      "pods",
   211  									Namespace: namespace,
   212  								},
   213  								Spec: v1.PodSpec{
   214  									Containers: []v1.Container{
   215  										{
   216  											Name: "Containers",
   217  										},
   218  									},
   219  								},
   220  							},
   221  						},
   222  					},
   223  				},
   224  				Status: v1alpha1.JobStatus{
   225  					State: v1alpha1.JobState{
   226  						Phase: v1alpha1.Pending,
   227  					},
   228  				},
   229  			},
   230  			PodGroup: &schedulingapi.PodGroup{
   231  				ObjectMeta: metav1.ObjectMeta{
   232  					Name:      "job1-e7f18111-1cec-11ea-b688-fa163ec79500",
   233  					Namespace: namespace,
   234  				},
   235  				Spec: schedulingapi.PodGroupSpec{
   236  					MinResources:  &v1.ResourceList{},
   237  					MinTaskMember: map[string]int32{},
   238  				},
   239  				Status: schedulingapi.PodGroupStatus{
   240  					Phase: schedulingapi.PodGroupInqueue,
   241  				},
   242  			},
   243  			PodRetainPhase: state.PodRetainPhaseNone,
   244  			UpdateStatus:   nil,
   245  			JobInfo: &apis.JobInfo{
   246  				Namespace: namespace,
   247  				Name:      "jobinfo1",
   248  				Pods: map[string]map[string]*v1.Pod{
   249  					"task1": {
   250  						"job1-task1-0": buildPod(namespace, "job1-task1-0", v1.PodRunning, nil),
   251  						"job1-task1-1": buildPod(namespace, "job1-task1-1", v1.PodRunning, nil),
   252  					},
   253  				},
   254  			},
   255  			Pods: map[string]*v1.Pod{
   256  				"job1-task1-0": buildPod(namespace, "job1-task1-0", v1.PodRunning, nil),
   257  				"job1-task1-1": buildPod(namespace, "job1-task1-1", v1.PodRunning, nil),
   258  			},
   259  			TotalNumPods: 6,
   260  			Plugins:      []string{"svc", "ssh", "env"},
   261  			ExpectVal:    nil,
   262  		},
   263  		{
   264  			Name: "SyncJob with dependsOn job can't find the dependent task",
   265  			/*
   266  				Work dependsOn Master task, preempt actions causes controller deadlock
   267  				   controller                master,work             scheduler
   268  				       |                           |  <---preempt-----  |
   269  				       |                           |  <---kill work---  |
   270  				       | ----watch work kill---->  |                    |
   271  					   |                           |  <---kill master-- |
   272  				       | ----create work pods--->  |                    |
   273  				       | --wait master running-->  |                    |
   274  				       |                           |                    |
   275  					   | ---watch master kill--->  |                    |
   276  				       | --push master to queue->  |                    |
   277  				       | -wait process to create-> |                    |
   278  			*/
   279  			Job: &v1alpha1.Job{
   280  				ObjectMeta: metav1.ObjectMeta{
   281  					Name:            "job1",
   282  					Namespace:       namespace,
   283  					ResourceVersion: "100",
   284  					UID:             "e7f18111-1cec-11ea-b688-fa163ec79500",
   285  				},
   286  				Spec: v1alpha1.JobSpec{
   287  					Tasks: []v1alpha1.TaskSpec{
   288  						{
   289  							Name:     "master",
   290  							Replicas: 1,
   291  							Template: v1.PodTemplateSpec{
   292  								ObjectMeta: metav1.ObjectMeta{
   293  									Name:      "pods",
   294  									Namespace: namespace,
   295  								},
   296  								Spec: v1.PodSpec{
   297  									Containers: []v1.Container{
   298  										{
   299  											Name: "Containers",
   300  										},
   301  									},
   302  								},
   303  							},
   304  						},
   305  						{
   306  							Name:     "work",
   307  							Replicas: 3,
   308  							Template: v1.PodTemplateSpec{
   309  								ObjectMeta: metav1.ObjectMeta{
   310  									Name:      "pods",
   311  									Namespace: namespace,
   312  								},
   313  								Spec: v1.PodSpec{
   314  									Containers: []v1.Container{
   315  										{
   316  											Name: "Containers",
   317  										},
   318  									},
   319  								},
   320  							},
   321  							DependsOn: &v1alpha1.DependsOn{
   322  								Name: []string{"master"},
   323  							},
   324  						},
   325  					},
   326  				},
   327  				Status: v1alpha1.JobStatus{
   328  					State: v1alpha1.JobState{
   329  						Phase: v1alpha1.Pending,
   330  					},
   331  				},
   332  			},
   333  			PodGroup: &schedulingapi.PodGroup{
   334  				ObjectMeta: metav1.ObjectMeta{
   335  					Name:      "job1-e7f18111-1cec-11ea-b688-fa163ec79500",
   336  					Namespace: namespace,
   337  				},
   338  				Spec: schedulingapi.PodGroupSpec{
   339  					MinResources:  &v1.ResourceList{},
   340  					MinTaskMember: map[string]int32{},
   341  				},
   342  				Status: schedulingapi.PodGroupStatus{
   343  					Phase: schedulingapi.PodGroupInqueue,
   344  				},
   345  			},
   346  			PodRetainPhase: state.PodRetainPhaseNone,
   347  			UpdateStatus:   nil,
   348  			JobInfo: &apis.JobInfo{
   349  				Namespace: namespace,
   350  				Name:      "jobinfo1",
   351  				Pods: map[string]map[string]*v1.Pod{
   352  					"work": {
   353  						"job1-work-0": buildPod(namespace, "job1-work-0", v1.PodRunning, nil),
   354  						"job1-work-1": buildPod(namespace, "job1-work-1", v1.PodRunning, nil),
   355  					},
   356  				},
   357  			},
   358  			Pods: map[string]*v1.Pod{
   359  				"job1-work-0": buildPod(namespace, "job1-work-0", v1.PodRunning, nil),
   360  				"job1-work-1": buildPod(namespace, "job1-work-1", v1.PodRunning, nil),
   361  			},
   362  			TotalNumPods: 4,
   363  			Plugins:      []string{"svc", "ssh", "env"},
   364  			ExpectVal:    nil,
   365  		},
   366  	}
   367  	for i, testcase := range testcases {
   368  
   369  		t.Run(testcase.Name, func(t *testing.T) {
   370  			fakeController := newFakeController()
   371  
   372  			patches := gomonkey.ApplyMethod(reflect.TypeOf(fakeController), "GetQueueInfo", func(_ *jobcontroller, _ string) (*schedulingapi.Queue, error) {
   373  				return &schedulingapi.Queue{}, nil
   374  			})
   375  
   376  			defer patches.Reset()
   377  
   378  			jobPlugins := make(map[string][]string)
   379  
   380  			for _, plugin := range testcase.Plugins {
   381  				jobPlugins[plugin] = make([]string, 0)
   382  			}
   383  			testcase.JobInfo.Job = testcase.Job
   384  			testcase.JobInfo.Job.Spec.Plugins = jobPlugins
   385  
   386  			fakeController.pgInformer.Informer().GetIndexer().Add(testcase.PodGroup)
   387  			fakeController.vcClient.SchedulingV1beta1().PodGroups(testcase.PodGroup.Namespace).Create(context.TODO(), testcase.PodGroup, metav1.CreateOptions{})
   388  
   389  			for _, pod := range testcase.Pods {
   390  				_, err := fakeController.kubeClient.CoreV1().Pods(namespace).Create(context.TODO(), pod, metav1.CreateOptions{})
   391  				if err != nil {
   392  					t.Error("Error While Creating pods")
   393  				}
   394  			}
   395  
   396  			_, err := fakeController.vcClient.BatchV1alpha1().Jobs(namespace).Create(context.TODO(), testcase.Job, metav1.CreateOptions{})
   397  			if err != nil {
   398  				t.Errorf("Expected no Error while creating job, but got error: %s", err)
   399  			}
   400  
   401  			err = fakeController.cache.Add(testcase.Job)
   402  			if err != nil {
   403  				t.Error("Error While Adding Job in cache")
   404  			}
   405  
   406  			err = fakeController.syncJob(testcase.JobInfo, nil)
   407  			if err != testcase.ExpectVal {
   408  				t.Errorf("Expected no error while syncing job, but got error: %s", err)
   409  			}
   410  
   411  			podList, err := fakeController.kubeClient.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{})
   412  			if err != nil {
   413  				t.Errorf("Expected no error while listing pods, but got error %s in case %d", err, i)
   414  			}
   415  			if testcase.TotalNumPods != len(podList.Items) {
   416  				t.Errorf("Expected Total number of pods to be same as podlist count: Expected: %d, Got: %d in case: %d", testcase.TotalNumPods, len(podList.Items), i)
   417  			}
   418  		})
   419  	}
   420  }
   421  
   422  func TestCreateJobIOIfNotExistFunc(t *testing.T) {
   423  	namespace := "test"
   424  
   425  	testcases := []struct {
   426  		Name      string
   427  		Job       *v1alpha1.Job
   428  		ExpextVal error
   429  	}{
   430  		{
   431  			Name: "Create Job IO case",
   432  			Job: &v1alpha1.Job{
   433  				ObjectMeta: metav1.ObjectMeta{
   434  					Name:            "job1",
   435  					Namespace:       namespace,
   436  					ResourceVersion: "100",
   437  				},
   438  				Spec: v1alpha1.JobSpec{
   439  					Volumes: []v1alpha1.VolumeSpec{
   440  						{
   441  							VolumeClaimName: "pvc1",
   442  						},
   443  					},
   444  				},
   445  			},
   446  			ExpextVal: errors.New("pvc pvc1 is not found, the job will be in the Pending state until the PVC is created"),
   447  		},
   448  	}
   449  
   450  	for i, testcase := range testcases {
   451  
   452  		t.Run(testcase.Name, func(t *testing.T) {
   453  			fakeController := newFakeController()
   454  
   455  			job, err := fakeController.createJobIOIfNotExist(testcase.Job)
   456  			if testcase.ExpextVal == nil {
   457  				if err != nil {
   458  					t.Errorf("Expected Return value to be : %v, but got: %v in testcase %d", testcase.ExpextVal, err, i)
   459  				}
   460  			} else {
   461  				if err == nil || err.Error() != testcase.ExpextVal.Error() {
   462  					t.Errorf("Expected Return value to be : %v, but got: %v in testcase %d", testcase.ExpextVal.Error(), err.Error(), i)
   463  				}
   464  			}
   465  
   466  			if len(job.Spec.Volumes) == 0 {
   467  				t.Errorf("Expected number of volumes to be greater than 0 but got: %d in case: %d", len(job.Spec.Volumes), i)
   468  			}
   469  		})
   470  	}
   471  }
   472  
   473  func TestCreatePVCFunc(t *testing.T) {
   474  	namespace := "test"
   475  
   476  	testcases := []struct {
   477  		Name        string
   478  		Job         *v1alpha1.Job
   479  		VolumeClaim *v1.PersistentVolumeClaimSpec
   480  		ExpextVal   error
   481  	}{
   482  		{
   483  			Name: "CreatePVC success Case",
   484  			Job: &v1alpha1.Job{
   485  				ObjectMeta: metav1.ObjectMeta{
   486  					Name:            "job1",
   487  					Namespace:       namespace,
   488  					ResourceVersion: "100",
   489  				},
   490  			},
   491  			VolumeClaim: &v1.PersistentVolumeClaimSpec{
   492  				VolumeName: "vol1",
   493  			},
   494  			ExpextVal: nil,
   495  		},
   496  	}
   497  
   498  	for _, testcase := range testcases {
   499  		t.Run(testcase.Name, func(t *testing.T) {
   500  			fakeController := newFakeController()
   501  
   502  			err := fakeController.createPVC(testcase.Job, "pvc1", testcase.VolumeClaim)
   503  			if err != testcase.ExpextVal {
   504  				t.Errorf("Expected return value to be equal to expected: %s, but got: %s", testcase.ExpextVal, err)
   505  			}
   506  			_, err = fakeController.kubeClient.CoreV1().PersistentVolumeClaims(namespace).Get(context.TODO(), "pvc1", metav1.GetOptions{})
   507  			if err != nil {
   508  				t.Error("Expected PVC to get created, but not created")
   509  			}
   510  		})
   511  	}
   512  }
   513  
   514  func TestCreatePodGroupIfNotExistFunc(t *testing.T) {
   515  	namespace := "test"
   516  
   517  	testcases := []struct {
   518  		Name      string
   519  		Job       *v1alpha1.Job
   520  		ExpextVal error
   521  	}{
   522  		{
   523  			Name: "CreatePodGroup success Case",
   524  			Job: &v1alpha1.Job{
   525  				ObjectMeta: metav1.ObjectMeta{
   526  					Namespace:       namespace,
   527  					Name:            "job1",
   528  					ResourceVersion: "100",
   529  					UID:             "e7f18111-1cec-11ea-b688-fa163ec79500",
   530  				},
   531  			},
   532  			ExpextVal: nil,
   533  		},
   534  	}
   535  
   536  	for _, testcase := range testcases {
   537  		t.Run(testcase.Name, func(t *testing.T) {
   538  			fakeController := newFakeController()
   539  
   540  			err := fakeController.createOrUpdatePodGroup(testcase.Job)
   541  			if err != testcase.ExpextVal {
   542  				t.Errorf("Expected return value to be equal to expected: %s, but got: %s", testcase.ExpextVal, err)
   543  			}
   544  
   545  			pgName := testcase.Job.Name + "-" + string(testcase.Job.UID)
   546  			_, err = fakeController.vcClient.SchedulingV1beta1().PodGroups(namespace).Get(context.TODO(), pgName, metav1.GetOptions{})
   547  			if err != nil {
   548  				t.Error("Expected PodGroup to get created, but not created")
   549  			}
   550  		})
   551  
   552  	}
   553  }
   554  
   555  func TestUpdatePodGroupIfJobUpdateFunc(t *testing.T) {
   556  	namespace := "test"
   557  
   558  	testcases := []struct {
   559  		Name      string
   560  		PodGroup  *schedulingapi.PodGroup
   561  		Job       *v1alpha1.Job
   562  		ExpectVal error
   563  	}{
   564  		{
   565  			Name: "UpdatePodGroup success Case",
   566  			PodGroup: &schedulingapi.PodGroup{
   567  				ObjectMeta: metav1.ObjectMeta{
   568  					Namespace: namespace,
   569  					Name:      "job1-e7f18111-1cec-11ea-b688-fa163ec79500",
   570  				},
   571  				Spec: schedulingapi.PodGroupSpec{
   572  					MinResources: &v1.ResourceList{},
   573  				},
   574  			},
   575  			Job: &v1alpha1.Job{
   576  				ObjectMeta: metav1.ObjectMeta{
   577  					Namespace:       namespace,
   578  					Name:            "job1",
   579  					ResourceVersion: "100",
   580  					UID:             "e7f18111-1cec-11ea-b688-fa163ec79500",
   581  				},
   582  				Spec: v1alpha1.JobSpec{
   583  					PriorityClassName: "new",
   584  				},
   585  			},
   586  			ExpectVal: nil,
   587  		},
   588  	}
   589  
   590  	for _, testcase := range testcases {
   591  		t.Run(testcase.Name, func(t *testing.T) {
   592  			fakeController := newFakeController()
   593  			fakeController.pgInformer.Informer().GetIndexer().Add(testcase.PodGroup)
   594  			fakeController.vcClient.SchedulingV1beta1().PodGroups(testcase.PodGroup.Namespace).Create(context.TODO(), testcase.PodGroup, metav1.CreateOptions{})
   595  
   596  			err := fakeController.createOrUpdatePodGroup(testcase.Job)
   597  			if err != testcase.ExpectVal {
   598  				t.Errorf("Expected return value to be equal to expected: %s, but got: %s", testcase.ExpectVal, err)
   599  			}
   600  
   601  			pgName := testcase.Job.Name + "-" + string(testcase.Job.UID)
   602  			pg, err := fakeController.vcClient.SchedulingV1beta1().PodGroups(namespace).Get(context.TODO(), pgName, metav1.GetOptions{})
   603  			if err != nil {
   604  				t.Error("Expected PodGroup to be created, but not created")
   605  			}
   606  			if pg.Spec.PriorityClassName != testcase.Job.Spec.PriorityClassName {
   607  				t.Errorf("Expected PodGroup.Spec.PriorityClassName to be updated to: %s, but got: %s", testcase.Job.Spec.PriorityClassName, pg.Spec.PriorityClassName)
   608  			}
   609  
   610  		})
   611  
   612  	}
   613  
   614  }
   615  
   616  func TestDeleteJobPod(t *testing.T) {
   617  	namespace := "test"
   618  
   619  	testcases := []struct {
   620  		Name      string
   621  		Job       *v1alpha1.Job
   622  		Pods      map[string]*v1.Pod
   623  		DeletePod *v1.Pod
   624  		ExpextVal error
   625  	}{
   626  		{
   627  			Name: "DeleteJobPod success case",
   628  			Job: &v1alpha1.Job{
   629  				ObjectMeta: metav1.ObjectMeta{
   630  					Name:            "job1",
   631  					Namespace:       namespace,
   632  					ResourceVersion: "100",
   633  				},
   634  			},
   635  			Pods: map[string]*v1.Pod{
   636  				"job1-task1-0": buildPod(namespace, "job1-task1-0", v1.PodRunning, nil),
   637  				"job1-task1-1": buildPod(namespace, "job1-task1-1", v1.PodRunning, nil),
   638  			},
   639  			DeletePod: buildPod(namespace, "job1-task1-0", v1.PodRunning, nil),
   640  			ExpextVal: nil,
   641  		},
   642  	}
   643  
   644  	for _, testcase := range testcases {
   645  		t.Run(testcase.Name, func(t *testing.T) {
   646  			fakeController := newFakeController()
   647  
   648  			for _, pod := range testcase.Pods {
   649  				_, err := fakeController.kubeClient.CoreV1().Pods(namespace).Create(context.TODO(), pod, metav1.CreateOptions{})
   650  				if err != nil {
   651  					t.Error("Expected error not to occur")
   652  				}
   653  			}
   654  
   655  			err := fakeController.deleteJobPod(testcase.Job.Name, testcase.DeletePod)
   656  			if err != testcase.ExpextVal {
   657  				t.Errorf("Expected return value to be equal to expected: %s, but got: %s", testcase.ExpextVal, err)
   658  			}
   659  
   660  			_, err = fakeController.kubeClient.CoreV1().Pods(namespace).Get(context.TODO(), "job1-task1-0", metav1.GetOptions{})
   661  			if err == nil {
   662  				t.Error("Expected Pod to be deleted but not deleted")
   663  			}
   664  		})
   665  	}
   666  }