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
564 changes: 492 additions & 72 deletions crates/e2e-report/src/lib.rs

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion tests/e2e-cucumber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,29 @@ There is no tag-filter tiering. Each CI job runs the **whole** suite
**pass / xfail / skip** at runtime from its capability tags plus the known-bug
matrix, then reconciles the actual result against that expectation.

### Naming

Each feature file has a short **key** that prefixes both its scenario names and
its ids. The key is usually the file's stem, but not always — `install_lifecycle`
uses `lifecycle` and `model_serving` uses `serve` — so `FEATURE_KEYS` in
`tests/feature_naming.rs` is the list, not this page:

- **Scenario name** — `Scenario: <key>-<NN> - <description>`, numbered
sequentially in declaration order. The report sorts the grid's rows by this
index, so it must match the order in the file. Without the key the index names
nothing: every file used to number from 1, so "1" meant eight different
scenarios.
- **`@id:`** — `<key>-<slug>`, so an id alone says which feature it belongs to.

`tests/feature_naming.rs` enforces all of this (sequential, unique suite-wide,
feature-qualified ids) in the ordinary `cargo test` run. Adding a feature file
means adding its key to `FEATURE_KEYS` there.

Scenarios carry stable-id and capability tags:

| Tag | Meaning |
|---|---|
| `@id:<slug>` | Stable scenario id. Keys the expectation matrix and the report grid; every scenario has one. |
| `@id:<key>-<slug>` | Stable scenario id, prefixed with its feature's key. Keys the expectation matrix and the report grid; every scenario has one. |
| `@requires-gpu` | Needs a usable AMD GPU. Resolves to **skip** (n/a) on a host with none — the mock job, or a WSL host whose ROCm passthrough is incomplete (`driver_status` other than `wsl_rocdxg_ready`), where the gfx target is reported but unreachable. |
| `@requires-bare-metal` | Premise is a host running the in-tree amdgpu driver, so it does not hold under WSL2. Resolves to **skip** there. `@requires-os:linux` cannot express this: WSL2 reports an `os_family` of `linux`. |
| `@requires-wsl` | The inverse: premise **is** a WSL2 host. Resolves to **skip** on native Linux, native Windows, and everything else. |
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e-cucumber/features/artifact_prefetch.feature
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Feature: Artifact prefetch cleanup

@id:artifact-prefetch-failed-marker-leaves-no-temp
Scenario: A failed artifact cache write leaves no temporary marker
Scenario: artifact-prefetch-01 - A failed artifact cache write leaves no temporary marker
Given a signed direct-download artifact fixture
And its cache marker destination is occupied by a directory
When the user approves the artifact prefetch
Expand Down
12 changes: 6 additions & 6 deletions tests/e2e-cucumber/features/bench.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ Feature: Benchmarking a served endpoint
# one of the two 404'd — and every request failure was swallowed, so the run
# still exited 0 with a row of blanks.
#
# Scenarios 1-3 run on every lane (MockServer-backed, no GPU needed) and are
# what pin the request path and the failure reporting. Scenario 4 is the
# bench-01 to bench-03 run on every lane (MockServer-backed, no GPU needed)
# and are what pin the request path and the failure reporting. bench-04 is the
# hardware proof against a really served model.

# The mock answers chat on BOTH the versioned and unversioned routes, so
# "the benchmark succeeded" alone would pass even with the bug present. This
# scenario therefore asserts which route the requests actually landed on.
@id:bench-load-reports-throughput
Scenario: 1 - Benchmarking a running server reports measured throughput
Scenario: bench-01 - Benchmarking a running server reports measured throughput
Given a model is being served
When the user benchmarks the served endpoint
Then the benchmark reports measured throughput
And the benchmark requests reached the versioned chat route

@id:bench-load-accepts-plain-address
Scenario: 2 - A plain host address is accepted and still reaches the server
Scenario: bench-02 - A plain host address is accepted and still reaches the server
Given a model is being served
When the user benchmarks the server using its plain host address
Then the benchmark reports measured throughput
And the benchmark requests reached the versioned chat route

@id:bench-load-surfaces-failures
Scenario: 3 - A benchmark whose every request is rejected fails loudly
Scenario: bench-03 - A benchmark whose every request is rejected fails loudly
Given an endpoint that rejects every request
When the user benchmarks the served endpoint
Then the benchmark reports that the requests failed
Expand All @@ -42,7 +42,7 @@ Feature: Benchmarking a served endpoint
# without an active ROCm runtime. Lemonade hosts do not need it, so omitting it
# fails on Instinct alone — mirror the sibling GPU serve scenarios and keep it.
@id:bench-load-real-serve @requires-gpu
Scenario: 4 - Benchmarking a really served model reports throughput
Scenario: bench-04 - Benchmarking a really served model reports throughput
Given a managed runtime is active
And a model is being served on GPU
When the user benchmarks the served endpoint
Expand Down
16 changes: 8 additions & 8 deletions tests/e2e-cucumber/features/chat.feature
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Feature: Chat and endpoint detection

@id:chat-served-model-discoverable
Scenario: 1 - A served model is discoverable through the services list
Scenario: chat-01 - A served model is discoverable through the services list
Given a model is being served
And the model is registered with the CLI
When the user checks for running services
Expand All @@ -13,7 +13,7 @@ Feature: Chat and endpoint detection
# offers it — the notice must precede any request. (Previously an
# untestable-black-box gap.)
@id:chat-privacy-notice-accurate @requires-os:linux
Scenario: 2 - The privacy notice is shown before using a local endpoint
Scenario: chat-02 - The privacy notice is shown before using a local endpoint
Given a model is being served locally
And the model is registered with the CLI
When the user opens interactive chat
Expand All @@ -23,7 +23,7 @@ Feature: Chat and endpoint detection
Then interactive chat exits successfully

@id:chat-managed-model-interactive @requires-os:linux
Scenario: 3 - Interactive chat uses a running managed model
Scenario: chat-03 - Interactive chat uses a running managed model
Given a running managed model is available locally
When the user opens interactive chat
Then the local endpoint is shown for confirmation
Expand All @@ -35,7 +35,7 @@ Feature: Chat and endpoint detection
Then interactive chat exits successfully

@id:chat-endpoint-shown-in-services
Scenario: 4 - A served model's endpoint is shown in the services list
Scenario: chat-04 - A served model's endpoint is shown in the services list
Given a model is being served
And the model is registered with the CLI
When the user lists running services
Expand All @@ -46,18 +46,18 @@ Feature: Chat and endpoint detection
# assertion (a tools-bearing request is accepted) is engine-agnostic, so no GPU
# is required — dropping @requires-gpu gives this per-PR mock-lane coverage.
@id:chat-tool-definitions-accepted
Scenario: 5 - Chat requests that include tool definitions are accepted
Scenario: chat-05 - Chat requests that include tool definitions are accepted
Given a managed runtime is active
And a model is served in the background
When a chat request with tool definitions is sent
Then the chat response is successful

# Runs on every lane (see scenario 5): real serve on a GPU host, MockServer on
# Runs on every lane (see chat-05): real serve on a GPU host, MockServer on
# the no-GPU mock lane. Asserts only that a served model returns a non-empty
# reply, which is engine-agnostic — real generation is covered by the
# @requires-gpu serve-*-inference scenarios.
@id:chat-end-to-end-local-model
Scenario: 6 - End-to-end chat through a locally served model
Scenario: chat-06 - End-to-end chat through a locally served model
Given a managed runtime is active
And a model is served in the background
And the served model has been detected
Expand All @@ -70,7 +70,7 @@ Feature: Chat and endpoint detection
# reports `rocm chat` as covered. Runs on mock (no GPU): the local provider
# resolves the planted managed-service record and talks to the mock server.
@id:chat-cli-oneshot-prompt
Scenario: 7 - The chat CLI answers a one-shot prompt against a local server
Scenario: chat-07 - The chat CLI answers a one-shot prompt against a local server
Given a model is being served
And the model is registered with the CLI
When the user sends a one-shot chat prompt through the CLI
Expand Down
22 changes: 11 additions & 11 deletions tests/e2e-cucumber/features/dash.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Feature: Interactive dashboard
# not yet promoted to a blocking contract (tracked as a follow-up).

@id:dash-opens-and-navigates @requires-os:linux
Scenario: 1 - A user opens the dashboard and navigates to ROCm setup
Scenario: dash-01 - A user opens the dashboard and navigates to ROCm setup
When the user opens the dashboard with demo data
Then the dashboard home view is displayed
When the user opens the ROCm view
Expand All @@ -15,7 +15,7 @@ Feature: Interactive dashboard
Then the dashboard exits successfully

@id:dash-chat-offline-reply @requires-os:linux
Scenario: 2 - A user receives a response in interactive chat
Scenario: dash-02 - A user receives a response in interactive chat
Given interactive chat uses an offline assistant
When the user opens interactive chat
And the user sends a message about GPU health
Expand All @@ -24,7 +24,7 @@ Feature: Interactive dashboard
Then interactive chat exits successfully

@id:dash-loading-service-status @requires-os:linux
Scenario: 3 - The dashboard reports a model that is still loading as loading
Scenario: dash-03 - The dashboard reports a model that is still loading as loading
Given a managed model is still loading
When the user opens the dashboard
And the user opens the Observe view
Expand All @@ -33,7 +33,7 @@ Feature: Interactive dashboard
Then the dashboard exits successfully

@id:dash-managed-service-metrics @requires-os:linux
Scenario: 4 - Observe displays metrics from a managed model
Scenario: dash-04 - Observe displays metrics from a managed model
Given a managed model exposes serving metrics
When the user opens the dashboard
And the user opens the Observe view
Expand All @@ -42,7 +42,7 @@ Feature: Interactive dashboard
Then the dashboard exits successfully

@id:dash-help-guidance @requires-os:linux
Scenario: 5 - A user can discover dashboard help and next-step guidance
Scenario: dash-05 - A user can discover dashboard help and next-step guidance
When the user opens the dashboard with demo data
And the user opens dashboard help
Then navigation and next-step guidance are displayed
Expand All @@ -51,7 +51,7 @@ Feature: Interactive dashboard
Then the dashboard exits successfully

@id:dash-command-palette-navigation @requires-os:linux
Scenario: 6 - A user navigates to Serving through the command palette
Scenario: dash-06 - A user navigates to Serving through the command palette
When the user opens the dashboard with demo data
And the user opens the command palette
Then dashboard destinations are displayed
Expand All @@ -61,7 +61,7 @@ Feature: Interactive dashboard
Then the dashboard exits successfully

@id:dash-managed-service-visible @requires-os:linux
Scenario: 7 - A managed model is visible in the dashboard
Scenario: dash-07 - A managed model is visible in the dashboard
Given a running managed model is available locally
When the user opens the dashboard
And the user opens the Observe view
Expand All @@ -70,8 +70,8 @@ Feature: Interactive dashboard
Then the dashboard exits successfully


@id:eai-7960-gen-tps-held-after-scrape-failure @requires-os:linux
Scenario: 8 - Gen throughput stays visible for the validity window after a scrape failure
@id:dash-gen-tps-held-after-scrape-failure @requires-os:linux
Scenario: dash-08 - Gen throughput stays visible for the validity window after a scrape failure
# EAI-7960 principal regression: after establishing a positive gen_tps
# baseline through the scripted mock, a single /metrics transport failure
# must NOT immediately clear the displayed "tok/s" value. The contract
Expand All @@ -88,8 +88,8 @@ Feature: Interactive dashboard
When the user quits the dashboard
Then the dashboard exits successfully

@id:eai-7960-gen-tps-expiry-boundary @requires-os:linux
Scenario: 9 - Gen throughput expires after the validity window following sustained failure
@id:dash-gen-tps-expiry-boundary @requires-os:linux
Scenario: dash-09 - Gen throughput expires after the validity window following sustained failure
# EAI-7960 expiry-boundary scenario: two contract boundaries are pinned.
#
# BOUNDARY 1 (held assertion) — immediately after the first failed scrape,
Expand Down
Loading
Loading