volcano.sh/volcano@v1.9.0/pkg/controllers/garbagecollector/garbagecollector_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 garbagecollector
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  	"time"
    23  
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  
    26  	"volcano.sh/apis/pkg/apis/batch/v1alpha1"
    27  	volcanoclient "volcano.sh/apis/pkg/client/clientset/versioned/fake"
    28  	"volcano.sh/volcano/pkg/controllers/framework"
    29  )
    30  
    31  func TestGarbageCollector_ProcessJob(t *testing.T) {
    32  
    33  }
    34  
    35  func TestGarbageCollector_ProcessTTL(t *testing.T) {
    36  	namespace := "test"
    37  	var ttlSecond int32 = 3
    38  	var ttlSecondZero int32
    39  	testcases := []struct {
    40  		Name        string
    41  		Job         *v1alpha1.Job
    42  		ExpectedVal bool
    43  		ExpectedErr error
    44  	}{
    45  		{
    46  			Name: "False Case",
    47  			Job: &v1alpha1.Job{
    48  				ObjectMeta: metav1.ObjectMeta{
    49  					Name:      "job1",
    50  					Namespace: namespace,
    51  				},
    52  				Spec: v1alpha1.JobSpec{
    53  					TTLSecondsAfterFinished: &ttlSecond,
    54  				},
    55  				Status: v1alpha1.JobStatus{
    56  					State: v1alpha1.JobState{
    57  						LastTransitionTime: metav1.NewTime(time.Now()),
    58  						Phase:              v1alpha1.Completed,
    59  					},
    60  				},
    61  			},
    62  			ExpectedVal: false,
    63  			ExpectedErr: nil,
    64  		},
    65  		{
    66  			Name: "True Case",
    67  			Job: &v1alpha1.Job{
    68  				ObjectMeta: metav1.ObjectMeta{
    69  					Name:      "job1",
    70  					Namespace: namespace,
    71  				},
    72  				Spec: v1alpha1.JobSpec{
    73  					TTLSecondsAfterFinished: &ttlSecondZero,
    74  				},
    75  				Status: v1alpha1.JobStatus{
    76  					State: v1alpha1.JobState{
    77  						LastTransitionTime: metav1.NewTime(time.Now()),
    78  						Phase:              v1alpha1.Completed,
    79  					},
    80  				},
    81  			},
    82  			ExpectedVal: true,
    83  			ExpectedErr: nil,
    84  		},
    85  	}
    86  	for i, testcase := range testcases {
    87  		gc := &gccontroller{}
    88  		gc.Initialize(&framework.ControllerOption{
    89  			VolcanoClient: volcanoclient.NewSimpleClientset(),
    90  		})
    91  
    92  		expired, err := gc.processTTL(testcase.Job)
    93  		if err != nil {
    94  			t.Error("Did not expect error")
    95  		}
    96  		if expired != testcase.ExpectedVal {
    97  			t.Errorf("Expected Return Value to be %t, but got %t in case %d", testcase.ExpectedVal, expired, i)
    98  		}
    99  	}
   100  }
   101  
   102  func TestGarbageCollector_NeedsCleanup(t *testing.T) {
   103  	namespace := "test"
   104  
   105  	var ttlSecond int32 = 3
   106  
   107  	testcases := []struct {
   108  		Name        string
   109  		Job         *v1alpha1.Job
   110  		ExpectedVal bool
   111  	}{
   112  		{
   113  			Name: "Success Case",
   114  			Job: &v1alpha1.Job{
   115  				ObjectMeta: metav1.ObjectMeta{
   116  					Name:      "job1",
   117  					Namespace: namespace,
   118  				},
   119  				Spec: v1alpha1.JobSpec{
   120  					TTLSecondsAfterFinished: &ttlSecond,
   121  				},
   122  				Status: v1alpha1.JobStatus{
   123  					State: v1alpha1.JobState{
   124  						Phase: v1alpha1.Completed,
   125  					},
   126  				},
   127  			},
   128  			ExpectedVal: true,
   129  		},
   130  		{
   131  			Name: "Failure Case",
   132  			Job: &v1alpha1.Job{
   133  				ObjectMeta: metav1.ObjectMeta{
   134  					Name:      "job1",
   135  					Namespace: namespace,
   136  				},
   137  				Spec: v1alpha1.JobSpec{
   138  					TTLSecondsAfterFinished: &ttlSecond,
   139  				},
   140  				Status: v1alpha1.JobStatus{
   141  					State: v1alpha1.JobState{
   142  						Phase: v1alpha1.Running,
   143  					},
   144  				},
   145  			},
   146  			ExpectedVal: false,
   147  		},
   148  	}
   149  
   150  	for i, testcase := range testcases {
   151  		finished := needsCleanup(testcase.Job)
   152  		if finished != testcase.ExpectedVal {
   153  			t.Errorf("Expected value to be %t, but got: %t in case %d", testcase.ExpectedVal, finished, i)
   154  		}
   155  	}
   156  }
   157  
   158  func TestGarbageCollector_IsJobFinished(t *testing.T) {
   159  	namespace := "test"
   160  
   161  	testcases := []struct {
   162  		Name        string
   163  		Job         *v1alpha1.Job
   164  		ExpectedVal bool
   165  	}{
   166  		{
   167  			Name: "True Case",
   168  			Job: &v1alpha1.Job{
   169  				ObjectMeta: metav1.ObjectMeta{
   170  					Name:      "job1",
   171  					Namespace: namespace,
   172  				},
   173  				Status: v1alpha1.JobStatus{
   174  					State: v1alpha1.JobState{
   175  						Phase: v1alpha1.Completed,
   176  					},
   177  				},
   178  			},
   179  			ExpectedVal: true,
   180  		},
   181  		{
   182  			Name: "False Case",
   183  			Job: &v1alpha1.Job{
   184  				ObjectMeta: metav1.ObjectMeta{
   185  					Name:      "job1",
   186  					Namespace: namespace,
   187  				},
   188  				Status: v1alpha1.JobStatus{
   189  					State: v1alpha1.JobState{
   190  						Phase: v1alpha1.Running,
   191  					},
   192  				},
   193  			},
   194  			ExpectedVal: false,
   195  		},
   196  	}
   197  
   198  	for i, testcase := range testcases {
   199  		finished := isJobFinished(testcase.Job)
   200  		if finished != testcase.ExpectedVal {
   201  			t.Errorf("Expected value to be %t, but got: %t in case %d", testcase.ExpectedVal, finished, i)
   202  		}
   203  	}
   204  }
   205  
   206  func TestGarbageCollector_GetFinishAndExpireTime(t *testing.T) {
   207  	namespace := "test"
   208  
   209  	var ttlSecond int32 = 3
   210  	var ttlSecondFail int32 = 2
   211  
   212  	testTime := time.Date(1, 1, 1, 1, 1, 1, 0, time.UTC)
   213  
   214  	testcases := []struct {
   215  		Name        string
   216  		Job         *v1alpha1.Job
   217  		ExpectedErr error
   218  	}{
   219  		{
   220  			Name: "Success case",
   221  			Job: &v1alpha1.Job{
   222  				ObjectMeta: metav1.ObjectMeta{
   223  					Name:      "job1",
   224  					Namespace: namespace,
   225  				},
   226  				Spec: v1alpha1.JobSpec{
   227  					TTLSecondsAfterFinished: &ttlSecond,
   228  				},
   229  				Status: v1alpha1.JobStatus{
   230  					State: v1alpha1.JobState{
   231  						Phase:              v1alpha1.Completed,
   232  						LastTransitionTime: metav1.NewTime(testTime),
   233  					},
   234  				},
   235  			},
   236  			ExpectedErr: nil,
   237  		},
   238  		{
   239  			Name: "Failure case",
   240  			Job: &v1alpha1.Job{
   241  				ObjectMeta: metav1.ObjectMeta{
   242  					Name:      "job1",
   243  					Namespace: namespace,
   244  				},
   245  				Spec: v1alpha1.JobSpec{
   246  					TTLSecondsAfterFinished: &ttlSecondFail,
   247  				},
   248  				Status: v1alpha1.JobStatus{
   249  					State: v1alpha1.JobState{
   250  						Phase:              v1alpha1.Completed,
   251  						LastTransitionTime: metav1.NewTime(testTime),
   252  					},
   253  				},
   254  			},
   255  			ExpectedErr: nil,
   256  		},
   257  	}
   258  
   259  	for i, testcase := range testcases {
   260  		finishTime, expireTime, err := getFinishAndExpireTime(testcase.Job)
   261  		if err != nil && err.Error() != testcase.ExpectedErr.Error() {
   262  			t.Errorf("Expected Error to be: %s but got: %s in case %d", testcase.ExpectedErr, err, i)
   263  		}
   264  
   265  		if finishTime != nil && metav1.NewTime(*finishTime) != testcase.Job.Status.State.LastTransitionTime {
   266  			t.Errorf("Expected value to be: %v, but got: %v in case %d", testcase.Job.Status.State.LastTransitionTime, metav1.NewTime(*finishTime), i)
   267  		}
   268  
   269  		if expireTime != nil && metav1.NewTime(*expireTime) != metav1.NewTime(testcase.Job.Status.State.LastTransitionTime.Add(time.Duration(*testcase.Job.Spec.TTLSecondsAfterFinished)*time.Second)) {
   270  			t.Errorf("Expected value to be: %v, but got: %v in case %d", testcase.Job.Status.State.LastTransitionTime.Add(time.Duration(*testcase.Job.Spec.TTLSecondsAfterFinished)*time.Second), metav1.NewTime(*expireTime), i)
   271  		}
   272  	}
   273  }
   274  
   275  func TestGarbageCollector_TimeLeft(t *testing.T) {
   276  	namespace := "test"
   277  
   278  	var ttlSecond int32 = 3
   279  
   280  	testTime := time.Date(1, 1, 1, 1, 1, 1, 0, time.UTC)
   281  
   282  	testcases := []struct {
   283  		Name        string
   284  		Job         *v1alpha1.Job
   285  		Time        *time.Time
   286  		ExpectedVal time.Duration
   287  		ExpectedErr error
   288  	}{
   289  		{
   290  			Name: "Success Case",
   291  			Job: &v1alpha1.Job{
   292  				ObjectMeta: metav1.ObjectMeta{
   293  					Name:      "job1",
   294  					Namespace: namespace,
   295  				},
   296  				Spec: v1alpha1.JobSpec{
   297  					TTLSecondsAfterFinished: &ttlSecond,
   298  				},
   299  				Status: v1alpha1.JobStatus{
   300  					State: v1alpha1.JobState{
   301  						Phase:              v1alpha1.Completed,
   302  						LastTransitionTime: metav1.NewTime(testTime),
   303  					},
   304  				},
   305  			},
   306  			Time:        &testTime,
   307  			ExpectedVal: time.Duration(3),
   308  			ExpectedErr: nil,
   309  		},
   310  		{
   311  			Name: "Failure Case",
   312  			Job: &v1alpha1.Job{
   313  				ObjectMeta: metav1.ObjectMeta{
   314  					Name:      "job1",
   315  					Namespace: namespace,
   316  				},
   317  				Spec: v1alpha1.JobSpec{
   318  					TTLSecondsAfterFinished: &ttlSecond,
   319  				},
   320  				Status: v1alpha1.JobStatus{
   321  					State: v1alpha1.JobState{
   322  						LastTransitionTime: metav1.NewTime(testTime),
   323  					},
   324  				},
   325  			},
   326  			Time:        &testTime,
   327  			ExpectedVal: time.Duration(3),
   328  			ExpectedErr: fmt.Errorf("job %s/%s should not be cleaned up", "test", "job1"),
   329  		},
   330  	}
   331  
   332  	for i, testcase := range testcases {
   333  		timeDuration, err := timeLeft(testcase.Job, testcase.Time)
   334  		if err != nil && err.Error() != testcase.ExpectedErr.Error() {
   335  			t.Errorf("Expected Error to be: %s but got: %s in case %d", testcase.ExpectedErr, err, i)
   336  		}
   337  
   338  		if timeDuration != nil && timeDuration.Seconds() != float64(testcase.ExpectedVal*time.Second)/1e9 {
   339  			t.Errorf("Expected Value to be: %v but got: %f in case %d", testcase.ExpectedVal, timeDuration.Seconds(), i)
   340  		}
   341  	}
   342  }
   343  
   344  func TestGarbageCollector_JobFinishTime(t *testing.T) {
   345  	namespace := "test"
   346  
   347  	testcases := []struct {
   348  		Name        string
   349  		Job         *v1alpha1.Job
   350  		ExpectedVal error
   351  	}{
   352  		{
   353  			Name: "Success Case",
   354  			Job: &v1alpha1.Job{
   355  				ObjectMeta: metav1.ObjectMeta{
   356  					Name:      "job1",
   357  					Namespace: namespace,
   358  				},
   359  				Status: v1alpha1.JobStatus{
   360  					State: v1alpha1.JobState{
   361  						LastTransitionTime: metav1.NewTime(time.Now()),
   362  					},
   363  				},
   364  			},
   365  			ExpectedVal: nil,
   366  		},
   367  		{
   368  			Name: "Failure Case",
   369  			Job: &v1alpha1.Job{
   370  				ObjectMeta: metav1.ObjectMeta{
   371  					Name:      "job1",
   372  					Namespace: namespace,
   373  				},
   374  			},
   375  			ExpectedVal: fmt.Errorf("unable to find the time when the Job %s/%s finished", "test", "job1"),
   376  		},
   377  	}
   378  
   379  	for i, testcase := range testcases {
   380  		_, err := jobFinishTime(testcase.Job)
   381  		if err != nil && err.Error() != testcase.ExpectedVal.Error() {
   382  			t.Errorf("Expected Error to be: %s but got: %s in case %d", testcase.ExpectedVal, err, i)
   383  		}
   384  	}
   385  }