@@ -20,6 +20,7 @@ import (
2020 "context"
2121 "encoding/json"
2222 "os"
23+ "reflect"
2324 "testing"
2425 "time"
2526
@@ -46,6 +47,8 @@ const (
4647 test1Type = "test-one"
4748 test2Type = "test-two"
4849 testPickerType = "test-picker"
50+ testSourceType = "test-source"
51+ testExtractorType = "test-extractor"
4952)
5053
5154type testStruct struct {
@@ -82,6 +85,12 @@ func TestLoadRawConfiguration(t *testing.T) {
8285 Name : "testPicker" ,
8386 Type : testPickerType ,
8487 },
88+ {
89+ Type : testSourceType ,
90+ },
91+ {
92+ Type : testExtractorType ,
93+ },
8594 },
8695 SchedulingProfiles : []configapi.SchedulingProfile {
8796 {
@@ -100,6 +109,14 @@ func TestLoadRawConfiguration(t *testing.T) {
100109 },
101110 },
102111 },
112+ Data : & configapi.DataLayerConfig {
113+ Sources : []configapi.DataLayerSource {
114+ {
115+ PluginRef : "test-source" ,
116+ Extractors : []string {"test-extractor" },
117+ },
118+ },
119+ },
103120 FeatureGates : configapi.FeatureGates {datalayer .FeatureGate },
104121 SaturationDetector : & configapi.SaturationDetector {
105122 MetricsStalenessThreshold : metav1.Duration {Duration : 150 * time .Millisecond },
@@ -188,6 +205,14 @@ func TestLoadRawConfigurationWithDefaults(t *testing.T) {
188205 Name : "testPicker" ,
189206 Type : testPickerType ,
190207 },
208+ {
209+ Name : testSourceType ,
210+ Type : testSourceType ,
211+ },
212+ {
213+ Name : testExtractorType ,
214+ Type : testExtractorType ,
215+ },
191216 },
192217 SchedulingProfiles : []configapi.SchedulingProfile {
193218 {
@@ -206,6 +231,14 @@ func TestLoadRawConfigurationWithDefaults(t *testing.T) {
206231 },
207232 },
208233 },
234+ Data : & configapi.DataLayerConfig {
235+ Sources : []configapi.DataLayerSource {
236+ {
237+ PluginRef : "test-source" ,
238+ Extractors : []string {"test-extractor" },
239+ },
240+ },
241+ },
209242 FeatureGates : configapi.FeatureGates {datalayer .FeatureGate },
210243 SaturationDetector : & configapi.SaturationDetector {
211244 QueueDepthThreshold : saturationdetector .DefaultQueueDepthThreshold ,
@@ -358,7 +391,7 @@ func checkError(t *testing.T, function string, test testStruct, err error) {
358391 if ! test .wantErr {
359392 t .Fatalf ("In test '%s' %s returned unexpected error: %v, want %v" , test .name , function , err , test .wantErr )
360393 }
361- t .Logf ("error was %s" , err )
394+ t .Logf ("error in %s was %s" , test . name , err )
362395 } else if test .wantErr {
363396 t .Fatalf ("In test %s %s did not return an expected error" , test .name , function )
364397 }
@@ -459,6 +492,21 @@ func TestLoadConfig(t *testing.T) {
459492 configText : errorUnknownFeatureGateText ,
460493 wantErr : true ,
461494 },
495+ {
496+ name : "errorMissingDataConfig" ,
497+ configText : errorMissingDataConfigText ,
498+ wantErr : true ,
499+ },
500+ {
501+ name : "errorBadSourceReference" ,
502+ configText : errorBadSourceReferenceText ,
503+ wantErr : true ,
504+ },
505+ {
506+ name : "errorBadExtractorReference" ,
507+ configText : errorBadExtractorReferenceText ,
508+ wantErr : true ,
509+ },
462510 }
463511
464512 registerNeededFeatureGates ()
@@ -577,13 +625,20 @@ plugins:
577625 blockSize: 32
578626- name: testPicker
579627 type: test-picker
628+ - type: test-source
629+ - type: test-extractor
580630schedulingProfiles:
581631- name: default
582632 plugins:
583633 - pluginRef: test1
584634 - pluginRef: test-two
585635 weight: 50
586636 - pluginRef: testPicker
637+ data:
638+ sources:
639+ - pluginRef: test-source
640+ extractors:
641+ - test-extractor
587642featureGates:
588643- dataLayer
589644saturationDetector:
@@ -768,6 +823,72 @@ featureGates:
768823- qwerty
769824`
770825
826+ // datalayer enabled without config
827+ //
828+ //nolint:dupword
829+ const errorMissingDataConfigText = `
830+ apiVersion: inference.networking.x-k8s.io/v1alpha1
831+ kind: EndpointPickerConfig
832+ plugins:
833+ - name: test1
834+ type: test-one
835+ parameters:
836+ threshold: 10
837+ schedulingProfiles:
838+ - name: default
839+ plugins:
840+ - pluginRef: test1
841+ featureGates:
842+ - dataLayer
843+ `
844+
845+ // error bad DataSource plugin reference
846+ //
847+ //nolint:dupword
848+ const errorBadSourceReferenceText = `
849+ apiVersion: inference.networking.x-k8s.io/v1alpha1
850+ kind: EndpointPickerConfig
851+ plugins:
852+ - name: test1
853+ type: test-one
854+ parameters:
855+ threshold: 10
856+ schedulingProfiles:
857+ - name: default
858+ plugins:
859+ - pluginRef: test1
860+ data:
861+ sources:
862+ - pluginRef: test-one
863+ featureGates:
864+ - dataLayer
865+ `
866+
867+ // error bad Extractor plugin reference
868+ //
869+ //nolint:dupword
870+ const errorBadExtractorReferenceText = `
871+ apiVersion: inference.networking.x-k8s.io/v1alpha1
872+ kind: EndpointPickerConfig
873+ plugins:
874+ - name: test1
875+ type: test-one
876+ parameters:
877+ threshold: 10
878+ - type: test-source
879+ schedulingProfiles:
880+ - name: default
881+ plugins:
882+ - pluginRef: test1
883+ data:
884+ sources:
885+ - pluginRef: test-source
886+ extractors:
887+ - test-one
888+ featureGates:
889+ - dataLayer
890+ `
891+
771892// compile-time type validation
772893var _ framework.Filter = & test1 {}
773894
@@ -858,6 +979,60 @@ func (p *testProfileHandler) ProcessResults(_ context.Context, _ *types.CycleSta
858979 return nil , nil
859980}
860981
982+ // compile-time type validation
983+ var _ datalayer.DataSource = & testSource {}
984+
985+ type testSource struct {
986+ typedName plugins.TypedName
987+ }
988+
989+ func newTestSource () * testSource {
990+ return & testSource {
991+ typedName : plugins.TypedName {Type : testSourceType , Name : "test-source" },
992+ }
993+ }
994+
995+ func (s * testSource ) TypedName () plugins.TypedName {
996+ return s .typedName
997+ }
998+
999+ func (s * testSource ) AddExtractor (_ datalayer.Extractor ) error {
1000+ return nil
1001+ }
1002+
1003+ func (s * testSource ) Collect (ctx context.Context , ep datalayer.Endpoint ) error {
1004+ return nil
1005+ }
1006+
1007+ func (s * testSource ) Extractors () []string {
1008+ return []string {}
1009+ }
1010+
1011+ // compile-time type validation
1012+ var _ datalayer.Extractor = & testExtractor {}
1013+
1014+ type testExtractor struct {
1015+ typedName plugins.TypedName
1016+ }
1017+
1018+ func newTestExtractor () * testExtractor {
1019+ return & testExtractor {
1020+ typedName : plugins.TypedName {Type : testExtractorType , Name : "test-extractor" },
1021+ }
1022+ }
1023+
1024+ func (e * testExtractor ) TypedName () plugins.TypedName {
1025+ return e .typedName
1026+ }
1027+
1028+ func (e * testExtractor ) ExpectedInputType () reflect.Type {
1029+ return reflect .TypeOf ("" )
1030+ }
1031+
1032+ func (e * testExtractor ) Extract (ctx context.Context , data any , ep datalayer.Endpoint ) error {
1033+ return nil
1034+ }
1035+
8611036func registerTestPlugins () {
8621037 plugins .Register (test1Type ,
8631038 func (_ string , parameters json.RawMessage , _ plugins.Handle ) (plugins.Plugin , error ) {
@@ -884,6 +1059,18 @@ func registerTestPlugins() {
8841059 return newTestProfileHandler (), nil
8851060 },
8861061 )
1062+
1063+ plugins .Register (testSourceType ,
1064+ func (_ string , _ json.RawMessage , _ plugins.Handle ) (plugins.Plugin , error ) {
1065+ return newTestSource (), nil
1066+ },
1067+ )
1068+
1069+ plugins .Register (testExtractorType ,
1070+ func (_ string , _ json.RawMessage , _ plugins.Handle ) (plugins.Plugin , error ) {
1071+ return newTestExtractor (), nil
1072+ },
1073+ )
8871074}
8881075
8891076// valid configuration
0 commit comments