Skip to content

Commit 4fad1a9

Browse files
committed
feat(flowcontrol): Add bundled Flow Control config
Introduces a new top-level `Config` for the Flow Control layer. This config bundles the configurations for the `controller` and `registry` packages, providing a single, unified point of entry fo validation and default application. This simplifies the management and initialization of the flow control system by centralizing its configuration.
1 parent 30421ce commit 4fad1a9

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

pkg/epp/flowcontrol/config.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package flowcontrol
18+
19+
import (
20+
"fmt"
21+
22+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/controller"
23+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/registry"
24+
)
25+
26+
// Config is the top-level configuration for the entire flow control module.
27+
// It embeds the configurations for the controller and the registry, providing a single point of entry for validation
28+
// and initialization.
29+
type Config struct {
30+
Controller controller.Config
31+
Registry registry.Config
32+
}
33+
34+
// ValidateAndApplyDefaults checks the configuration for validity and populates any empty fields with system defaults.
35+
// It delegates validation to the underlying controller and registry configurations.
36+
// It returns a new, validated `Config` object and does not mutate the receiver.
37+
func (c *Config) ValidateAndApplyDefaults() (*Config, error) {
38+
validatedControllerCfg, err := c.Controller.ValidateAndApplyDefaults()
39+
if err != nil {
40+
return nil, fmt.Errorf("controller config validation failed: %w", err)
41+
}
42+
validatedRegistryCfg, err := c.Registry.ValidateAndApplyDefaults()
43+
if err != nil {
44+
return nil, fmt.Errorf("registry config validation failed: %w", err)
45+
}
46+
return &Config{
47+
Controller: *validatedControllerCfg,
48+
Registry: *validatedRegistryCfg,
49+
}, nil
50+
}

pkg/epp/flowcontrol/config_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package flowcontrol
18+
19+
import (
20+
"testing"
21+
"time"
22+
23+
"github.com/stretchr/testify/assert"
24+
"github.com/stretchr/testify/require"
25+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/controller"
26+
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/flowcontrol/registry"
27+
)
28+
29+
func TestConfig_ValidateAndApplyDefaults(t *testing.T) {
30+
t.Parallel()
31+
32+
// A minimal valid registry config, which is required for the success case.
33+
validRegistryConfig := registry.Config{
34+
PriorityBands: []registry.PriorityBandConfig{
35+
{Priority: 1, PriorityName: "TestBand"},
36+
},
37+
}
38+
39+
testCases := []struct {
40+
name string
41+
input Config
42+
expectErr bool
43+
expectedErrIs error
44+
}{
45+
{
46+
name: "ShouldSucceed_WhenSubConfigsAreValid",
47+
input: Config{
48+
Controller: controller.Config{},
49+
Registry: validRegistryConfig,
50+
},
51+
expectErr: false,
52+
},
53+
{
54+
name: "ShouldFail_WhenControllerConfigIsInvalid",
55+
input: Config{
56+
Controller: controller.Config{
57+
DefaultRequestTTL: -1 * time.Second,
58+
},
59+
Registry: validRegistryConfig,
60+
},
61+
expectErr: true,
62+
},
63+
{
64+
name: "ShouldFail_WhenRegistryConfigIsInvalid",
65+
input: Config{
66+
Controller: controller.Config{},
67+
Registry: registry.Config{
68+
PriorityBands: []registry.PriorityBandConfig{},
69+
},
70+
},
71+
expectErr: true,
72+
},
73+
}
74+
75+
for _, tc := range testCases {
76+
t.Run(tc.name, func(t *testing.T) {
77+
t.Parallel()
78+
originalInput := tc.input
79+
validatedCfg, err := tc.input.ValidateAndApplyDefaults()
80+
81+
if tc.expectErr {
82+
require.Error(t, err, "expected an error but got nil")
83+
} else {
84+
require.NoError(t, err, "expected no error but got: %v", err)
85+
require.NotNil(t, validatedCfg, "validatedCfg should not be nil on success")
86+
}
87+
88+
assert.Equal(t, originalInput, tc.input, "input config should not be mutated")
89+
})
90+
}
91+
}

0 commit comments

Comments
 (0)