/*
 *
 * Copyright 2018 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package health

import (
	"context"
	"errors"
	"reflect"
	"testing"
	"time"

	"google.golang.org/grpc/connectivity"
)

const defaultTestTimeout = 10 * time.Second

func (s) TestClientHealthCheckBackoff(t *testing.T) {
	const maxRetries = 5

	var want []time.Duration
	for i := 0; i < maxRetries; i++ {
		want = append(want, time.Duration(i+1)*time.Second)
	}

	var got []time.Duration
	newStream := func(string) (interface{}, error) {
		if len(got) < maxRetries {
			return nil, errors.New("backoff")
		}
		return nil, nil
	}

	oldBackoffFunc := backoffFunc
	backoffFunc = func(ctx context.Context, retries int) bool {
		got = append(got, time.Duration(retries+1)*time.Second)
		return true
	}
	defer func() { backoffFunc = oldBackoffFunc }()

	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	clientHealthCheck(ctx, newStream, func(connectivity.State, error) {}, "test")

	if !reflect.DeepEqual(got, want) {
		t.Fatalf("Backoff durations for %v retries are %v. (expected: %v)", maxRetries, got, want)
	}
}
