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  }