debugging DefaltApplyJitter, adding tests

This commit is contained in:
William Dillon 2026-02-26 19:55:48 -05:00
parent b4edee4292
commit 8cefae503f
4 changed files with 79 additions and 13 deletions

View File

@ -93,6 +93,8 @@ func Fibonacci(n int64) int64 {
case n >= int64(len(TheFibonacciSequence)):
panic(fmt.Sprintf("invalid input: %d overflows int64\n",
n))
case n < 0:
panic(fmt.Sprintf("invalid input: %d would cause index out of range panic\n", n))
default:
return TheFibonacciSequence[n]
}

View File

@ -2,19 +2,12 @@ package fibonacci
import (
"context"
"fmt"
"math/big"
"testing"
"time"
"code.wmdillon.com/wmdillon/backoff/utilities"
)
func wouldOverflow(a, b int64) (product int64, overflows bool) {
results := new(big.Int).Mul(big.NewInt(a), big.NewInt(b))
return results.Int64(), results.IsInt64()
}
func fibonacci(n int64) int64 {
switch {
case n <= 0:
@ -129,7 +122,6 @@ func TestFibonacciPauseLimit(t *testing.T) {
t.Fatalf("error for %d: expected value in range %s - %s; got %s\n", input, min, max, got)
}
}
fmt.Printf("finished\n")
}
func TestFibonacciBackoffAfter(t *testing.T) {

View File

@ -10,15 +10,64 @@ var (
ApplyJitter = DefaultApplyJitter
)
const (
maxInt64 = math.MaxInt64
minInt64 = math.MinInt64
)
func satAdd(a, b int64) int64 {
switch {
case b > 0 && a > maxInt64-b:
return maxInt64
case b < 0 && a < minInt64-b:
return minInt64
default:
return a + b
}
}
func satSub(a, b int64) int64 {
switch {
case b > 0 && a < minInt64+b:
return minInt64
case b < 0 && a > maxInt64+b:
return maxInt64
default:
return a - b
}
}
func DefaultApplyJitter(pauseDuration time.Duration, jitter time.Duration) time.Duration {
switch {
case jitter == 0, pauseDuration == 0:
case pauseDuration <= 0:
return 0
case jitter == 0:
return pauseDuration
case jitter < 0:
jitter = -jitter
case jitter > pauseDuration:
pauseDuration, jitter = jitter, pauseDuration
}
min := pauseDuration.Nanoseconds() - jitter.Nanoseconds()
max := pauseDuration.Nanoseconds() + jitter.Nanoseconds()
rnd := int64(math.Max(float64(rand.Int64N(max-min)+min), 0))
return time.Duration(rnd)
min := satSub(pauseDuration.Nanoseconds(), jitter.Nanoseconds())
if min < 0 {
min = 0
}
max := satAdd(pauseDuration.Nanoseconds(), jitter.Nanoseconds())
if max <= min {
return time.Duration(min)
}
var maxExcl int64
if max == math.MaxInt64 {
span := max - min
if span == math.MaxInt64 {
return time.Duration(rand.Int64N(math.MaxInt64) + min)
}
n := rand.Int64N(span + 1)
return time.Duration(min + n)
}
maxExcl = max + 1
return time.Duration(min + rand.Int64N(maxExcl-min))
}

23
utilities/jitter_test.go Normal file
View File

@ -0,0 +1,23 @@
package utilities
import (
"testing"
"time"
)
func TestDefaultApplyJitterIsAlwaysGEZero(t *testing.T) {
if got := DefaultApplyJitter(maxInt64, time.Nanosecond); got < 0 {
t.Fatalf("error: wanted >= 0; got %s\n", got)
}
if got := DefaultApplyJitter(maxInt64, maxInt64); got < 0 {
t.Fatalf("error: wanted >= 0; got %s\n", got)
}
}
func TestDefaultApplyJitterWithZeroPauseAlwaysZero(t *testing.T) {
for i := 0; i < 10; i++ {
if got := DefaultApplyJitter(0, time.Duration(i)); got != 0 {
t.Fatalf("error: wanted 0; got %s\n", got)
}
}
}