-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvalidator_test.go
More file actions
163 lines (150 loc) · 5.34 KB
/
validator_test.go
File metadata and controls
163 lines (150 loc) · 5.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package bulwark
import (
"context"
"testing"
)
// TestAssertValidPriority verifies that AssertValidPriority passes valid
// priorities through unchanged and panics for any priority outside [0, priorities).
// This validator is intended for development environments where misuse of the
// library should be caught immediately rather than silently corrected.
func TestAssertValidPriority(t *testing.T) {
t.Run("valid priority passes through", func(t *testing.T) {
for _, p := range []Priority{High, Important, Medium, Low} {
got, err := AssertValidPriority(p, StandardPriorities)
if err != nil {
t.Errorf("priority %d: unexpected error: %v", p, err)
}
if got != p {
t.Errorf("priority %d: expected %d, got %d", p, p, got)
}
}
})
t.Run("negative priority panics", func(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Error("expected panic, got none")
}
}()
AssertValidPriority(-1, StandardPriorities)
})
t.Run("out of range priority panics", func(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Error("expected panic, got none")
}
}()
AssertValidPriority(Priority(StandardPriorities), StandardPriorities)
})
}
// TestClampInvalidPriority verifies that ClampInvalidPriority passes valid
// priorities through unchanged and clamps any out-of-range priority — including
// negative values — to the lowest valid priority (priorities-1). Clamping to
// the lowest rather than the nearest boundary ensures that invalid or malicious
// input is never silently promoted to a higher-importance tier.
func TestClampInvalidPriority(t *testing.T) {
t.Run("valid priority passes through", func(t *testing.T) {
for _, p := range []Priority{High, Important, Medium, Low} {
got, err := ClampInvalidPriority(p, StandardPriorities)
if err != nil {
t.Errorf("priority %d: unexpected error: %v", p, err)
}
if got != p {
t.Errorf("priority %d: expected %d, got %d", p, p, got)
}
}
})
t.Run("negative priority clamped to lowest", func(t *testing.T) {
got, err := ClampInvalidPriority(-1, StandardPriorities)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if got != Priority(StandardPriorities-1) {
t.Errorf("expected %d, got %d", StandardPriorities-1, got)
}
})
t.Run("out of range priority adjusted to lowest", func(t *testing.T) {
got, err := ClampInvalidPriority(Priority(StandardPriorities), StandardPriorities)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if got != Priority(StandardPriorities-1) {
t.Errorf("expected %d, got %d", StandardPriorities-1, got)
}
})
}
// TestRejectInvalidPriority verifies that RejectInvalidPriority passes valid
// priorities through unchanged and returns an error for any priority outside
// [0, priorities). This validator is suited for APIs where the caller is
// responsible for providing a valid priority and must handle the error.
func TestRejectInvalidPriority(t *testing.T) {
t.Run("valid priority passes through", func(t *testing.T) {
for _, p := range []Priority{High, Important, Medium, Low} {
got, err := RejectInvalidPriority(p, StandardPriorities)
if err != nil {
t.Errorf("priority %d: unexpected error: %v", p, err)
}
if got != p {
t.Errorf("priority %d: expected %d, got %d", p, p, got)
}
}
})
t.Run("negative priority returns error", func(t *testing.T) {
_, err := RejectInvalidPriority(-1, StandardPriorities)
if err == nil {
t.Error("expected error, got nil")
}
})
t.Run("out of range priority returns error", func(t *testing.T) {
_, err := RejectInvalidPriority(Priority(StandardPriorities), StandardPriorities)
if err == nil {
t.Error("expected error, got nil")
}
})
}
// TestWithPriorityValidator verifies that WithPriorityValidator wires a custom
// validator into the throttle so that it is called on every request. It also
// confirms that the default behaviour (no option provided) uses
// ClampInvalidPriority: out-of-range priorities are clamped rather than
// rejected, so the throttled function is still invoked.
func TestWithPriorityValidator(t *testing.T) {
t.Run("custom validator is applied", func(t *testing.T) {
called := false
throttle := NewAdaptiveThrottle(StandardPriorities,
WithPriorityValidator(func(p Priority, priorities int) (Priority, error) {
called = true
return p, nil
}),
)
throttle.Throttle(context.Background(), High, func(_ context.Context) error {
return nil
})
if !called {
t.Error("expected custom validator to be called")
}
})
t.Run("RejectInvalidPriority used as validator rejects invalid priority", func(t *testing.T) {
throttle := NewAdaptiveThrottle(StandardPriorities,
WithPriorityValidator(RejectInvalidPriority),
)
err := throttle.Throttle(context.Background(), Priority(StandardPriorities), func(_ context.Context) error {
return nil
})
if err == nil {
t.Error("expected error for out-of-range priority, got nil")
}
})
t.Run("default validator adjusts invalid priority", func(t *testing.T) {
throttle := NewAdaptiveThrottle(StandardPriorities)
called := false
err := throttle.Throttle(context.Background(), Priority(StandardPriorities), func(_ context.Context) error {
called = true
return nil
})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !called {
t.Error("expected throttled function to be called after priority adjustment")
}
})
}