package hw05_parallel_execution //nolint:golint,stylecheck import ( "fmt" "math/rand" "sync/atomic" "testing" "time" "github.com/stretchr/testify/require" "go.uber.org/goleak" ) func TestRunMixed(t *testing.T) { defer goleak.VerifyNone(t) t.Run("50 tasks in 10 goroutines with 100% errors and maxErrors=23 should run not more N+M (=33) tasks", func(t *testing.T) { tasksCount := 50 tasks := make([]Task, 0, tasksCount) var runTasksCount int32 for i := 0; i < tasksCount; i++ { err := fmt.Errorf("error from task %d", i) tasks = append(tasks, func() error { time.Sleep(time.Millisecond * time.Duration(rand.Intn(100))) atomic.AddInt32(&runTasksCount, 1) return err }) } workersCount := 10 maxErrorsCount := 23 result := RunMixed(tasks, workersCount, maxErrorsCount) require.Equal(t, ErrErrorsLimitExceeded, result) require.LessOrEqual(t, runTasksCount, int32(workersCount+maxErrorsCount), "extra tasks were started") }) t.Run("50 tasks in 5 goroutines with 50% errors and m<0 should ignore errores", func(t *testing.T) { tasksCount := 50 tasks := make([]Task, 0, tasksCount) var runTasksCount int32 var sumTime time.Duration for i := 0; i < tasksCount; i++ { err := fmt.Errorf("error from task %d", i) taskSleep := time.Millisecond * time.Duration(rand.Intn(100)) sumTime += taskSleep tasks = append(tasks, func() error { time.Sleep(taskSleep) atomic.AddInt32(&runTasksCount, 1) if i%2 == 0 { return err } return nil }) } workersCount := 5 maxErrorsCount := -1 start := time.Now() result := RunMixed(tasks, workersCount, maxErrorsCount) elapsedTime := time.Since(start) require.Nil(t, result) require.Equal(t, runTasksCount, int32(tasksCount), "not all tasks were completed") require.LessOrEqual(t, int64(elapsedTime), int64(sumTime/2), "tasks were run sequentially?") }) t.Run("143 tasks in 7 goroutines without errors", func(t *testing.T) { tasksCount := 143 tasks := make([]Task, 0, tasksCount) var runTasksCount int32 var sumTime time.Duration for i := 0; i < tasksCount; i++ { taskSleep := time.Millisecond * time.Duration(rand.Intn(100)) sumTime += taskSleep tasks = append(tasks, func() error { time.Sleep(taskSleep) atomic.AddInt32(&runTasksCount, 1) return nil }) } workersCount := 7 maxErrorsCount := 1 start := time.Now() result := RunMixed(tasks, workersCount, maxErrorsCount) elapsedTime := time.Since(start) require.Nil(t, result) require.Equal(t, runTasksCount, int32(tasksCount), "not all tasks were completed") require.LessOrEqual(t, int64(elapsedTime), int64(sumTime/2), "tasks were run sequentially?") }) }