End-to-end scenarios — keystone-tempest-plugin — branch master
Branch
master@41e16f7f319c— repository https://opendev.org/openstack/keystone-tempest-plugin — analysed on 2026-10-28
The exchanges shown were recorded during the full run against Keystone stable/2026.2 (_rewrite/exchanges_master.json.gz, 17,873 exchanges). Each exchange carries the test that made it.
1. A persona test class: setup, assertions, teardown
Example: DomainManagerTests of keystone_tempest_plugin/tests/rbac/v3/test_project.py, whose credentials are ['domain_manager', 'system_admin'] (keystone_tempest_plugin/tests/rbac/v3/test_project.py:345-347).
sequenceDiagram
participant T as Tempest (test class)
participant K as Keystone
Note over T,K: class setup — dynamic credentials
T->>K: POST /v3/auth/tokens (admin from tempest.conf, system scope)
K-->>T: 201 + X-Subject-Token
T->>K: GET /v3/domains, POST /v3/domains, POST /v3/users (random names)
T->>K: GET /v3/roles, PUT /v3/domains/{d}/users/{u}/roles/{manager}
T->>K: POST /v3/auth/tokens (persona user, domain scope)
K-->>T: 201 (persona token)
T->>K: POST /v3/users, GET /v3/roles, PUT /v3/system/users/{u2}/roles/{admin}, POST /v3/auth/tokens (system_admin credential)
Note over T,K: each test — resources created by the system admin client
T->>K: POST /v3/projects (system_admin token)
K-->>T: 201
Note over T,K: assertions with the persona token
T->>K: GET /v3/projects/{id in own domain}
K-->>T: 200 → do_request(…, expected_status=200) passes
T->>K: GET /v3/projects/{id in another domain}
K-->>T: 403 → do_request(…, expected_status=Forbidden) passes
Note over T,K: cleanup (addCleanup, then class teardown)
T->>K: DELETE /v3/projects/{id} (204, or 404 if the test already deleted it)
T->>K: DELETE /v3/users/{u}, PATCH /v3/domains/{d} (enabled=false), DELETE /v3/domains/{d}
K-->>T: 204 / 200 / 204- System personas get a token scoped to the system (
system: all). - Domain personas get a token scoped to a domain.
- Project personas get a token scoped to a project.
The role is admin, manager, member or reader. The second credential, system_admin, gives each class an administrator client to create and delete the targets of its assertions.
2. One RBAC assertion
sequenceDiagram
participant Test as test method
participant DR as do_request (plugin)
participant RC as Tempest RestClient
participant K as Keystone
Test->>DR: do_request("create_project", expected_status=Forbidden, name=…)
DR->>RC: client.create_project(name=…)
RC->>K: POST /v3/projects (X-Auth-Token = persona token)
K->>K: oslo.policy identity:create_project (scope + role + target)
alt refused
K-->>RC: 403 {"error": {"message": "You are not authorized to perform the requested action: identity:create_project."}}
RC-->>DR: raises Forbidden
DR-->>Test: assertRaises(Forbidden) passes
else allowed
K-->>RC: 201 {"project": …}
RC-->>DR: response
DR-->>Test: assertRaises fails → test fails
enddo_request compares the status only (keystone_tempest_plugin/tests/rbac/v3/base.py:34-44). For an integer status, it checks response.response.status. The body is still validated by Tempest's JSON schemas for its own identity clients (03).
3. Running the suite against OpenKeel Keystone
sequenceDiagram
participant C as conformance_capture.py (adapter keystone_tempest_plugin.py)
participant K as Keystone under test (in-process wsgiref, port P)
participant R as Tempest runner (subprocess)
C->>K: start: SQLite, Fernet, bootstrap, enforce_scope + enforce_new_defaults
C->>R: python ktp_runner.py <modules> (tempest.conf → http://127.0.0.1:P/v3)
loop every test
R->>K: HTTP request + X-Test-Id: <test id>
K-->>R: response
C->>C: record the exchange under that test id
end
R-->>C: one result per test, RBAC assertions
C->>C: exchanges, response schemas, observed errors, rbac-assertionsTo test another implementation, point [identity] uri_v3 of tempest.conf at it (07 § 2).
Source: reverse-spec-keystone-tempest-plugin/04-scenarios_master.md. The _rewrite/ and _inventory/ files are not published on the site.