Files
mayfly-go/server/pkg/runner/runner_test.go

149 lines
2.8 KiB
Go
Raw Normal View History

package runner
import (
"context"
"github.com/stretchr/testify/require"
"mayfly-go/pkg/utils/timex"
"sync"
"testing"
"time"
)
var _ Job = &testJob{}
func newTestJob(key string, runTime time.Duration) *testJob {
return &testJob{
deadline: time.Now(),
Key: key,
run: func(ctx context.Context) {
timex.SleepWithContext(ctx, runTime)
},
}
}
type testJob struct {
run RunFunc
Key JobKey
status JobStatus
ran bool
deadline time.Time
}
func (t *testJob) Renew(job Job) {
}
func (t *testJob) GetDeadline() time.Time {
return t.deadline
}
func (t *testJob) Schedule() bool {
return !t.ran
}
func (t *testJob) Run(ctx context.Context) {
if t.run == nil {
return
}
t.run(ctx)
t.ran = true
}
func (t *testJob) Runnable(_ NextFunc) bool {
return true
}
func (t *testJob) GetKey() JobKey {
return t.Key
}
func (t *testJob) GetStatus() JobStatus {
return t.status
}
func (t *testJob) SetStatus(status JobStatus) {
t.status = status
}
func TestRunner_Close(t *testing.T) {
runner := NewRunner[*testJob](1)
signal := make(chan struct{}, 1)
waiting := sync.WaitGroup{}
waiting.Add(1)
go func() {
job := &testJob{
Key: "close",
run: func(ctx context.Context) {
waiting.Done()
timex.SleepWithContext(ctx, time.Hour)
signal <- struct{}{}
},
}
_ = runner.Add(context.Background(), job)
}()
waiting.Wait()
timer := time.NewTimer(time.Microsecond * 10)
runner.Close()
select {
case <-timer.C:
require.FailNow(t, "runner 未能及时退出")
case <-signal:
}
}
func TestRunner_AddJob(t *testing.T) {
type testCase struct {
name string
job *testJob
want bool
}
testCases := []testCase{
{
name: "first job",
job: newTestJob("single", time.Hour),
want: true,
},
{
name: "second job",
job: newTestJob("dual", time.Hour),
want: true,
},
{
name: "non repetitive job",
job: newTestJob("single", time.Hour),
want: true,
},
{
name: "repetitive job",
job: newTestJob("dual", time.Hour),
want: true,
},
}
runner := NewRunner[*testJob](1)
defer runner.Close()
for _, tc := range testCases {
err := runner.Add(context.Background(), tc.job)
require.NoError(t, err)
}
}
func TestJob_UpdateStatus(t *testing.T) {
const d = time.Millisecond * 20
runner := NewRunner[*testJob](1)
running := newTestJob("running", d*2)
waiting := newTestJob("waiting", d*2)
_ = runner.Add(context.Background(), running)
_ = runner.Add(context.Background(), waiting)
time.Sleep(d)
require.Equal(t, JobRunning, running.status)
require.Equal(t, JobWaiting, waiting.status)
time.Sleep(d * 2)
require.Equal(t, JobRemoved, running.status)
require.Equal(t, JobRunning, waiting.status)
time.Sleep(d * 2)
require.Equal(t, JobRemoved, running.status)
require.Equal(t, JobRemoved, waiting.status)
}