|
|
|
|
@ -137,6 +137,82 @@ func TestSchedulerCancelCtx(t *testing.T) {
|
|
|
|
|
<-jobDone
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSchedulerWaitOnRunningJobs(t *testing.T) {
|
|
|
|
|
// do not use t.Parallel() since it relies on the sys eventer
|
|
|
|
|
require := require.New(t)
|
|
|
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
|
|
|
wrapper := db.TestWrapper(t)
|
|
|
|
|
iam.TestRepo(t, conn, wrapper)
|
|
|
|
|
event.TestEnableEventing(t, true)
|
|
|
|
|
testConfig := event.DefaultEventerConfig()
|
|
|
|
|
testLock := &sync.Mutex{}
|
|
|
|
|
testLogger := hclog.New(&hclog.LoggerOptions{
|
|
|
|
|
Mutex: testLock,
|
|
|
|
|
})
|
|
|
|
|
err := event.InitSysEventer(testLogger, testLock, "TestSchedulerWorkflow", event.WithEventerConfig(testConfig))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
sched := TestScheduler(t, conn, wrapper, WithRunJobsLimit(10), WithRunJobsInterval(time.Second), WithMonitorInterval(time.Second))
|
|
|
|
|
|
|
|
|
|
jobReady := make(chan struct{})
|
|
|
|
|
finishJob := make(chan struct{})
|
|
|
|
|
fn := func(ctx context.Context) error {
|
|
|
|
|
jobReady <- struct{}{}
|
|
|
|
|
<-finishJob
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tj := testJob{name: "name", description: "desc", fn: fn, nextRunIn: time.Hour}
|
|
|
|
|
err = sched.RegisterJob(context.Background(), tj)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
baseCtx, baseCnl := context.WithCancel(context.Background())
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
err = sched.Start(baseCtx, &wg)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
waiting := make(chan struct{})
|
|
|
|
|
go func() {
|
|
|
|
|
defer close(waiting)
|
|
|
|
|
wg.Wait()
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
// Wait for scheduler to run job
|
|
|
|
|
<-jobReady
|
|
|
|
|
|
|
|
|
|
// Verify waitGroup is still waiting
|
|
|
|
|
select {
|
|
|
|
|
case <-waiting:
|
|
|
|
|
t.Fatal("expected waitgroup to be waiting")
|
|
|
|
|
default:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Cancel base context
|
|
|
|
|
baseCnl()
|
|
|
|
|
|
|
|
|
|
// Sleep to propagate context cancel
|
|
|
|
|
time.Sleep(250 * time.Millisecond)
|
|
|
|
|
|
|
|
|
|
// Verify waitGroup is still waiting
|
|
|
|
|
select {
|
|
|
|
|
case <-waiting:
|
|
|
|
|
t.Fatal("expected waitgroup to be waiting")
|
|
|
|
|
default:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
finishJob <- struct{}{}
|
|
|
|
|
|
|
|
|
|
// Sleep to ensure job finish is registered
|
|
|
|
|
time.Sleep(250 * time.Millisecond)
|
|
|
|
|
|
|
|
|
|
// Now that job has finished, verify waitGroup is no longer waiting
|
|
|
|
|
select {
|
|
|
|
|
case <-waiting:
|
|
|
|
|
default:
|
|
|
|
|
t.Fatal("expected waitgroup to no longer be waiting")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestSchedulerInterruptedCancelCtx(t *testing.T) {
|
|
|
|
|
// do not use t.Parallel() since it relies on the sys eventer
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
@ -259,7 +335,13 @@ func TestSchedulerJobProgress(t *testing.T) {
|
|
|
|
|
sched := TestScheduler(t, conn, wrapper, WithRunJobsLimit(10), WithRunJobsInterval(time.Second), WithMonitorInterval(time.Second))
|
|
|
|
|
|
|
|
|
|
jobReady := make(chan struct{})
|
|
|
|
|
done := make(chan struct{})
|
|
|
|
|
fn := func(ctx context.Context) error {
|
|
|
|
|
select {
|
|
|
|
|
case <-done:
|
|
|
|
|
return nil
|
|
|
|
|
default:
|
|
|
|
|
}
|
|
|
|
|
jobReady <- struct{}{}
|
|
|
|
|
<-ctx.Done()
|
|
|
|
|
return nil
|
|
|
|
|
@ -268,6 +350,11 @@ func TestSchedulerJobProgress(t *testing.T) {
|
|
|
|
|
statusRequest := make(chan struct{})
|
|
|
|
|
jobStatus := make(chan JobStatus)
|
|
|
|
|
status := func() JobStatus {
|
|
|
|
|
select {
|
|
|
|
|
case <-done:
|
|
|
|
|
return JobStatus{}
|
|
|
|
|
default:
|
|
|
|
|
}
|
|
|
|
|
statusRequest <- struct{}{}
|
|
|
|
|
return <-jobStatus
|
|
|
|
|
}
|
|
|
|
|
@ -332,7 +419,9 @@ func TestSchedulerJobProgress(t *testing.T) {
|
|
|
|
|
assert.Equal(uint32(10), run.CompletedCount)
|
|
|
|
|
|
|
|
|
|
baseCnl()
|
|
|
|
|
// unblock goroutines waiting on channels
|
|
|
|
|
// Close done to bypass future job run / job status requests that will block on channels
|
|
|
|
|
close(done)
|
|
|
|
|
// unblock existing goroutines waiting on channels
|
|
|
|
|
jobStatus <- JobStatus{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|