From bcf4aafb0bbd21dd6b71d1a288915c54dd28d7ee Mon Sep 17 00:00:00 2001 From: Arinda Arif <79823430+arinda-arif@users.noreply.github.com> Date: Wed, 8 Jan 2025 16:49:12 +0700 Subject: [PATCH] fix: replay endtime validation (#320) * fix: replay end time validation issue * test: fix failed test case in deployment service --- .../service/deployment_service_test.go | 2 +- core/scheduler/service/replay_validator.go | 12 ++++-- .../service/replay_validator_test.go | 42 ++++++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/core/scheduler/service/deployment_service_test.go b/core/scheduler/service/deployment_service_test.go index c016eafef4..0d7588619a 100644 --- a/core/scheduler/service/deployment_service_test.go +++ b/core/scheduler/service/deployment_service_test.go @@ -340,7 +340,7 @@ func TestDeploymentService(t *testing.T) { defer mScheduler.AssertExpectations(t) runService := service.NewJobRunService(logger, jobRepo, nil, nil, nil, - mScheduler, priorityResolver, nil, nil, nil, nil) + mScheduler, priorityResolver, nil, nil, nil) err := runService.UploadJobs(ctx, tnnt1, jobNamesToUpload, jobNamesToDelete) assert.ErrorContains(t, err, upstreamErr) diff --git a/core/scheduler/service/replay_validator.go b/core/scheduler/service/replay_validator.go index 64e9fdf1bb..4021286abb 100644 --- a/core/scheduler/service/replay_validator.go +++ b/core/scheduler/service/replay_validator.go @@ -43,10 +43,16 @@ func (v Validator) validateDateRange(ctx context.Context, replayRequest *schedul jobLogicalStartDate := jobSpec.Schedule.StartDate.UTC() jobScheduleStartDate := jobCron.Next(jobLogicalStartDate) - // time bound for end date - if jobSpec.Schedule.EndDate != nil && replayEndDate.After(jobSpec.Schedule.EndDate.UTC()) { - return errors.NewError(errors.ErrFailedPrecond, scheduler.EntityReplay, fmt.Sprintf("replay end date (%s) is not allowed to be set after the job end date (%s)", replayEndDate.String(), jobSpec.Schedule.EndDate.UTC().String())) + if jobSpec.Schedule.EndDate != nil { + jobLogicalEndDate := jobSpec.Schedule.EndDate.UTC() + jobScheduleEndDate := jobCron.Next(jobLogicalEndDate) + + // time bound for end date + if replayEndDate.After(jobScheduleEndDate.UTC()) { + return errors.NewError(errors.ErrFailedPrecond, scheduler.EntityReplay, fmt.Sprintf("replay end date (%s) is not allowed to be set after the job scheduled end date (%s)", replayEndDate.String(), jobScheduleEndDate.UTC().String())) + } } + currentTime := time.Now().UTC() if replayEndDate.After(currentTime) { return errors.NewError(errors.ErrFailedPrecond, scheduler.EntityReplay, fmt.Sprintf("replay end date (%s) is not allowed to be set to a future date, current time: (%s)", replayEndDate.String(), currentTime.String())) diff --git a/core/scheduler/service/replay_validator_test.go b/core/scheduler/service/replay_validator_test.go index 65694604f2..7ea363741c 100644 --- a/core/scheduler/service/replay_validator_test.go +++ b/core/scheduler/service/replay_validator_test.go @@ -109,7 +109,7 @@ func TestReplayValidator(t *testing.T) { jobRepository := new(JobRepository) defer jobRepository.AssertExpectations(t) - schEndTime := jobEndTime.Add(-1 * time.Second) + schEndTime := jobEndTime.Add(-25 * time.Hour) jobRepository.On("GetJobDetails", ctx, replayReq.Tenant().ProjectName(), replayReq.JobName()).Return(&scheduler.JobWithDetails{ Schedule: &scheduler.Schedule{ StartDate: jobStartTime, @@ -121,6 +121,46 @@ func TestReplayValidator(t *testing.T) { err := validator.Validate(ctx, replayReq, jobCron) assert.ErrorContains(t, err, "replay end date") }) + t.Run("should not return error if replay end date equals to job's end_date scheduled date", func(t *testing.T) { + replayRepository := new(ReplayRepository) + defer replayRepository.AssertExpectations(t) + + sch := new(mockReplayScheduler) + defer sch.AssertExpectations(t) + + jobRepository := new(JobRepository) + defer jobRepository.AssertExpectations(t) + + jobAStartTimeStr := "2023-01-02T12:00:00Z" + jobAStartTime, _ := time.Parse(scheduler.ISODateFormat, jobAStartTimeStr) + jobAEndTime := jobAStartTime.Add(48 * time.Hour) + jobAEndScheduledTime := jobAEndTime.Add(24 * time.Hour) + + replayJobAStartTime := jobCron.Next(jobStartTime) + replayJobAEndTime := jobAEndScheduledTime + + replayJobAConfig := scheduler.NewReplayConfig(replayJobAStartTime, replayJobAEndTime, parallel, replayJobConfig, description) + replayJobAReq := scheduler.NewReplayRequest(jobName, tnnt, replayJobAConfig, scheduler.ReplayStateCreated) + + replayJobARunsCriteria := &scheduler.JobRunsCriteria{ + Name: jobName.String(), + StartDate: replayJobAStartTime, + EndDate: replayJobAEndTime, + } + + jobRepository.On("GetJobDetails", ctx, replayReq.Tenant().ProjectName(), replayReq.JobName()).Return(&scheduler.JobWithDetails{ + Schedule: &scheduler.Schedule{ + StartDate: jobStartTime, + EndDate: &jobAEndTime, + }, + }, nil) + replayRepository.On("GetReplayRequestsByStatus", ctx, replayStatusToValidate).Return(nil, nil) + sch.On("GetJobRuns", ctx, tnnt, replayJobARunsCriteria, jobCron).Return(nil, nil) + + validator := service.NewValidator(replayRepository, sch, jobRepository) + err := validator.Validate(ctx, replayJobAReq, jobCron) + assert.NoError(t, err) + }) t.Run("should return error if conflict replay found", func(t *testing.T) { replayRepository := new(ReplayRepository) defer replayRepository.AssertExpectations(t)