github.com/ngicks/gokugen@v0.0.5/task_storage/multi_node_test.go (about) 1 package taskstorage_test 2 3 import ( 4 "context" 5 "errors" 6 "sync/atomic" 7 "testing" 8 "time" 9 10 "github.com/ngicks/gokugen" 11 "github.com/ngicks/gokugen/impl/repository" 12 taskstorage "github.com/ngicks/gokugen/task_storage" 13 syncparam "github.com/ngicks/type-param-common/sync-param" 14 ) 15 16 func prepareMulti(freeParam bool) ( 17 ts *taskstorage.MultiNodeTaskStorage, 18 repo *repository.InMemoryRepo, 19 registry *syncparam.Map[string, gokugen.WorkFnWParam], 20 sched func(ctx gokugen.SchedulerContext) (gokugen.Task, error), 21 doAllTasks func(), 22 getTaskResults func() []resultSet, 23 ) { 24 _, ts, repo, registry = buildTaskStorage() 25 sched, doAllTasks, getTaskResults = prepare(ts, freeParam) 26 return 27 } 28 29 func TestMultiNode(t *testing.T) { 30 prep := func(paramLoad bool) func() ( 31 repo *repository.InMemoryRepo, 32 registry *syncparam.Map[string, gokugen.WorkFnWParam], 33 sched func(ctx gokugen.SchedulerContext) (gokugen.Task, error), 34 doAllTasks func(), 35 getTaskResults func() []resultSet, 36 ) { 37 return func() ( 38 repo *repository.InMemoryRepo, 39 registry *syncparam.Map[string, gokugen.WorkFnWParam], 40 sched func(ctx gokugen.SchedulerContext) (gokugen.Task, error), 41 doAllTasks func(), 42 getTaskResults func() []resultSet, 43 ) { 44 _, repo, registry, sched, doAllTasks, getTaskResults = prepareMulti(paramLoad) 45 return 46 } 47 } 48 49 t.Run("no param load", func(t *testing.T) { 50 storageTestSet(t, prep(false)) 51 }) 52 53 t.Run("param load", func(t *testing.T) { 54 storageTestSet(t, prep(true)) 55 }) 56 57 t.Run("error if already marked as working", func(t *testing.T) { 58 _, repo, registry, sched, doAllTasks, getTaskResults := prepareMulti(false) 59 60 var count int64 61 registry.Store("foobar", func(taskCtx context.Context, scheduled time.Time, param any) (any, error) { 62 atomic.AddInt64(&count, 1) 63 return nil, nil 64 }) 65 66 sched( 67 gokugen.BuildContext( 68 time.Now(), 69 nil, 70 nil, 71 gokugen.WithParam(nil), 72 gokugen.WithWorkId("foobar"), 73 ), 74 ) 75 76 storedTasks, _ := repo.GetAll() 77 task := storedTasks[0] 78 79 err := repo.Update(task.Id, taskstorage.UpdateDiff{ 80 UpdateKey: taskstorage.UpdateKey{ 81 State: true, 82 }, 83 Diff: taskstorage.TaskInfo{ 84 State: taskstorage.Working, 85 }, 86 }) 87 if err != nil { 88 t.Fatal(err) 89 } 90 91 doAllTasks() 92 93 results := getTaskResults() 94 95 if !errors.Is(results[0].err, taskstorage.ErrOtherNodeWorkingOnTheTask) { 96 t.Fatalf("wrong error type: %v", results[0]) 97 } 98 if atomic.LoadInt64(&count) != 0 { 99 t.Fatalf("internal work is called") 100 } 101 }) 102 }