package scheduler import ( "context" "errors" "testing" "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" ) func TestTask(t *testing.T) { ctx := context.Background() var i int task := NewTask( func(ctx context.Context) (any, error) { i += 1 return nil, nil }, ) task.Run(ctx) assert.Equal(t, nil, task.res) assert.NotEmpty(t, task.updatedAt) assert.Equal(t, 1, i) assert.Equal(t, 1, int(task.GetAttempts())) } func TestAbortTask(t *testing.T) { ctx := context.Background() task := NewTask( func(ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, ) timer := time.NewTicker(200 * time.Millisecond) go func() { <-timer.C task.Abort() }() task.Run(ctx) assert.Equal(t, Abort, task.GetState()) } func TestTaskContextDone(t *testing.T) { ctx, fnCancel := context.WithCancel(context.Background()) task := NewTask( func(ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, ) timer := time.NewTicker(200 * time.Millisecond) go func() { <-timer.C fnCancel() }() task.Run(ctx) assert.Equal(t, Failed, task.GetState()) } func TestTaskFnSuccess(t *testing.T) { ctx := context.Background() var result int task := NewTask( func(ctx context.Context) (any, error) { return 3, nil }, WithFnSuccess(func(ctx context.Context, res any) { t, ok := res.(int) if !ok { return } result = t * 2 }), ) task.Run(ctx) assert.Equal(t, Success, task.GetState()) assert.Equal(t, 6, result) } func TestTaskFnError(t *testing.T) { ctx := context.Background() var result error task := NewTask( func(ctx context.Context) (any, error) { return 3, errors.New("error occurred...") }, WithFnError(func(ctx context.Context, err error) { result = err }), ) task.Run(ctx) assert.Equal(t, Failed, task.GetState()) assert.Equal(t, "error occurred...", result.Error()) } func TestTaskWithErrJobNotCompletedYet(t *testing.T) { ctx := context.Background() var attempts int task := NewTask( func(ctx context.Context) (any, error) { if attempts < 2 { attempts += 1 return nil, ErrJobNotCompletedYet } return "ok", nil }, ) for i := 0; i < 2; i++ { task.Run(ctx) assert.Equal(t, Pending, task.GetState()) } task.Run(ctx) assert.Equal(t, Success, task.GetState()) assert.Equal(t, 3, int(task.GetAttempts())) } func TestTaskTimeExceeded(t *testing.T) { ctx := context.Background() task := NewTask( func(ctx context.Context) (any, error) { return "ko", nil }, WithMaxDuration(5*time.Millisecond), ) time.Sleep(10 * time.Millisecond) task.Run(ctx) assert.Equal(t, Failed, task.GetState()) assert.Equal(t, 0, int(task.GetAttempts())) } func TestTaskExecTimeout(t *testing.T) { ctx := context.Background() task := NewTask( func(ctx context.Context) (any, error) { <-ctx.Done() return nil, ctx.Err() }, WithExecTimeout(5*time.Millisecond), ) time.Sleep(10 * time.Millisecond) task.Run(ctx) assert.Equal(t, Failed, task.GetState()) assert.Equal(t, 1, int(task.GetAttempts())) } func TestTaskDetails(t *testing.T) { ctx := context.Background() task := NewTask( func(ctx context.Context) (any, error) { return "coucou", nil }, ) details := task.IntoDetails() assert.Equal(t, 0, int(details.Attempts)) assert.Equal(t, "pending", details.State) assert.False(t, details.CreatedAt.IsZero()) assert.Empty(t, details.UpdatedAt) assert.Nil(t, details.MaxDuration) assert.Empty(t, details.Err) assert.NotEmpty(t, details.ElapsedTime) task.Run(ctx) details = task.IntoDetails() assert.Equal(t, 1, int(details.Attempts)) assert.Equal(t, "success", details.State) assert.False(t, details.CreatedAt.IsZero()) assert.NotEmpty(t, details.UpdatedAt) assert.Nil(t, details.MaxDuration) assert.Empty(t, details.Err) assert.NotEmpty(t, details.ElapsedTime) } func TestTaskAdditionalInfos(t *testing.T) { t.Run("with key value", func(t *testing.T) { elementID := uuid.NewString() task := NewTask( func(ctx context.Context) (any, error) { return "yo", nil }, WithAdditionalInfos("transportId", elementID), WithAdditionalInfos("element", "transport"), ) assert.Equal(t, elementID, task.additionalInfos["transportId"]) assert.Equal(t, "transport", task.additionalInfos["element"]) }) t.Run("with empty key", func(t *testing.T) { elementID := uuid.NewString() task := NewTask( func(ctx context.Context) (any, error) { return "hello", nil }, WithAdditionalInfos("", elementID), WithAdditionalInfos("element", "transport"), ) assert.Equal(t, "transport", task.additionalInfos["element"]) }) t.Run("with empty infos", func(t *testing.T) { task := NewTask( func(ctx context.Context) (any, error) { return "hey", nil }, ) assert.Nil(t, task.additionalInfos) }) }