// Copyright (c) The go-grpc-middleware Authors.
// Licensed under the Apache License 2.0.

package backoffutils_test

import (
	"testing"
	"time"

	"github.com/grpc-ecosystem/go-grpc-middleware/v2/util/backoffutils"
	"github.com/stretchr/testify/assert"
)

// scale duration by a factor
func scaleDuration(d time.Duration, factor float64) time.Duration {
	return time.Duration(float64(d) * factor)
}

func TestJitterUp(t *testing.T) {
	// arguments to jitterup
	duration := 10 * time.Second
	variance := 0.10

	// bound to check
	max := 11000 * time.Millisecond
	min := 9000 * time.Millisecond
	high := scaleDuration(max, 0.98)
	low := scaleDuration(min, 1.02)

	highCount := 0
	lowCount := 0

	for i := 0; i < 1000; i++ {
		out := backoffutils.JitterUp(duration, variance)
		assert.LessOrEqual(t, out, max, "value %s must be <= %s", out, max)
		assert.GreaterOrEqual(t, out, min, "value %s must be >= %s", out, min)

		if out > high {
			highCount++
		}
		if out < low {
			lowCount++
		}
	}

	assert.NotEqual(t, 0, highCount, "at least one sample should reach to >%s", high)
	assert.NotEqual(t, 0, lowCount, "at least one sample should to <%s", low)
}
