From 2ffabec306f76a0084101c24020e2c747f168646 Mon Sep 17 00:00:00 2001 From: along Date: Thu, 20 Aug 2026 19:34:39 -0700 Subject: [PATCH 1/8] test(bdd): invoke an LLM function in the single-cluster helmfile feature Add an @llm-function-type scenario after the echo function lifecycle: create a function of type LLM backed by the OpenAI-compatible sample image, deploy it, invoke a chat completion through the LLM gateway, and assert an unauthenticated gateway request returns 401. The wiring test seeds canned invoke and curl results and asserts the LLM create, invoke, and no-auth commands ran. Relates to #1019 Signed-off-by: along --- .../features/single-cluster-helmfile.feature | 46 +++++++++++++++++++ tests/bdd/godog_test.go | 23 ++++++++++ 2 files changed, 69 insertions(+) diff --git a/tests/bdd/features/single-cluster-helmfile.feature b/tests/bdd/features/single-cluster-helmfile.feature index 7efeccd26..8617352ca 100644 --- a/tests/bdd/features/single-cluster-helmfile.feature +++ b/tests/bdd/features/single-cluster-helmfile.feature @@ -206,3 +206,49 @@ Feature: Install a local single-cluster NVCF stack with Helmfile """ Then the command exit code should be 0 And the command output should contain "bdd-grpc-echo" + + # The LLM scenario proves the serve path the @llm-gateway scenario + # only installs: an LLM-type function is routed through the + # llm-api-gateway and llm-request-router instead of the standard + # invocation path. The CLI derives the gateway host from the invoke + # URL (invocation.localhost -> llm.localhost) and rewrites the + # request body model to /, so the scenario only + # supplies the OpenAI-compatible path and the model name. + # Depends on the earlier control-plane install and NVCA + # registration scenarios in this feature run; not a standalone + # tag target. + @llm-function-type + Scenario: Operator creates, deploys, and invokes an LLM-type OpenAI-compatible sample function + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function create --name bdd-openai-compatible-sample --image nvcr.io/${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM}/nvcf-openai-compatible-sample:1.0.0 --function-type LLM --inference-url /v1/chat/completions --inference-port 8000 --health-uri /health --health-port 8000 --health-timeout PT30S --llm-model 'name=openai-compatible-sample,uris=/v1/chat/completions|/v1/embeddings,routingMethod=round_robin' + """ + Then the command exit code should be 0 + + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function deploy create --gpu H100 --instance-type NCP.GPU.H100_8x --backend ncp-local --regions us-west-1 --min-instances 1 --max-instances 1 --timeout 900 + """ + Then the command exit code should be 0 + + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml api-key generate --description bdd-openai-compatible-sample --for function --scopes invoke_function,list_functions,queue_details,list_functions_details + """ + Then the command exit code should be 0 + + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function invoke --inference-url /v1/chat/completions --model-name openai-compatible-sample --request-body '{"messages":[{"role":"user","content":"bdd-llm-echo"}]}' --timeout 120 + """ + Then the command exit code should be 0 + And the command output should contain "chat.completion" + + # The gateway must reject requests that carry no API key. curl + # reports only the status code so the assertion cannot match + # response-body noise. + When I run command: + """ + curl -s -o /dev/null -w "%{http_code}" -X POST http://llm.localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"unauthenticated/check","messages":[]}' + """ + Then the command output should contain "401" diff --git a/tests/bdd/godog_test.go b/tests/bdd/godog_test.go index 91a8571f2..27e1154e3 100644 --- a/tests/bdd/godog_test.go +++ b/tests/bdd/godog_test.go @@ -411,6 +411,16 @@ func TestSingleClusterHelmfileFeatureFileWiresToSteps(t *testing.T) { ExitCode: 0, Stdout: "Function invocation completed!\n\nResponse:\n{\"message\":\"bdd-grpc-echo\"}\n", }, + "/usr/bin/nvcf-cli --config /repo-root-placeholder/tests/bdd/fixtures/nvcf-cli-local.yaml function invoke" + + " --inference-url /v1/chat/completions --model-name openai-compatible-sample" + + " --request-body '{\"messages\":[{\"role\":\"user\",\"content\":\"bdd-llm-echo\"}]}' --timeout 120": { + ExitCode: 0, + Stdout: "Function invocation completed!\n\nResponse:\n{\"object\":\"chat.completion\",\"choices\":[{\"message\":{\"content\":\"bdd-llm-echo\"}}]}\n", + }, + `curl -s -o /dev/null -w "%{http_code}" -X POST http://llm.localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"unauthenticated/check","messages":[]}'`: { + ExitCode: 0, + Stdout: "401", + }, // Conflict precheck: feature asserts the conflicting // multi-cluster control-plane is absent. "k3d cluster get ncp-local-cp": {ExitCode: 1}, @@ -462,6 +472,19 @@ func TestSingleClusterHelmfileFeatureFileWiresToSteps(t *testing.T) { if !commandRanThatContains(suite.Runner.(*fakeRunner).runs, "api-key generate --description bdd-grpc-load-tester-supreme --for function") { t.Fatal("gRPC sample function API key was not generated for the function service") } + if !commandRanThatContainsAll(suite.Runner.(*fakeRunner).runs, + "function create --name bdd-openai-compatible-sample", + "nvcf-openai-compatible-sample:1.0.0", + "--function-type LLM", + "--llm-model") { + t.Fatal("LLM sample function was not created with the LLM function type and model config") + } + if !commandRanThatContains(suite.Runner.(*fakeRunner).runs, "function invoke --inference-url /v1/chat/completions --model-name openai-compatible-sample") { + t.Fatal("LLM function invoke CLI command was never invoked") + } + if !commandRanThatContains(suite.Runner.(*fakeRunner).runs, "http://llm.localhost:8080/v1/chat/completions") { + t.Fatal("unauthenticated LLM gateway check was never invoked") + } } // TestObservabilityControlFeatureFileWiresToSteps runs the live-install From c5297ac9a16547e9fd2df3547a075c5f8f031a7b Mon Sep 17 00:00:00 2001 From: along Date: Thu, 20 Aug 2026 19:37:29 -0700 Subject: [PATCH 2/8] test(bdd): address review findings on the LLM scenario Strengthen the invoke assertion with a choices check, assert the curl exit code, correct the comment describing the LLM Host-header routing, and document why the gateway invoke has no poll duration. Relates to #1019 Signed-off-by: along --- .../features/single-cluster-helmfile.feature | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/bdd/features/single-cluster-helmfile.feature b/tests/bdd/features/single-cluster-helmfile.feature index 8617352ca..0f85ab397 100644 --- a/tests/bdd/features/single-cluster-helmfile.feature +++ b/tests/bdd/features/single-cluster-helmfile.feature @@ -210,10 +210,11 @@ Feature: Install a local single-cluster NVCF stack with Helmfile # The LLM scenario proves the serve path the @llm-gateway scenario # only installs: an LLM-type function is routed through the # llm-api-gateway and llm-request-router instead of the standard - # invocation path. The CLI derives the gateway host from the invoke - # URL (invocation.localhost -> llm.localhost) and rewrites the - # request body model to /, so the scenario only - # supplies the OpenAI-compatible path and the model name. + # invocation path. For LLM functions the CLI overrides the request + # Host header with the LLM gateway host derived from the profile's + # invoke host (invocation.localhost -> llm.localhost) and rewrites + # the request body model to /, so the scenario + # only supplies the OpenAI-compatible path and the model name. # Depends on the earlier control-plane install and NVCA # registration scenarios in this feature run; not a standalone # tag target. @@ -237,12 +238,17 @@ Feature: Install a local single-cluster NVCF stack with Helmfile """ Then the command exit code should be 0 + # The gateway path answers synchronously, so no --poll-duration + # (the echo scenarios poll the 202 queue path). "choices" guards + # against a degenerate empty envelope; the assertion is tightened + # to the sample's reply content once the live run pins it. When I run command: """ ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function invoke --inference-url /v1/chat/completions --model-name openai-compatible-sample --request-body '{"messages":[{"role":"user","content":"bdd-llm-echo"}]}' --timeout 120 """ Then the command exit code should be 0 And the command output should contain "chat.completion" + And the command output should contain "choices" # The gateway must reject requests that carry no API key. curl # reports only the status code so the assertion cannot match @@ -251,4 +257,5 @@ Feature: Install a local single-cluster NVCF stack with Helmfile """ curl -s -o /dev/null -w "%{http_code}" -X POST http://llm.localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"unauthenticated/check","messages":[]}' """ - Then the command output should contain "401" + Then the command exit code should be 0 + And the command output should contain "401" From 70b244582d11c15f73300c130b22d1edae0fff5a Mon Sep 17 00:00:00 2001 From: along Date: Thu, 20 Aug 2026 21:29:17 -0700 Subject: [PATCH 3/8] test(bdd): reference the published multi-arch sample image tag The OpenAI-compatible sample is published multi-arch under the local tag, not a semver tag. Point the LLM scenario and its wiring assertion at the tag that exists. Relates to #1019 Signed-off-by: along --- tests/bdd/features/single-cluster-helmfile.feature | 2 +- tests/bdd/godog_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bdd/features/single-cluster-helmfile.feature b/tests/bdd/features/single-cluster-helmfile.feature index 0f85ab397..de68d3e4c 100644 --- a/tests/bdd/features/single-cluster-helmfile.feature +++ b/tests/bdd/features/single-cluster-helmfile.feature @@ -222,7 +222,7 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Scenario: Operator creates, deploys, and invokes an LLM-type OpenAI-compatible sample function When I run command: """ - ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function create --name bdd-openai-compatible-sample --image nvcr.io/${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM}/nvcf-openai-compatible-sample:1.0.0 --function-type LLM --inference-url /v1/chat/completions --inference-port 8000 --health-uri /health --health-port 8000 --health-timeout PT30S --llm-model 'name=openai-compatible-sample,uris=/v1/chat/completions|/v1/embeddings,routingMethod=round_robin' + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function create --name bdd-openai-compatible-sample --image nvcr.io/${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM}/nvcf-openai-compatible-sample:local --function-type LLM --inference-url /v1/chat/completions --inference-port 8000 --health-uri /health --health-port 8000 --health-timeout PT30S --llm-model 'name=openai-compatible-sample,uris=/v1/chat/completions|/v1/embeddings,routingMethod=round_robin' """ Then the command exit code should be 0 diff --git a/tests/bdd/godog_test.go b/tests/bdd/godog_test.go index 27e1154e3..6ea289cd2 100644 --- a/tests/bdd/godog_test.go +++ b/tests/bdd/godog_test.go @@ -474,7 +474,7 @@ func TestSingleClusterHelmfileFeatureFileWiresToSteps(t *testing.T) { } if !commandRanThatContainsAll(suite.Runner.(*fakeRunner).runs, "function create --name bdd-openai-compatible-sample", - "nvcf-openai-compatible-sample:1.0.0", + "nvcf-openai-compatible-sample:local", "--function-type LLM", "--llm-model") { t.Fatal("LLM sample function was not created with the LLM function type and model config") From 37bc2b815a5ed3ebc57f186b94555fe8778518cb Mon Sep 17 00:00:00 2001 From: along Date: Thu, 20 Aug 2026 21:47:10 -0700 Subject: [PATCH 4/8] chore(self-managed): ignore the stack render output directory make template and the CLI install path write rendered manifests and the control-plane profile under out/, which showed up as untracked noise. The compute-plane stack already ignores its out/ the same way. Relates to #1019 Signed-off-by: along --- deploy/stacks/self-managed/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 deploy/stacks/self-managed/.gitignore diff --git a/deploy/stacks/self-managed/.gitignore b/deploy/stacks/self-managed/.gitignore new file mode 100644 index 000000000..89f9ac04a --- /dev/null +++ b/deploy/stacks/self-managed/.gitignore @@ -0,0 +1 @@ +out/ From ec9e6582a01e4453d25e7bec3b2f196bf8489dd6 Mon Sep 17 00:00:00 2001 From: along Date: Thu, 20 Aug 2026 22:32:42 -0700 Subject: [PATCH 5/8] test(bdd): unblock the LLM scenario on local sizing Two live-run failures fixed. The LLM function pod could not schedule: each function pod's utils sidecar requests 4 CPU and the echo scenarios left their deployments running, exhausting the GPU nodes on the documented 12-CPU local sizing. Every function scenario now removes its deployment after invoking. The LLM router client sidecar image also defaults to the literal dummy in the self-managed API profile, so the fixture and Background now set it to the sample org's stargate-client, mirroring the multi-cluster fixture. Relates to #1019 Signed-off-by: along --- .../features/single-cluster-helmfile.feature | 35 ++++++++++++++++--- .../bdd/fixtures/self-managed-local-bdd.yaml | 5 +++ tests/bdd/godog_test.go | 3 ++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/tests/bdd/features/single-cluster-helmfile.feature b/tests/bdd/features/single-cluster-helmfile.feature index de68d3e4c..e04bdaf2e 100644 --- a/tests/bdd/features/single-cluster-helmfile.feature +++ b/tests/bdd/features/single-cluster-helmfile.feature @@ -20,10 +20,11 @@ Feature: Install a local single-cluster NVCF stack with Helmfile # ingress.gatewayApi.*). The Background only overlays the operator-specific # values that vary per NGC org and pull-secret name. And I update yaml file "deploy/stacks/self-managed/environments/local-bdd.yaml" with keys: - | global.imagePullSecrets[0].name | nvcr-pull-secret | - | global.helm.sources.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} | - | global.image.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} | - | observability.profile | disabled | + | global.imagePullSecrets[0].name | nvcr-pull-secret | + | global.helm.sources.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} | + | global.image.repository | ${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM} | + | api.env.NVCF_SIDECARS_LLM_ROUTER_CLIENT_IMAGE | nvcr.io/${SAMPLE_NGC_ORG}/${SAMPLE_NGC_TEAM}/stargate-client:0.2.0 | + | observability.profile | disabled | And I copy the file "tests/bdd/fixtures/nvcf-compute-plane-local-bdd.yaml" to "deploy/stacks/nvcf-compute-plane/environments/local-bdd.yaml" And I update yaml file "deploy/stacks/nvcf-compute-plane/environments/local-bdd.yaml" with keys: | global.imagePullSecrets[0].name | nvcr-pull-secret | @@ -180,6 +181,16 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Then the command exit code should be 0 And the command output should contain "bdd-echo" + # Remove the deployment so its worker pod (whose utils sidecar + # requests 4 CPU) frees the GPU node for the later scenarios. + # The local sizing cannot hold every scenario's deployment at + # once. + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function delete --deployment-only + """ + Then the command exit code should be 0 + @function-lifecycle @grpc Scenario: Operator creates, deploys, and invokes the gRPC Load Tester Supreme sample function When I run command: @@ -207,6 +218,14 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Then the command exit code should be 0 And the command output should contain "bdd-grpc-echo" + # Free the GPU node for the LLM scenario; see the HTTP scenario's + # cleanup comment. + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function delete --deployment-only + """ + Then the command exit code should be 0 + # The LLM scenario proves the serve path the @llm-gateway scenario # only installs: an LLM-type function is routed through the # llm-api-gateway and llm-request-router instead of the standard @@ -259,3 +278,11 @@ Feature: Install a local single-cluster NVCF stack with Helmfile """ Then the command exit code should be 0 And the command output should contain "401" + + # Leave the cluster's GPU capacity free, same as the echo + # scenarios. + When I run command: + """ + ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function delete --deployment-only + """ + Then the command exit code should be 0 diff --git a/tests/bdd/fixtures/self-managed-local-bdd.yaml b/tests/bdd/fixtures/self-managed-local-bdd.yaml index a746c6ed6..abb8451a1 100644 --- a/tests/bdd/fixtures/self-managed-local-bdd.yaml +++ b/tests/bdd/fixtures/self-managed-local-bdd.yaml @@ -50,9 +50,14 @@ openbao: # Pylon exits at startup when the API advertises its default HTTPS dummy OTLP # endpoint because the current binary has no OpenTelemetry TLS provider. Keep # worker telemetry on HTTP in this fixture until Pylon supports HTTPS OTLP. +# +# The LLM router client sidecar image defaults to the literal "dummy" in +# the self-managed API profile; LLM-type function pods cannot pull it. +# The feature Background overlays the org/team placeholders below. api: env: MANAGEMENT_OTLP_TRACING_ENDPOINT: http://dummy:8282 + NVCF_SIDECARS_LLM_ROUTER_CLIENT_IMAGE: nvcr.io/REPLACE_WITH_SAMPLE_NGC_ORG/REPLACE_WITH_SAMPLE_NGC_TEAM/stargate-client:0.2.0 # LLM gateway talks to nvcf-api over plaintext gRPC in local dev # (api.nvcf.svc.cluster.local:9090 has no TLS). diff --git a/tests/bdd/godog_test.go b/tests/bdd/godog_test.go index 6ea289cd2..f8e150884 100644 --- a/tests/bdd/godog_test.go +++ b/tests/bdd/godog_test.go @@ -482,6 +482,9 @@ func TestSingleClusterHelmfileFeatureFileWiresToSteps(t *testing.T) { if !commandRanThatContains(suite.Runner.(*fakeRunner).runs, "function invoke --inference-url /v1/chat/completions --model-name openai-compatible-sample") { t.Fatal("LLM function invoke CLI command was never invoked") } + if !commandRanThatContains(suite.Runner.(*fakeRunner).runs, "function delete --deployment-only") { + t.Fatal("function deployment cleanup was never invoked") + } if !commandRanThatContains(suite.Runner.(*fakeRunner).runs, "http://llm.localhost:8080/v1/chat/completions") { t.Fatal("unauthenticated LLM gateway check was never invoked") } From c414cad00be04eac34b2dff42a14678df8605803 Mon Sep 17 00:00:00 2001 From: along Date: Thu, 20 Aug 2026 22:59:01 -0700 Subject: [PATCH 6/8] test(bdd): assert the LLM sample's reply content The live run confirmed the sample answers with its fixed load-testing message; assert that content instead of only the envelope shape. Relates to #1019 Signed-off-by: along --- tests/bdd/features/single-cluster-helmfile.feature | 8 ++++---- tests/bdd/godog_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/bdd/features/single-cluster-helmfile.feature b/tests/bdd/features/single-cluster-helmfile.feature index e04bdaf2e..4154e86a2 100644 --- a/tests/bdd/features/single-cluster-helmfile.feature +++ b/tests/bdd/features/single-cluster-helmfile.feature @@ -258,16 +258,16 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Then the command exit code should be 0 # The gateway path answers synchronously, so no --poll-duration - # (the echo scenarios poll the 202 queue path). "choices" guards - # against a degenerate empty envelope; the assertion is tightened - # to the sample's reply content once the live run pins it. + # (the echo scenarios poll the 202 queue path). The sample always + # answers with its fixed load-testing message, so the assertion + # checks that content rather than only the envelope shape. When I run command: """ ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function invoke --inference-url /v1/chat/completions --model-name openai-compatible-sample --request-body '{"messages":[{"role":"user","content":"bdd-llm-echo"}]}' --timeout 120 """ Then the command exit code should be 0 And the command output should contain "chat.completion" - And the command output should contain "choices" + And the command output should contain "fixed 128-byte response" # The gateway must reject requests that carry no API key. curl # reports only the status code so the assertion cannot match diff --git a/tests/bdd/godog_test.go b/tests/bdd/godog_test.go index f8e150884..a1c00aa0e 100644 --- a/tests/bdd/godog_test.go +++ b/tests/bdd/godog_test.go @@ -415,7 +415,7 @@ func TestSingleClusterHelmfileFeatureFileWiresToSteps(t *testing.T) { " --inference-url /v1/chat/completions --model-name openai-compatible-sample" + " --request-body '{\"messages\":[{\"role\":\"user\",\"content\":\"bdd-llm-echo\"}]}' --timeout 120": { ExitCode: 0, - Stdout: "Function invocation completed!\n\nResponse:\n{\"object\":\"chat.completion\",\"choices\":[{\"message\":{\"content\":\"bdd-llm-echo\"}}]}\n", + Stdout: "Function invocation completed!\n\nResponse:\n{\"object\":\"chat.completion\",\"choices\":[{\"message\":{\"content\":\"This is a fixed 128-byte response from an NVCF-hosted OpenAI-compatible sample, used for load testing and throughput benchmarks.\"}}]}\n", }, `curl -s -o /dev/null -w "%{http_code}" -X POST http://llm.localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"unauthenticated/check","messages":[]}'`: { ExitCode: 0, From 83fe41514c48f535600eebd1595149919ceaf7d7 Mon Sep 17 00:00:00 2001 From: along Date: Fri, 21 Aug 2026 10:48:40 -0700 Subject: [PATCH 7/8] test(bdd): wrap the canned LLM response for line length Relates to #1019 Signed-off-by: along --- tests/bdd/godog_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/bdd/godog_test.go b/tests/bdd/godog_test.go index a1c00aa0e..7b31c14cc 100644 --- a/tests/bdd/godog_test.go +++ b/tests/bdd/godog_test.go @@ -415,7 +415,9 @@ func TestSingleClusterHelmfileFeatureFileWiresToSteps(t *testing.T) { " --inference-url /v1/chat/completions --model-name openai-compatible-sample" + " --request-body '{\"messages\":[{\"role\":\"user\",\"content\":\"bdd-llm-echo\"}]}' --timeout 120": { ExitCode: 0, - Stdout: "Function invocation completed!\n\nResponse:\n{\"object\":\"chat.completion\",\"choices\":[{\"message\":{\"content\":\"This is a fixed 128-byte response from an NVCF-hosted OpenAI-compatible sample, used for load testing and throughput benchmarks.\"}}]}\n", + Stdout: "Function invocation completed!\n\nResponse:\n" + + `{"object":"chat.completion","choices":[{"message":{"content":"This is a fixed 128-byte response from an NVCF-hosted OpenAI-compatible sample, used for load testing and throughput benchmarks."}}]}` + + "\n", }, `curl -s -o /dev/null -w "%{http_code}" -X POST http://llm.localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"unauthenticated/check","messages":[]}'`: { ExitCode: 0, From 60704aace9d2d3f303b8db6ac594bcf5aee683f7 Mon Sep 17 00:00:00 2001 From: along Date: Fri, 21 Aug 2026 10:53:31 -0700 Subject: [PATCH 8/8] test(bdd): tighten scenario comments Relates to #1019 Signed-off-by: along --- .../features/single-cluster-helmfile.feature | 40 +++++++------------ .../bdd/fixtures/self-managed-local-bdd.yaml | 5 +-- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/tests/bdd/features/single-cluster-helmfile.feature b/tests/bdd/features/single-cluster-helmfile.feature index 4154e86a2..a85fdbe7c 100644 --- a/tests/bdd/features/single-cluster-helmfile.feature +++ b/tests/bdd/features/single-cluster-helmfile.feature @@ -181,10 +181,8 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Then the command exit code should be 0 And the command output should contain "bdd-echo" - # Remove the deployment so its worker pod (whose utils sidecar - # requests 4 CPU) frees the GPU node for the later scenarios. - # The local sizing cannot hold every scenario's deployment at - # once. + # Remove the deployment: the local sizing cannot hold every + # scenario's deployment at once. When I run command: """ ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function delete --deployment-only @@ -218,25 +216,19 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Then the command exit code should be 0 And the command output should contain "bdd-grpc-echo" - # Free the GPU node for the LLM scenario; see the HTTP scenario's - # cleanup comment. + # Free the GPU node for the LLM scenario. When I run command: """ ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function delete --deployment-only """ Then the command exit code should be 0 - # The LLM scenario proves the serve path the @llm-gateway scenario - # only installs: an LLM-type function is routed through the - # llm-api-gateway and llm-request-router instead of the standard - # invocation path. For LLM functions the CLI overrides the request - # Host header with the LLM gateway host derived from the profile's - # invoke host (invocation.localhost -> llm.localhost) and rewrites - # the request body model to /, so the scenario - # only supplies the OpenAI-compatible path and the model name. - # Depends on the earlier control-plane install and NVCA - # registration scenarios in this feature run; not a standalone - # tag target. + # Proves the serve path the @llm-gateway scenario only installs: + # LLM-type functions route through llm-api-gateway and + # llm-request-router. The CLI maps invocation.localhost to the + # llm.localhost gateway host and rewrites the body model to + # /. Depends on the earlier install and + # registration scenarios; not a standalone tag target. @llm-function-type Scenario: Operator creates, deploys, and invokes an LLM-type OpenAI-compatible sample function When I run command: @@ -257,10 +249,8 @@ Feature: Install a local single-cluster NVCF stack with Helmfile """ Then the command exit code should be 0 - # The gateway path answers synchronously, so no --poll-duration - # (the echo scenarios poll the 202 queue path). The sample always - # answers with its fixed load-testing message, so the assertion - # checks that content rather than only the envelope shape. + # The gateway answers synchronously (no queue polling). The + # sample always returns its fixed load-testing message. When I run command: """ ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function invoke --inference-url /v1/chat/completions --model-name openai-compatible-sample --request-body '{"messages":[{"role":"user","content":"bdd-llm-echo"}]}' --timeout 120 @@ -269,9 +259,8 @@ Feature: Install a local single-cluster NVCF stack with Helmfile And the command output should contain "chat.completion" And the command output should contain "fixed 128-byte response" - # The gateway must reject requests that carry no API key. curl - # reports only the status code so the assertion cannot match - # response-body noise. + # curl reports only the status code so the assertion cannot + # match response-body noise. When I run command: """ curl -s -o /dev/null -w "%{http_code}" -X POST http://llm.localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"unauthenticated/check","messages":[]}' @@ -279,8 +268,7 @@ Feature: Install a local single-cluster NVCF stack with Helmfile Then the command exit code should be 0 And the command output should contain "401" - # Leave the cluster's GPU capacity free, same as the echo - # scenarios. + # Leave the GPU capacity free, same as the echo scenarios. When I run command: """ ${NVCF_CLI} --config ${REPO_ROOT}/tests/bdd/fixtures/nvcf-cli-local.yaml function delete --deployment-only diff --git a/tests/bdd/fixtures/self-managed-local-bdd.yaml b/tests/bdd/fixtures/self-managed-local-bdd.yaml index abb8451a1..b4ed793ca 100644 --- a/tests/bdd/fixtures/self-managed-local-bdd.yaml +++ b/tests/bdd/fixtures/self-managed-local-bdd.yaml @@ -51,9 +51,8 @@ openbao: # endpoint because the current binary has no OpenTelemetry TLS provider. Keep # worker telemetry on HTTP in this fixture until Pylon supports HTTPS OTLP. # -# The LLM router client sidecar image defaults to the literal "dummy" in -# the self-managed API profile; LLM-type function pods cannot pull it. -# The feature Background overlays the org/team placeholders below. +# The LLM router client sidecar image defaults to "dummy" in the +# self-managed API profile; the Background overlays the placeholders. api: env: MANAGEMENT_OTLP_TRACING_ENDPOINT: http://dummy:8282