Go · 1420 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package worker_test
4
5 import (
6 "testing"
7 "time"
8
9 "github.com/tenseleyFlow/shithub/internal/worker"
10 )
11
12 func TestBackoff_Doubles(t *testing.T) {
13 t.Parallel()
14 cases := []struct {
15 attempts int
16 want time.Duration
17 }{
18 {1, 30 * time.Second},
19 {2, 60 * time.Second},
20 {3, 120 * time.Second},
21 {4, 240 * time.Second},
22 {5, 480 * time.Second},
23 {6, 960 * time.Second},
24 {7, 1920 * time.Second},
25 {8, time.Hour}, // capped
26 {10, time.Hour}, // still capped
27 }
28 for _, c := range cases {
29 got := worker.Backoff(c.attempts, nil)
30 if got != c.want {
31 t.Errorf("Backoff(%d) = %v, want %v", c.attempts, got, c.want)
32 }
33 }
34 }
35
36 func TestBackoff_JitterStaysInBand(t *testing.T) {
37 t.Parallel()
38 const attempts = 4
39 base := worker.Backoff(attempts, nil)
40 low := time.Duration(float64(base) * 0.8)
41 high := time.Duration(float64(base) * 1.2)
42 for i := 0; i < 100; i++ {
43 j := float64(i) / 100.0
44 got := worker.Backoff(attempts, func() float64 { return j })
45 if got < low || got >= high {
46 t.Fatalf("jitter %v: got %v, want in [%v, %v)", j, got, low, high)
47 }
48 }
49 }
50
51 func TestBackoff_NonPositiveAttemptsClampsToOne(t *testing.T) {
52 t.Parallel()
53 if got := worker.Backoff(0, nil); got != 30*time.Second {
54 t.Errorf("Backoff(0) = %v, want 30s", got)
55 }
56 if got := worker.Backoff(-5, nil); got != 30*time.Second {
57 t.Errorf("Backoff(-5) = %v, want 30s", got)
58 }
59 }
60