| 1 | // SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | |
| 3 | package webhook |
| 4 | |
| 5 | import ( |
| 6 | "testing" |
| 7 | "time" |
| 8 | ) |
| 9 | |
| 10 | func TestBackoffSchedule(t *testing.T) { |
| 11 | cases := []struct { |
| 12 | attempt int |
| 13 | want time.Duration |
| 14 | }{ |
| 15 | {1, 30 * time.Second}, |
| 16 | {2, 1 * time.Minute}, |
| 17 | {3, 2 * time.Minute}, |
| 18 | {4, 4 * time.Minute}, |
| 19 | {5, 8 * time.Minute}, |
| 20 | {8, 64 * time.Minute}, |
| 21 | } |
| 22 | for _, tc := range cases { |
| 23 | got := Backoff(tc.attempt, nil) |
| 24 | if got != tc.want { |
| 25 | t.Errorf("Backoff(%d) = %v; want %v", tc.attempt, got, tc.want) |
| 26 | } |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | func TestBackoffCapsAt24Hours(t *testing.T) { |
| 31 | got := Backoff(50, nil) |
| 32 | if got != BackoffMax { |
| 33 | t.Fatalf("Backoff(50) = %v; want %v", got, BackoffMax) |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | func TestBackoffJitterStaysWithinTwentyPercent(t *testing.T) { |
| 38 | base := Backoff(3, nil) // 2 minutes |
| 39 | for j := 0.0; j < 1.0; j += 0.05 { |
| 40 | jit := j |
| 41 | got := Backoff(3, func() float64 { return jit }) |
| 42 | min := time.Duration(float64(base) * 0.79) |
| 43 | max := time.Duration(float64(base) * 1.21) |
| 44 | if got < min || got > max { |
| 45 | t.Errorf("Backoff(3, jitter=%.2f) = %v; want in [%v, %v]", jit, got, min, max) |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | func TestBackoffClampsZeroAttempt(t *testing.T) { |
| 51 | got := Backoff(0, nil) |
| 52 | if got != BackoffBase { |
| 53 | t.Fatalf("Backoff(0) = %v; want %v", got, BackoffBase) |
| 54 | } |
| 55 | } |
| 56 |