Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deploy/stacks/self-managed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
out/
76 changes: 72 additions & 4 deletions tests/bdd/features/single-cluster-helmfile.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -180,6 +181,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-echo"

# 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
"""
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:
Expand All @@ -206,3 +215,62 @@ 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.
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

# 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
# <functionId>/<model>. 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:
"""
${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

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

# 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
"""
Then the command exit code should be 0
And the command output should contain "chat.completion"
And the command output should contain "fixed 128-byte response"

# 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 exit code should be 0
And the command output should contain "401"

# 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
"""
Then the command exit code should be 0
4 changes: 4 additions & 0 deletions tests/bdd/fixtures/self-managed-local-bdd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ 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 "dummy" in the
# self-managed API profile; the Background overlays the placeholders.
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).
Expand Down
28 changes: 28 additions & 0 deletions tests/bdd/godog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,18 @@ 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":"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,
Stdout: "401",
},
// Conflict precheck: feature asserts the conflicting
// multi-cluster control-plane is absent.
"k3d cluster get ncp-local-cp": {ExitCode: 1},
Expand Down Expand Up @@ -462,6 +474,22 @@ 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:local",
"--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, "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")
}
}

// TestObservabilityControlFeatureFileWiresToSteps runs the live-install
Expand Down
Loading