Testing the cloud services
The digital key cloud is where a key is issued, distributed, used and revoked, and where the certificates that bind a vehicle, the cloud and a handset together are held. This page covers how the studio exercises the backend interfaces, how a cloud call becomes a step of a case, how interface performance is measured and recorded, how key issuance and distribution are verified, and how the certificate chain is checked.
Where the cloud sits
The cloud is reached from the studio, not from the agent. A bench command needs the physical device; a cloud call does not. The studio issues the request itself and asserts on the answer, so a cloud case runs whether or not an agent is online, and nothing is dispatched to a bench.
| Target | Reached through | Who performs the call |
|---|---|---|
| Cloud backend interface | The studio | The studio |
| Vehicle, ECU, bench device | The agent | The agent on the bench |
| Handset and its wallet | The agent | The agent on the bench β see Testing mobile wallets |
This is the opposite of the bench-driven work in Remote shell and serial, where the agent does the work.
Exercising a backend interface
A cloud step is one request plus a set of expectations on the response. The studio sends the
request, waits for the answer, and captures what came back: the status code, the response
headers, the body, and the time the call took. The elapsed time is the same measurement the
platform records as duration_ms on the execution.
Cloud step expectations use the same two-part shape as every other expectation: an extractor
that reads a value out of the response, and a matcher that decides whether it passes. The
extractor is specific to the interface under test; the matcher is portable, so equals,
less_than or contains is reused across cloud interfaces and bench cases.
- ordinal: 2
kind: action
script: "$KEY_ISSUE_REQUEST"
timeout_ms: 10000
assertions:
- index: 0
extractor: "response.status"
matcher: "equals"
expected: 200
- index: 1
extractor: "response.body.keyId"
matcher: "equals"
expected: "$EXPECTED_KEY_ID"Measuring interface performance
Two numbers matter for a backend interface: how long a call takes, and how often it fails.
- Latency is the elapsed time of the call, recorded on the execution as
duration_ms. An assertion such asresponse.elapsed_msless_than15000turns a budget into a result that can fail. - Error rate is derived from the executions of a run: the share that ended in a failed execution against the share that ran. A matrix across regions or accounts gives the rate per row, so a slow region is visible next to a slow interface.
The distinction between the two kinds of failure matters, and the platform keeps them apart:
| Outcome | Meaning | Recorded as |
|---|---|---|
| The interface answered, and the answer did not match the expectation | The product is wrong. | A failed execution with the mismatch in result. |
| The interface could not be reached, timed out, or answered with a server error | The infrastructure is wrong. | An errored execution with the transport failure in error_message. |
A performance budget belongs to the first row only when the interface answered. A timeout is not a latency regression, and counting it as one hides the real defect.
An interface that answers with a throttling status is doing its job. Assert on the status code explicitly, so a throttled call is recorded as the expected behaviour instead of being folded into the error rate.
Verifying key issuance and distribution
Issuance is a three-party claim, and a test is only as good as the weakest link in it: the backend issued a key, the vehicle carries that key, and the handset holds it.
The key matches. The key identifier and its fingerprint returned by the issuance interface are compared with the key provisioned to the vehicle, read from the vehicle side of the bench, and with the key held in the wallet. The three must be the same key, not three keys of the same shape. The comparison is an equality assertion on a fingerprint value, which makes it portable across projects.
Use is one-time. A digital key that has been used must not be usable again. The case presents the key a second time and asserts that the interface refuses it. The refusal is the expected result, so it is written as its own expectation rather than as an error.
Revocation takes effect. After the key is revoked, the interface refuses it, the vehicle stops honouring it, and the wallet no longer offers it. Each of those is a separate expectation, because they are separate systems, and a revocation that reaches the backend but not the handset is a real defect that a single assertion would have missed.
Checking the certificate chain
The certificates that bind a vehicle, the cloud and a handset together form a chain of trust, and the chain is checked as a whole rather than one certificate at a time.
| Check | What it establishes |
|---|---|
| Validity window | The certificate is valid now, and the clock on the bench agrees with the issuing authority. |
| Chain of trust | Each certificate is signed by the issuer it names, up to a root the platform is configured to trust. |
| Binding | The vehicle certificate, the cloud certificate and the handset certificate all name the same vehicle. |
| Key usage | Each certificate carries the usages its role allows, so a handset certificate cannot be used where a vehicle certificate belongs. |
A failure in any of them is recorded against the step that made the check, with the certificate and the failing property named. A chain that fails on the issuer is a different defect from one that fails on the binding, and the report has to tell them apart.
The trusted roots and the expected vehicle identifier come from the project data, not from the response being tested. A check that derives its expectation from the same source it validates proves nothing.
Failure modes and boundaries
- A cloud interface that cannot be reached at all produces an errored execution for every step that depends on it. The run continues, and the report shows the dependency, so one unreachable interface does not look like a hundred product failures.
- Timeouts on cloud steps are set per step, in the same
timeout_msfield as any other step, and they are enforced by the studio rather than by the bench. - The studio reaches the cloud over the network the studio sits on. In an in-house installation that is your network, and the routes to the backend are part of what you operate β see Network requirements. Key material and certificates that a case prints into a response body are stored with the run, so keep secrets out of the assertions and out of the captured text.
Related pages
- Testing mobile wallets β the handset half of the same journey.
- The Test Case Model β the layers a cloud step belongs to.
- Data-driven matrices β sweeping an interface across regions or accounts.
- Results and reports β how a failure and its evidence are kept.
- Remote shell and serial β the bench-driven half of the work.