main
1package workerpool
2
3import (
4 "context"
5 "errors"
6 "sync/atomic"
7 "testing"
8 "time"
9)
10
11func TestPool_Run(t *testing.T) {
12 pool := New(2)
13
14 var count atomic.Int32
15 tasks := make([]Task, 10)
16 for i := range tasks {
17 tasks[i] = func(ctx context.Context) error {
18 count.Add(1)
19 return nil
20 }
21 }
22
23 results := pool.Run(context.Background(), tasks)
24
25 if len(results) != 10 {
26 t.Errorf("expected 10 results, got %d", len(results))
27 }
28 if count.Load() != 10 {
29 t.Errorf("expected 10 task executions, got %d", count.Load())
30 }
31 for i, r := range results {
32 if r.Error != nil {
33 t.Errorf("task %d unexpected error: %v", i, r.Error)
34 }
35 }
36}
37
38func TestPool_RunWithErrors(t *testing.T) {
39 pool := New(2)
40
41 testErr := errors.New("test error")
42 tasks := []Task{
43 func(ctx context.Context) error { return nil },
44 func(ctx context.Context) error { return testErr },
45 func(ctx context.Context) error { return nil },
46 }
47
48 results := pool.Run(context.Background(), tasks)
49
50 if results[0].Error != nil {
51 t.Error("task 0 should succeed")
52 }
53 if !errors.Is(results[1].Error, testErr) {
54 t.Errorf("task 1 expected testErr, got %v", results[1].Error)
55 }
56 if results[2].Error != nil {
57 t.Error("task 2 should succeed")
58 }
59}
60
61func TestPool_ContextCancellation(t *testing.T) {
62 pool := New(1)
63
64 ctx, cancel := context.WithCancel(context.Background())
65
66 started := make(chan struct{})
67 tasks := []Task{
68 func(ctx context.Context) error {
69 close(started)
70 time.Sleep(100 * time.Millisecond)
71 return nil
72 },
73 func(ctx context.Context) error {
74 return nil
75 },
76 }
77
78 go func() {
79 <-started
80 cancel()
81 }()
82
83 results := pool.Run(ctx, tasks)
84
85 // At least one task should have context error
86 hasCtxErr := false
87 for _, r := range results {
88 if errors.Is(r.Error, context.Canceled) {
89 hasCtxErr = true
90 break
91 }
92 }
93 if !hasCtxErr {
94 // May complete before cancellation - that's OK
95 t.Log("all tasks completed before cancellation")
96 }
97}
98
99func TestPool_EmptyTasks(t *testing.T) {
100 pool := New(4)
101 results := pool.Run(context.Background(), nil)
102
103 if len(results) != 0 {
104 t.Errorf("expected 0 results, got %d", len(results))
105 }
106}