Пример #1
0
func TestRoundRobin(t *testing.T) {
	p := loadbalancer.NewStaticPublisher([]endpoint.Endpoint{})
	defer p.Stop()

	lb := loadbalancer.RoundRobin(p)
	if _, err := lb.Get(); err == nil {
		t.Error("want error, got none")
	}

	counts := []int{0, 0, 0}
	p.Replace([]endpoint.Endpoint{
		func(context.Context, interface{}) (interface{}, error) { counts[0]++; return struct{}{}, nil },
		func(context.Context, interface{}) (interface{}, error) { counts[1]++; return struct{}{}, nil },
		func(context.Context, interface{}) (interface{}, error) { counts[2]++; return struct{}{}, nil },
	})
	runtime.Gosched()

	for i, want := range [][]int{
		{1, 0, 0},
		{1, 1, 0},
		{1, 1, 1},
		{2, 1, 1},
		{2, 2, 1},
		{2, 2, 2},
		{3, 2, 2},
	} {
		e, _ := lb.Get()
		e(context.Background(), struct{}{})
		if have := counts; !reflect.DeepEqual(want, have) {
			t.Errorf("%d: want %v, have %v", i+1, want, have)
		}
	}
}
Пример #2
0
func TestRetryMax(t *testing.T) {
	var (
		endpoints = []endpoint.Endpoint{}
		p         = loadbalancer.NewStaticPublisher(endpoints)
		lb        = loadbalancer.RoundRobin(p)
	)

	if _, err := loadbalancer.Retry(999, time.Second, lb)(context.Background(), struct{}{}); err == nil {
		t.Errorf("expected error, got none")
	}

	endpoints = []endpoint.Endpoint{
		func(context.Context, interface{}) (interface{}, error) { return nil, errors.New("error one") },
		func(context.Context, interface{}) (interface{}, error) { return nil, errors.New("error two") },
		func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil /* OK */ },
	}
	p.Replace(endpoints)
	runtime.Gosched()

	if _, err := loadbalancer.Retry(len(endpoints)-1, time.Second, lb)(context.Background(), struct{}{}); err == nil {
		t.Errorf("expected error, got none")
	}

	if _, err := loadbalancer.Retry(len(endpoints), time.Second, lb)(context.Background(), struct{}{}); err != nil {
		t.Error(err)
	}
}
Пример #3
0
func TestRetryTimeout(t *testing.T) {
	var (
		step    = make(chan struct{})
		e       = func(context.Context, interface{}) (interface{}, error) { <-step; return struct{}{}, nil }
		timeout = time.Millisecond
		retry   = loadbalancer.Retry(999, timeout, loadbalancer.RoundRobin(loadbalancer.NewStaticPublisher([]endpoint.Endpoint{e})))
		errs    = make(chan error)
		invoke  = func() { _, err := retry(context.Background(), struct{}{}); errs <- err }
	)

	go invoke()                    // invoke the endpoint
	step <- struct{}{}             // tell the endpoint to return
	if err := <-errs; err != nil { // that should succeed
		t.Error(err)
	}

	go invoke()                                         // invoke the endpoint
	time.Sleep(2 * timeout)                             // wait
	step <- struct{}{}                                  // tell the endpoint to return
	if err := <-errs; err != context.DeadlineExceeded { // that should not succeed
		t.Errorf("wanted error, got none")
	}
}