github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/cronjob/cronjob_test.go (about)

     1  package cronjob_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/kyma-incubator/compass/components/director/pkg/cronjob"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestCronJob(t *testing.T) {
    13  	const (
    14  		maxCronJobRuns        = 10 // Used for safeguarding the tests in case of infinite loop
    15  		defaultSchedulePeriod = time.Nanosecond
    16  	)
    17  
    18  	testCases := []struct {
    19  		Name                string
    20  		FnBody              func(executionsCount int, cancel context.CancelFunc)
    21  		ExpectedCronJobRuns int
    22  		SchedulePeriod      time.Duration
    23  	}{
    24  		{
    25  			Name:                "Should run cronJob until the context end",
    26  			ExpectedCronJobRuns: 3,
    27  			FnBody: func(executionsCount int, cancelCtx context.CancelFunc) {
    28  				if executionsCount == 3 {
    29  					cancelCtx()
    30  				}
    31  			},
    32  			SchedulePeriod: defaultSchedulePeriod,
    33  		},
    34  		{
    35  			Name: "Should not schedule next cronJob in parallel if execution takes more than the wait period",
    36  
    37  			ExpectedCronJobRuns: 1,
    38  			FnBody: func(executionsCount int, cancelCtx context.CancelFunc) {
    39  				<-time.After(defaultSchedulePeriod * 2)
    40  				cancelCtx()
    41  			},
    42  			SchedulePeriod: defaultSchedulePeriod,
    43  		},
    44  		{
    45  			Name:                "Should schedule next cronJob if execution takes more than the wait period",
    46  			ExpectedCronJobRuns: 3,
    47  			FnBody: func(executionsCount int, cancelCtx context.CancelFunc) {
    48  				<-time.After(defaultSchedulePeriod * 2)
    49  				if executionsCount == 3 {
    50  					cancelCtx()
    51  				}
    52  			},
    53  			SchedulePeriod: defaultSchedulePeriod,
    54  		},
    55  		{
    56  			Name:                "Should stop schedule immediately if context is canceled during waiting",
    57  			ExpectedCronJobRuns: 1,
    58  			FnBody: func(executionsCount int, cancelCtx context.CancelFunc) {
    59  				// give some time for the function to exit and the CronJob to start waiting for the next execution
    60  				time.AfterFunc(time.Millisecond*5, func() {
    61  					cancelCtx()
    62  				})
    63  			},
    64  			SchedulePeriod: time.Minute,
    65  		},
    66  	}
    67  
    68  	for _, testCase := range testCases {
    69  		t.Run(testCase.Name, func(t *testing.T) {
    70  			cronJob := cronjob.CronJob{
    71  				Name:           testCase.Name,
    72  				SchedulePeriod: testCase.SchedulePeriod,
    73  			}
    74  			cronJobRuns := 0
    75  			ctx, cancel := context.WithCancel(context.Background())
    76  
    77  			cronJob.Fn = func(ctx context.Context) {
    78  				cronJobRuns += 1
    79  				if cronJobRuns == maxCronJobRuns {
    80  					cancel()
    81  				} else {
    82  					testCase.FnBody(cronJobRuns, cancel)
    83  				}
    84  			}
    85  			err := cronjob.RunCronJob(ctx, cronjob.ElectionConfig{ElectionEnabled: false}, cronJob)
    86  			assert.NoError(t, err)
    87  
    88  			assert.Equal(t, cronJobRuns, testCase.ExpectedCronJobRuns)
    89  		})
    90  	}
    91  }