bitbucket.org/ai69/amoy@v0.2.3/worker_test.go (about)

     1  package amoy
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func TestParallelTaskRun(t *testing.T) {
    11  	tests := []struct {
    12  		name    string
    13  		timeOut time.Duration
    14  		num     int
    15  		tasks   []string
    16  		eta     time.Duration
    17  		wantErr bool
    18  	}{
    19  		{"1 Worker for 1 Task (Min)", ZeroDuration, 0, []string{"a"}, ZeroDuration, true},
    20  		{"1 Worker for 1 Task", ZeroDuration, 1, []string{"a"}, Seconds(1), false},
    21  		{"1 Worker for 2 Task", ZeroDuration, 1, []string{"a", "b"}, Seconds(2), false},
    22  		{"2 Workers for 2 Tasks", ZeroDuration, 2, []string{"a", "b"}, Seconds(1), false},
    23  		{"2 Workers for 3 Tasks", ZeroDuration, 2, []string{"a", "b", "c"}, Seconds(2), false},
    24  		{"2 Workers for 7 Tasks", ZeroDuration, 2, []string{"a", "b", "c", "d", "e", "f", "g"}, Seconds(4), false},
    25  		{"2 Workers for 7 Tasks With 0 Sec Timeout", Milliseconds(1), 2, []string{"a", "b", "c", "d", "e", "f", "g"}, ZeroDuration, true},
    26  		{"2 Workers for 7 Tasks With 0.5 Sec Timeout", Seconds(0.5), 2, []string{"a", "b", "c", "d", "e", "f", "g"}, Seconds(0.5), true},
    27  		{"2 Workers for 7 Tasks With 3.5 Sec Timeout", Seconds(3.5), 2, []string{"a", "b", "c", "d", "e", "f", "g"}, Seconds(3.5), true},
    28  		{"2 Workers for 7 Tasks With 5 Sec Timeout", Seconds(5), 2, []string{"a", "b", "c", "d", "e", "f", "g"}, Seconds(4), false},
    29  		{"7 Workers for 7 Tasks", ZeroDuration, 7, []string{"a", "b", "c", "d", "e", "f", "g"}, Seconds(1), false},
    30  		{"7 Workers for 7 Tasks (Max)", ZeroDuration, 20, []string{"a", "b", "c", "d", "e", "f", "g"}, Seconds(1), false},
    31  	}
    32  	tolerance := Milliseconds(100)
    33  	for _, tt := range tests {
    34  		t.Run(tt.name, func(t *testing.T) {
    35  			// create context
    36  			ctx := context.Background()
    37  			if tt.timeOut > 0 {
    38  				t.Logf("set context timeout: %v", tt.timeOut)
    39  				ctx, _ = context.WithTimeout(ctx, tt.timeOut)
    40  			}
    41  			// run
    42  			start := time.Now()
    43  			callTestParallelTaskRunTest(ctx, t, tt.name, tt.num, tt.tasks, tt.wantErr)
    44  			elapsed := time.Since(start)
    45  			// check elapsed time
    46  			if elapsed > tt.eta+tolerance {
    47  				t.Errorf("ParallelTaskRun() took too long (time cost: %v, expected: %v)", elapsed, tt.eta)
    48  			} else if elapsed < tt.eta-tolerance {
    49  				t.Errorf("ParallelTaskRun() took too short (time cost: %v, expected: %v)", elapsed, tt.eta)
    50  			}
    51  		})
    52  	}
    53  }
    54  
    55  func callTestParallelTaskRunTest(ctx context.Context, t *testing.T, name string, num int, tasks []string, wantErr bool) {
    56  	timeStart := time.Now()
    57  	timeLapsedStr := func() string {
    58  		return fmt.Sprintf("%02.3f", float64(time.Since(timeStart).Microseconds())/1e6)
    59  	}
    60  	err := ParallelTaskRun(ctx, num, len(tasks), func(ctx context.Context, id int) (interface{}, error) {
    61  		task := tasks[id]
    62  		t.Logf("[%s][%s] got task%d to run: %s", name, timeLapsedStr(), id, task)
    63  		if err := SleepWithContext(ctx, Seconds(1)); err != nil {
    64  			return nil, err
    65  		}
    66  		if FeelLucky(0.3) {
    67  			return nil, fmt.Errorf("feel unlucky")
    68  		}
    69  		return "[" + task + "]", nil
    70  	}, func(ctx context.Context, id int, result interface{}, err error) {
    71  		task := tasks[id]
    72  		t.Logf("[%s][%s] got task%d %q result: %v, error: %v", name, timeLapsedStr(), id, task, result, err)
    73  	})
    74  	if wantErr && err == nil {
    75  		t.Errorf("[%s] should return error (time cost: %v)", name, time.Since(timeStart))
    76  	} else if !wantErr && err != nil {
    77  		t.Errorf("[%s] failed (time cost: %v), error: %v", name, time.Since(timeStart), err)
    78  	} else {
    79  		t.Logf("[%s] all tasks are done (time_cost: %v), error: %v", name, time.Since(timeStart), err)
    80  	}
    81  }