113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
package scheduler
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/jonboulle/clockwork"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/goleak"
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
"gitlab.com/slon/shad-go/distbuild/pkg/api"
|
|
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
|
)
|
|
|
|
const (
|
|
workerID0 api.WorkerID = "w0"
|
|
)
|
|
|
|
func TestScheduler(t *testing.T) {
|
|
defer goleak.VerifyNone(t)
|
|
|
|
clock := clockwork.NewFakeClock()
|
|
timeAfter = clock.After
|
|
defer func() { timeAfter = time.After }()
|
|
|
|
config := Config{
|
|
CacheTimeout: time.Second,
|
|
DepsTimeout: time.Minute,
|
|
}
|
|
|
|
t.Run("SingleJob", func(t *testing.T) {
|
|
s := NewScheduler(zaptest.NewLogger(t), config)
|
|
|
|
job0 := &build.Job{ID: build.NewID()}
|
|
pendingJob0 := s.ScheduleJob(job0)
|
|
|
|
s.RegisterWorker(workerID0)
|
|
pickerJob := s.PickJob(workerID0, nil)
|
|
|
|
require.Equal(t, pendingJob0, pickerJob)
|
|
|
|
result := &api.JobResult{ID: job0.ID, ExitCode: 0}
|
|
s.OnJobComplete(workerID0, job0.ID, result)
|
|
|
|
select {
|
|
case <-pendingJob0.Finished:
|
|
require.Equal(t, pendingJob0.Result, result)
|
|
|
|
default:
|
|
t.Fatalf("job0 is not finished")
|
|
}
|
|
})
|
|
|
|
t.Run("PickJobTimeout", func(t *testing.T) {
|
|
s := NewScheduler(zaptest.NewLogger(t), config)
|
|
|
|
canceled := make(chan struct{})
|
|
close(canceled)
|
|
|
|
s.RegisterWorker(workerID0)
|
|
require.Nil(t, s.PickJob(workerID0, canceled))
|
|
})
|
|
|
|
t.Run("CacheLocalScheduling", func(t *testing.T) {
|
|
s := NewScheduler(zaptest.NewLogger(t), config)
|
|
|
|
job0 := &build.Job{ID: build.NewID()}
|
|
job1 := &build.Job{ID: build.NewID()}
|
|
|
|
s.RegisterWorker(workerID0)
|
|
s.OnJobComplete(workerID0, job0.ID, &api.JobResult{})
|
|
|
|
pendingJob1 := s.ScheduleJob(job1)
|
|
pendingJob0 := s.ScheduleJob(job0)
|
|
|
|
// job0 scheduling should be blocked on CacheTimeout
|
|
clock.BlockUntil(1)
|
|
|
|
pickedJob := s.PickJob(workerID0, nil)
|
|
require.Equal(t, pendingJob0, pickedJob)
|
|
|
|
pickedJob = s.PickJob(workerID0, nil)
|
|
require.Equal(t, pendingJob1, pickedJob)
|
|
|
|
clock.Advance(time.Hour)
|
|
})
|
|
|
|
t.Run("DependencyLocalScheduling", func(t *testing.T) {
|
|
s := NewScheduler(zaptest.NewLogger(t), config)
|
|
|
|
job0 := &build.Job{ID: build.NewID()}
|
|
job1 := &build.Job{ID: build.NewID(), Deps: []build.ID{job0.ID}}
|
|
job2 := &build.Job{ID: build.NewID()}
|
|
|
|
s.RegisterWorker(workerID0)
|
|
s.OnJobComplete(workerID0, job0.ID, &api.JobResult{})
|
|
|
|
pendingJob2 := s.ScheduleJob(job2)
|
|
pendingJob1 := s.ScheduleJob(job1)
|
|
|
|
// job1 should be blocked on DepsTimeout
|
|
clock.BlockUntil(1)
|
|
|
|
pickedJob := s.PickJob(workerID0, nil)
|
|
require.Equal(t, pendingJob1, pickedJob)
|
|
|
|
pickedJob = s.PickJob(workerID0, nil)
|
|
require.Equal(t, pendingJob2, pickedJob)
|
|
|
|
clock.Advance(time.Hour)
|
|
})
|
|
}
|