@@ -19,6 +19,7 @@ package epp
19
19
import (
20
20
"errors"
21
21
"fmt"
22
+ "log"
22
23
"os"
23
24
"strings"
24
25
"testing"
@@ -36,6 +37,7 @@ import (
36
37
infextv1 "sigs.k8s.io/gateway-api-inference-extension/api/v1"
37
38
infextv1a2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
38
39
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/env"
40
+ infextv1a2 "sigs.k8s.io/gateway-api-inference-extension/apix/v1alpha2"
39
41
testutils "sigs.k8s.io/gateway-api-inference-extension/test/utils"
40
42
41
43
"helm.sh/helm/v3/pkg/chart/loader"
@@ -84,6 +86,10 @@ const (
84
86
metricsRbacManifest = "../../testdata/metrics-rbac.yaml"
85
87
// modelServerManifestFilepathEnvVar is the env var that holds absolute path to the manifest for the model server test resource.
86
88
modelServerManifestFilepathEnvVar = "MANIFEST_PATH"
89
+ // replicaCount is the number of replicas of EPP.
90
+ replicaCount = 3
91
+
92
+ name = "vllm-llama3-8b-instruct"
87
93
)
88
94
89
95
const e2eLeaderElectionEnabledEnvVar = "E2E_LEADER_ELECTION_ENABLED"
@@ -102,15 +108,29 @@ func TestAPIs(t *testing.T) {
102
108
)
103
109
}
104
110
105
- func renderCharts (nsName string ) []string {
106
- chartPath := "./ charts/inferencepool" // Path to your Helm chart
111
+ func renderChartsToYamls (nsName string ) []string {
112
+ chartPath := "/usr/local/google/home/rahulgurnani/gateway-api-inference-extension/config/ charts/inferencepool"
107
113
chart , err := loader .Load (chartPath )
108
114
if err != nil {
109
115
panic (fmt .Sprintf ("Failed to load chart: %v" , err ))
110
116
}
111
- values , _ := chartutil .ReadValuesFile ("charts/inferencepool/values.yaml" )
117
+ values , _ := chartutil .ReadValuesFile ("/usr/local/google/home/rahulgurnani/gateway-api-inference-extension/config/charts/inferencepool/values.yaml" )
118
+ infExt , ok := values ["inferenceExtension" ].(map [string ]interface {})
119
+ if ok {
120
+ infExt ["replicas" ] = replicaCount
121
+ fmt .Println (infExt )
122
+ flags , ok := infExt ["flags" ].([]interface {})
123
+ if ok {
124
+ flags = append (flags , map [string ]string {
125
+ "name" : "ha-enable-leader-election" ,
126
+ "value" : "true" ,
127
+ })
128
+ infExt ["flags" ] = flags
129
+ }
130
+ }
131
+
112
132
options := chartutil.ReleaseOptions {
113
- Name : "vllm-llama3-8b-instruct" ,
133
+ Name : name ,
114
134
Namespace : nsName ,
115
135
}
116
136
renderValues , err := chartutil .ToRenderValues (chart , values , options , nil )
@@ -122,11 +142,22 @@ func renderCharts(nsName string) []string {
122
142
if err != nil {
123
143
panic (fmt .Sprintf ("Failed to render chart: %v" , err ))
124
144
}
125
- fmt .Println (rendered )
126
145
var renderedValues []string
127
- for _ , v := range rendered {
128
- renderedValues = append (renderedValues , v )
146
+ for fName , renderedChart := range rendered {
147
+ if strings .Contains (fName , "NOTES.txt" ) {
148
+ continue
149
+ }
150
+
151
+ fmt .Println ("----------------rendered----------------" )
152
+ fmt .Println (fName )
153
+ objs := strings .Split (renderedChart , "\n ---" )
154
+ for _ , obj := range objs {
155
+ fmt .Println ("-----------obj-----------" )
156
+ fmt .Println (obj )
157
+ renderedValues = append (renderedValues , obj )
158
+ }
129
159
}
160
+
130
161
return renderedValues
131
162
}
132
163
@@ -144,6 +175,7 @@ var _ = ginkgo.BeforeSuite(func() {
144
175
leaderElectionEnabled = true
145
176
ginkgo .By ("Leader election test mode enabled via " + e2eLeaderElectionEnabledEnvVar )
146
177
}
178
+ leaderElectionEnabled = true
147
179
148
180
ginkgo .By ("Setting up the test suite" )
149
181
setupSuite ()
@@ -165,8 +197,8 @@ func setupInfra() {
165
197
}
166
198
crds := map [string ]string {
167
199
"inferencepools.inference.networking.x-k8s.io" : xInferPoolManifest ,
168
- "inferenceobjectives.inference.networking.x-k8s.io" : xInferObjectiveManifest ,
169
200
"inferencepools.inference.networking.k8s.io" : inferPoolManifest ,
201
+ "inferenceobjectives.inference.networking.x-k8s.io" : xInferObjectiveManifest ,
170
202
}
171
203
172
204
createCRDs (testConfig , crds )
@@ -179,6 +211,10 @@ func setupInfra() {
179
211
createClient (testConfig , clientManifest )
180
212
createEnvoy (testConfig , envoyManifest )
181
213
createMetricsRbac (testConfig , metricsRbacManifest )
214
+ createInferExt (cli )
215
+ createClient (cli , clientManifest )
216
+ createEnvoy (cli , envoyManifest )
217
+ createMetricsRbac (cli , metricsRbacManifest )
182
218
// Run this step last, as it requires additional time for the model server to become ready.
183
219
ginkgo .By ("Creating model server resources from manifest: " + modelServerManifestPath )
184
220
createModelServer (testConfig , modelServerManifestArray )
@@ -214,6 +250,8 @@ func setupSuite() {
214
250
215
251
err = infextv1a2 .Install (testConfig .Scheme )
216
252
// err = infextv1a2.Install(scheme)
253
+ // TODO: Fix the v1a2 chart
254
+ err = infextv1a2 .Install (scheme )
217
255
gomega .ExpectWithOffset (1 , err ).NotTo (gomega .HaveOccurred ())
218
256
219
257
err = infextv1 .Install (testConfig .Scheme )
@@ -362,9 +400,13 @@ func createInferExt(testConfig *testutils.TestConfig, filePath string) {
362
400
}
363
401
func createInferExt (k8sClient client.Client , filePath string ) {
364
402
outManifests := renderCharts (nsName )
403
+ func createInferExt (k8sClient client.Client ) {
404
+ outManifests := renderChartsToYamls (nsName )
365
405
366
406
ginkgo .By ("Creating inference extension resources from manifest: " + filePath )
367
407
testutils .CreateObjsFromYaml (testConfig , outManifests )
408
+ ginkgo .By ("Creating inference extension resources from outManifests" )
409
+ createObjsFromYaml (k8sClient , outManifests )
368
410
369
411
// Wait for the deployment to exist.
370
412
deploy := & appsv1.Deployment {
@@ -378,5 +420,65 @@ func createInferExt(k8sClient client.Client, filePath string) {
378
420
testutils .DeploymentReadyReplicas (testConfig , deploy , 1 )
379
421
} else {
380
422
testutils .DeploymentAvailable (testConfig , deploy )
423
+ testutils .DeploymentAvailable (ctx , k8sClient , deploy , modelReadyTimeout , interval )
424
+ }
425
+
426
+ // Wait for the service to exist.
427
+ testutils .EventuallyExists (ctx , func () error {
428
+ return k8sClient .Get (ctx , types.NamespacedName {Namespace : nsName , Name : inferExtName }, & corev1.Service {})
429
+ }, existsTimeout , interval )
430
+ }
431
+
432
+ // applyYAMLFile reads a file containing YAML (possibly multiple docs)
433
+ // and applies each object to the cluster.
434
+ func applyYAMLFile (k8sClient client.Client , filePath string ) {
435
+ // Create the resources from the manifest file
436
+ createObjsFromYaml (k8sClient , readYaml (filePath ))
437
+ }
438
+
439
+ func readYaml (filePath string ) []string {
440
+ ginkgo .By ("Reading YAML file: " + filePath )
441
+ yamlBytes , err := os .ReadFile (filePath )
442
+ gomega .Expect (err ).NotTo (gomega .HaveOccurred ())
443
+
444
+ // Split multiple docs, if needed
445
+ return strings .Split (string (yamlBytes ), "\n ---" )
446
+ }
447
+
448
+ func createObjsFromYaml (k8sClient client.Client , docs []string ) {
449
+ // For each doc, decode and create
450
+ decoder := serializer .NewCodecFactory (scheme ).UniversalDeserializer ()
451
+ for _ , doc := range docs {
452
+ trimmed := strings .TrimSpace (doc )
453
+ if trimmed == "" {
454
+ continue
455
+ }
456
+
457
+ // Decode into a runtime.Object
458
+ obj , gvk , decodeErr := decoder .Decode ([]byte (trimmed ), nil , nil )
459
+ if decodeErr != nil {
460
+ log .Printf ("Trimmed: %s" , trimmed )
461
+ continue
462
+ }
463
+ gomega .Expect (decodeErr ).NotTo (gomega .HaveOccurred (),
464
+ "Failed to decode YAML document to a Kubernetes object" )
465
+
466
+ ginkgo .By (fmt .Sprintf ("Decoded GVK: %s" , gvk ))
467
+
468
+ unstrObj , ok := obj .(* unstructured.Unstructured )
469
+ if ! ok {
470
+ // Fallback if it's a typed object
471
+ unstrObj = & unstructured.Unstructured {}
472
+ // Convert typed to unstructured
473
+ err := scheme .Convert (obj , unstrObj , nil )
474
+ gomega .Expect (err ).NotTo (gomega .HaveOccurred ())
475
+ }
476
+
477
+ unstrObj .SetNamespace (nsName )
478
+
479
+ // Create the object
480
+ err := k8sClient .Create (ctx , unstrObj )
481
+ gomega .Expect (err ).NotTo (gomega .HaveOccurred (),
482
+ "Failed to create object from YAML" )
381
483
}
382
484
}
0 commit comments