func TestSingleExecutorClose(t *testing.T) { task1 := &fakeTask{runDuration: time.Hour} se := tasks.NewSingleExecutor() e := se.Start(task1) se.Close() <-e.Done() }
func TestSingleExecutorStart(t *testing.T) { task1 := &fakeTask{runDuration: time.Millisecond} task2 := &fakeTask{runDuration: time.Millisecond} task3 := &fakeTask{runDuration: time.Millisecond} se := tasks.NewSingleExecutor() defer se.Close() e := se.Start(task1) if tk, ex := se.Current(); tk.(*fakeTask) != task1 || ex != e { t.Error("Expect Current to be task 1.") } <-e.Done() e = se.Start(task2) if tk, ex := se.Current(); tk.(*fakeTask) != task2 || ex != e { t.Error("Expect Current to be task 2.") } <-e.Done() e = se.Start(task3) if tk, ex := se.Current(); tk.(*fakeTask) != task3 || ex != e { t.Error("Expect Current to be task 3.") } <-e.Done() if tk, ex := se.Current(); tk != nil || ex != nil { t.Error("Expected current task and execution to be nil.") } if !task1.hasRun() || !task2.hasRun() || !task3.hasRun() { t.Error("All three tasks should have run.") } }
func TestSingleExecutorPause(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task1 := &fakeTask2{runDuration: time.Hour, Starting: starting} se := tasks.NewSingleExecutor() defer se.Close() se.Start(task1) waitForStarts(starting, 1) se.Pause() }
func TestPauseNotSupportedPauseEarly(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task1 := &pauseTask{Starting: starting} se := tasks.NewSingleExecutor() defer se.Close() se.Start(task1) se.Pause() // Acknowledge if the task completed while pausing waitForStarts(starting, task1.Count()) time.Sleep(time.Millisecond) // No new tasks should start assertNoStarting(t, starting) }
func TestSingleExecutorForceStart(t *testing.T) { task1 := &fakeTask{runDuration: time.Hour} task2 := &fakeTask{runDuration: time.Hour} task3 := &fakeTask{runDuration: time.Hour} se := tasks.NewSingleExecutor() defer se.Close() e1 := se.Start(task1) e2 := se.Start(task2) e3 := se.Start(task3) e3.End() <-e1.Done() <-e2.Done() <-e3.Done() if !task1.hasRun() || !task2.hasRun() || !task3.hasRun() { t.Error("All three tasks should have run.") } }
func TestPauseSeriesItself(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task := &pauseTask{Starting: starting} se := tasks.NewSingleExecutor() defer se.Close() // Tasks in executor must support equality e := se.Start(&taskStruct{tasks.SeriesTasks(task, task)}) waitForStarts(starting, 1) se.Pause() select { case <-e.Done(): t.Error("Pause not working") case <-time.After(10 * time.Millisecond): } e.End() <-e.Done() }
func TestPauseNotSupported(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task1 := &pauseTask{Starting: starting} se := tasks.NewSingleExecutor() defer se.Close() e := se.Start(task1) waitForStarts(starting, 1) // Since this task doesn't support pause, this Pause() call won't return // until the task is finished. se.Pause() if out := task1.Count(); out != 1 { t.Errorf("Expected 1, got %d", out) } // A paused task can still end on its own. The only // guarantee is that the paused task won't do any additional work. <-e.Done() }
func TestPauseNotSupportedParallelPauseEarly(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task1 := &pauseTask{Starting: starting} ts := make([]tasks.Task, 20) for i := range ts { ts[i] = task1 } se := tasks.NewSingleExecutor() defer se.Close() se.Start(&taskStruct{tasks.ParallelTasks(ts...)}) se.Pause() // Acknowledge the tasks that completed while pausing waitForStarts(starting, task1.Count()) time.Sleep(time.Millisecond) // No new tasks should start assertNoStarting(t, starting) }
func TestSingleExecutorPauseFromBeginning(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task := &pauseTask{Starting: starting} se := tasks.NewSingleExecutor() defer se.Close() se.Pause() e := se.Start(&taskStruct{tasks.RepeatingTask(task, 2147483647)}) time.Sleep(5 * time.Millisecond) assertNoStarting(t, starting) se.Resume() waitForStarts(starting, 1) se.Pause() expected := 1 if out := task.Count(); out != expected { t.Errorf("Expected count of %d, got %d", expected, out) expected = out } e.End() <-e.Done() }
func TestPauseNotSupportedParallel(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task1 := &pauseTask{Starting: starting} ts := make([]tasks.Task, 20) for i := range ts { ts[i] = task1 } se := tasks.NewSingleExecutor() defer se.Close() e := se.Start(&taskStruct{tasks.ParallelTasks(ts...)}) waitForStarts(starting, len(ts)) // Since these parallel tasks don't support pause, this Pause() call // won't return until all the tasks have finished. se.Pause() if out := task1.Count(); out != len(ts) { t.Errorf("Expected %d, got %d", len(ts), out) } // A paused task can still end on its own. The only // guarantee is that the paused task won't do any additional work. <-e.Done() }
func TestSingleExecutorMultiThread(t *testing.T) { fakeTasks := make([]*fakeTask, 20) for i := range fakeTasks { fakeTasks[i] = &fakeTask{} } var wg sync.WaitGroup wg.Add(len(fakeTasks)) se := tasks.NewSingleExecutor() defer se.Close() for i := range fakeTasks { go func(t tasks.Task) { e := se.Start(t) <-e.Done() wg.Done() }(fakeTasks[i]) } wg.Wait() for i := range fakeTasks { if fakeTasks[i].timesRun != 1 { t.Error("Expected each task to be run exactly once.") } } }
func TestPauseSeries(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task := &pauseTask{Starting: starting} se := tasks.NewSingleExecutor() defer se.Close() ts := make([]tasks.Task, 20) for i := range ts { ts[i] = tasks.RepeatingTask(task, 2147483647) } // Tasks in executor must support equality e := se.Start(&taskStruct{tasks.SeriesTasks(ts...)}) waitForStarts(starting, 1) se.Pause() expected := 1 if out := task.Count(); out != expected { t.Errorf("Expected count of %d, got %d", expected, out) expected = out } time.Sleep(5 * time.Millisecond) assertNoStarting(t, starting) se.Resume() se.Resume() waitForStarts(starting, 1) se.Pause() expected += 1 if out := task.Count(); out != expected { t.Errorf("Expected count of %d, got %d", expected, out) expected = out } time.Sleep(5 * time.Millisecond) assertNoStarting(t, starting) se.Resume() e.End() <-e.Done() }
func TestInterruptWhilePaused(t *testing.T) { starting := make(chan bool, 100) defer close(starting) task1 := &fakeTask2{runDuration: time.Hour, Starting: starting} task2 := &fakeTask2{runDuration: time.Hour, Starting: starting} task3 := &fakeTask2{runDuration: time.Hour, Starting: starting} se := tasks.NewSingleExecutor() e1 := se.Start(task1) waitForStarts(starting, 1) se.Pause() ctask, _ := se.Current() if ctask != task1 { t.Error("Expect current task to be task1") } expectFalse(t, "e1.IsDone()", e1.IsDone()) e2 := se.Start(task2) expectTrue(t, "e1.IsDone()", e1.IsDone()) ctask, _ = se.Current() if ctask != task2 { t.Error("Expect current task to be task2") } time.Sleep(time.Millisecond) assertNoStarting(t, starting) expectFalse(t, "e2.IsDone()", e2.IsDone()) e3 := se.Start(task3) expectTrue(t, "e2.IsDone()", e2.IsDone()) ctask, _ = se.Current() if ctask != task3 { t.Error("Expect current task to be task3") } time.Sleep(time.Millisecond) assertNoStarting(t, starting) expectFalse(t, "e3.IsDone()", e3.IsDone()) se.Close() expectTrue(t, "e3.IsDone()", e3.IsDone()) }
func TestPauseNoTasks(t *testing.T) { se := tasks.NewSingleExecutor() defer se.Close() se.Pause() se.Resume() }