Skip to content

Commit 397cd73

Browse files
LukeAVanDriekfswain
authored andcommitted
refactor(flowcontrol): Enable behavioral mocking (kubernetes-sigs#1202)
The existing mock implementations for the flow control framework policies and accessors were simple stubs that returned fixed values. This style of mocking is too restrictive for testing complex, concurrent components where behavior needs to be dynamically controlled at test time. To prepare for testing more advanced orchestration logic, this commit refactors the core mocks to use function fields instead of static return values. This transforms them from simple stubs into flexible, behavioral mocks. Tests can now inject custom logic at runtime to simulate a wide range of policy decisions and interactions. The following mocks were updated: - MockPriorityBandAccessor - MockIntraFlowDispatchPolicy - MockInterFlowDispatchPolicy The policy tests that consume these mocks have been updated to use this new, more powerful mocking pattern.
1 parent 6707e7e commit 397cd73

File tree

4 files changed

+244
-315
lines changed

4 files changed

+244
-315
lines changed

pkg/epp/flowcontrol/framework/mocks/mocks.go

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/types"
2222
)
2323

24-
// MockItemComparator provides a mock implementation of the `framework.ItemComparator` interface.
24+
// MockItemComparator is a simple stub mock for the `framework.ItemComparator` interface.
2525
type MockItemComparator struct {
2626
FuncV framework.ItemComparatorFunc
2727
ScoreTypeV string
@@ -30,12 +30,11 @@ type MockItemComparator struct {
3030
func (m *MockItemComparator) Func() framework.ItemComparatorFunc { return m.FuncV }
3131
func (m *MockItemComparator) ScoreType() string { return m.ScoreTypeV }
3232

33-
var _ framework.ItemComparator = &MockItemComparator{}
34-
35-
// MockFlowQueueAccessor is a mock implementation of the `framework.FlowQueueAccessor` interface.
33+
// MockFlowQueueAccessor is a simple stub mock for the `framework.FlowQueueAccessor` interface.
34+
// It is used for tests that require static, predictable return values from a queue accessor.
35+
// For complex, stateful queue behavior, use the mock in `contracts/mocks.MockManagedQueue`.
3636
type MockFlowQueueAccessor struct {
3737
NameV string
38-
CapabilitiesV []framework.QueueCapability
3938
LenV int
4039
ByteSizeV uint64
4140
PeekHeadV types.QueueItemAccessor
@@ -44,12 +43,15 @@ type MockFlowQueueAccessor struct {
4443
PeekTailErrV error
4544
FlowSpecV types.FlowSpecification
4645
ComparatorV framework.ItemComparator
46+
CapabilitiesV []framework.QueueCapability
4747
}
4848

4949
func (m *MockFlowQueueAccessor) Name() string { return m.NameV }
50-
func (m *MockFlowQueueAccessor) Capabilities() []framework.QueueCapability { return m.CapabilitiesV }
5150
func (m *MockFlowQueueAccessor) Len() int { return m.LenV }
5251
func (m *MockFlowQueueAccessor) ByteSize() uint64 { return m.ByteSizeV }
52+
func (m *MockFlowQueueAccessor) Comparator() framework.ItemComparator { return m.ComparatorV }
53+
func (m *MockFlowQueueAccessor) FlowSpec() types.FlowSpecification { return m.FlowSpecV }
54+
func (m *MockFlowQueueAccessor) Capabilities() []framework.QueueCapability { return m.CapabilitiesV }
5355

5456
func (m *MockFlowQueueAccessor) PeekHead() (types.QueueItemAccessor, error) {
5557
return m.PeekHeadV, m.PeekHeadErrV
@@ -59,51 +61,47 @@ func (m *MockFlowQueueAccessor) PeekTail() (types.QueueItemAccessor, error) {
5961
return m.PeekTailV, m.PeekTailErrV
6062
}
6163

62-
func (m *MockFlowQueueAccessor) Comparator() framework.ItemComparator { return m.ComparatorV }
63-
func (m *MockFlowQueueAccessor) FlowSpec() types.FlowSpecification { return m.FlowSpecV }
64-
6564
var _ framework.FlowQueueAccessor = &MockFlowQueueAccessor{}
6665

67-
// MockPriorityBandAccessor is a mock implementation of the `framework.PriorityBandAccessor` interface.
66+
// MockPriorityBandAccessor is a behavioral mock for the `framework.MockPriorityBandAccessor` interface.
67+
// Simple accessors are configured with public value fields (e.g., `PriorityV`).
68+
// Complex methods with logic are configured with function fields (e.g., `IterateQueuesFunc`).
6869
type MockPriorityBandAccessor struct {
69-
PriorityV uint
70-
PriorityNameV string
71-
FlowIDsV []string
72-
QueueV framework.FlowQueueAccessor // Value to return for any Queue(flowID) call
73-
QueueFuncV func(flowID string) framework.FlowQueueAccessor
74-
IterateQueuesV func(callback func(queue framework.FlowQueueAccessor) bool)
70+
PriorityV uint
71+
PriorityNameV string
72+
FlowIDsFunc func() []string
73+
QueueFunc func(flowID string) framework.FlowQueueAccessor
74+
IterateQueuesFunc func(callback func(queue framework.FlowQueueAccessor) (keepIterating bool))
7575
}
7676

7777
func (m *MockPriorityBandAccessor) Priority() uint { return m.PriorityV }
7878
func (m *MockPriorityBandAccessor) PriorityName() string { return m.PriorityNameV }
79-
func (m *MockPriorityBandAccessor) FlowIDs() []string { return m.FlowIDsV }
79+
80+
func (m *MockPriorityBandAccessor) FlowIDs() []string {
81+
if m.FlowIDsFunc != nil {
82+
return m.FlowIDsFunc()
83+
}
84+
return nil
85+
}
8086

8187
func (m *MockPriorityBandAccessor) Queue(flowID string) framework.FlowQueueAccessor {
82-
if m.QueueFuncV != nil {
83-
return m.QueueFuncV(flowID)
88+
if m.QueueFunc != nil {
89+
return m.QueueFunc(flowID)
8490
}
85-
return m.QueueV
91+
return nil
8692
}
8793

8894
func (m *MockPriorityBandAccessor) IterateQueues(callback func(queue framework.FlowQueueAccessor) bool) {
89-
if m.IterateQueuesV != nil {
90-
m.IterateQueuesV(callback)
91-
} else {
92-
// Default behavior: iterate based on FlowIDsV and QueueV/QueueFuncV
93-
for _, id := range m.FlowIDsV {
94-
q := m.Queue(id)
95-
if q != nil { // Only call callback if queue exists
96-
if !callback(q) {
97-
return
98-
}
99-
}
100-
}
95+
if m.IterateQueuesFunc != nil {
96+
m.IterateQueuesFunc(callback)
10197
}
10298
}
10399

104100
var _ framework.PriorityBandAccessor = &MockPriorityBandAccessor{}
105101

106-
// MockSafeQueue is a mock implementation of the `framework.SafeQueue` interface.
102+
// MockSafeQueue is a simple stub mock for the `framework.SafeQueue` interface.
103+
// It is used for tests that need to control the exact return values of a queue's methods without simulating the queue's
104+
// internal logic or state.
107105
type MockSafeQueue struct {
108106
NameV string
109107
CapabilitiesV []framework.QueueCapability
@@ -162,24 +160,48 @@ func (m *MockSafeQueue) Drain() ([]types.QueueItemAccessor, error) {
162160

163161
var _ framework.SafeQueue = &MockSafeQueue{}
164162

165-
// MockIntraFlowDispatchPolicy is a mock implementation of the `framework.IntraFlowDispatchPolicy` interface.
163+
// MockIntraFlowDispatchPolicy is a behavioral mock for the `framework.IntraFlowDispatchPolicy` interface.
164+
// Simple accessors are configured with public value fields (e.g., `NameV`).
165+
// Complex methods with logic are configured with function fields (e.g., `SelectItemFunc`).
166166
type MockIntraFlowDispatchPolicy struct {
167167
NameV string
168-
SelectItemV types.QueueItemAccessor
169-
SelectItemErrV error
170168
ComparatorV framework.ItemComparator
171169
RequiredQueueCapabilitiesV []framework.QueueCapability
170+
SelectItemFunc func(queue framework.FlowQueueAccessor) (types.QueueItemAccessor, error)
172171
}
173172

174173
func (m *MockIntraFlowDispatchPolicy) Name() string { return m.NameV }
175174
func (m *MockIntraFlowDispatchPolicy) Comparator() framework.ItemComparator { return m.ComparatorV }
175+
func (m *MockIntraFlowDispatchPolicy) RequiredQueueCapabilities() []framework.QueueCapability {
176+
return m.RequiredQueueCapabilitiesV
177+
}
176178

177179
func (m *MockIntraFlowDispatchPolicy) SelectItem(queue framework.FlowQueueAccessor) (types.QueueItemAccessor, error) {
178-
return m.SelectItemV, m.SelectItemErrV
180+
if m.SelectItemFunc != nil {
181+
return m.SelectItemFunc(queue)
182+
}
183+
return nil, nil
179184
}
180185

181-
func (m *MockIntraFlowDispatchPolicy) RequiredQueueCapabilities() []framework.QueueCapability {
182-
return m.RequiredQueueCapabilitiesV
186+
var _ framework.IntraFlowDispatchPolicy = &MockIntraFlowDispatchPolicy{}
187+
188+
// MockInterFlowDispatchPolicy is a behavioral mock for the `framework.InterFlowDispatchPolicy` interface.
189+
// Simple accessors are configured with public value fields (e.g., `NameV`).
190+
// Complex methods with logic are configured with function fields (e.g., `SelectQueueFunc`).
191+
type MockInterFlowDispatchPolicy struct {
192+
NameV string
193+
SelectQueueFunc func(band framework.PriorityBandAccessor) (framework.FlowQueueAccessor, error)
183194
}
184195

185-
var _ framework.IntraFlowDispatchPolicy = &MockIntraFlowDispatchPolicy{}
196+
func (m *MockInterFlowDispatchPolicy) Name() string {
197+
return m.NameV
198+
}
199+
200+
func (m *MockInterFlowDispatchPolicy) SelectQueue(band framework.PriorityBandAccessor) (framework.FlowQueueAccessor, error) {
201+
if m.SelectQueueFunc != nil {
202+
return m.SelectQueueFunc(band)
203+
}
204+
return nil, nil
205+
}
206+
207+
var _ framework.InterFlowDispatchPolicy = &MockInterFlowDispatchPolicy{}

0 commit comments

Comments
 (0)