package agent import ( "context" "math/rand" "sync/atomic" "testing" "time" ) // Pieces fetched side by side are used in their order, never more than // depth at once in flight. func TestOrderedKeepsOrder(t *testing.T) { var inFlight, most int32 var got []int err := ordered(context.Background(), 20, 3, func(ctx context.Context, i int) ([]byte, error) { n := atomic.AddInt32(&inFlight, 1) for { m := atomic.LoadInt32(&most) if n <= m || atomic.CompareAndSwapInt32(&most, m, n) { break } } time.Sleep(time.Duration(rand.Intn(5)) * time.Millisecond) atomic.AddInt32(&inFlight, -1) return []byte{byte(i)}, nil }, func(i int, b []byte) error { if int(b[0]) != i { t.Errorf("piece %d carries %d", i, b[0]) } got = append(got, i) return nil }) if err != nil || len(got) != 20 { t.Fatalf("got %v, %v", got, err) } for i, v := range got { if v != i { t.Fatalf("order: %v", got) } } if most > 3 || most < 2 { t.Fatalf("at most %d in flight", most) } }