Skip to content

test(robot): add the three-VM RGW placement suite - #891

Open
johnramsden wants to merge 5 commits into
rgw-stack/10-robot-singlefrom
rgw-stack/11-robot-multivm
Open

johnramsden wants to merge 5 commits into
rgw-stack/10-robot-singlefrom
rgw-stack/11-robot-multivm

Conversation

@johnramsden

@johnramsden johnramsden commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

Description

Some behaviour only shows with real, separate machines, so this suite runs three LXD VMs as independent cluster members: a policy sent to one member enabling a gateway on another, a third member reading S3 from it, a port change requested from yet another member, and failures that only exist across a real network. Its 9 cases cover a migration during which an in-guest sampler reads one object without pause and every read must succeed on at least one gateway; two applies started together on different members ending as one 200 and one 409; a member that is switched off still reporting its last applied frontend, failing the apply with 500, not starving the other addition, and holding back the paired removal; a keep-one refusal reported together with an unreachable member; and scale to zero, twice.

resources/rgw_placement.py gains helpers to start detached PUTs inside a guest and to run a read sampler inside a guest rather than on the host — a migration finishes in under a second, and a host-side sampler is too slow to catch a gap that short. resources/microceph_harness.py gains multi-VM lifecycle helpers and cluster-readiness waits. wait_for_microceph_ready_in_vm checks the daemon actually answers again after a guest is stopped and started, since the control socket file itself survives that and is not proof the daemon behind it does.

resources/placement_status.py's cluster_member_names now matches exact member names rather than prefixes, and the new migration_samples detects an outage or an unfinished sampler in the collected read log, both covered by pytest.

Adds rgw-placement-multivm-tests to the robot-tests matrix. The suite keeps three nested guests running at once, so it sets runner: self-hosted-linux-amd64-jammy-xlarge, the runner deferred-ceph-multinode-tests already uses.

Stack: PR 11 of 13. Merge in order. Each PR is one logical change on top of the one before it.

  1. feat(db): add a table for each member's last applied RGW frontend #881 feat(db): add a table for each member's last applied RGW frontend
  2. fix(services): keep error classes through the service enable path #882 fix(services): keep error classes through the service enable path
  3. feat(api): describe an RGW placement as an object with explicit TLS intent #883 feat(api): describe an RGW placement as an object with explicit TLS intent
  4. feat(rgw): make the member-side RGW apply safe to repeat #884 feat(rgw): make the member-side RGW apply safe to repeat
  5. feat(rgw): wait until the gateway really serves the requested frontend #885 feat(rgw): wait until the gateway really serves the requested frontend
  6. feat(rgw): reuse the member's own pair when TLS is asked for without one #886 feat(rgw): reuse the member's own pair when TLS is asked for without one
  7. fix(rgw): make RGW disable converge when repeated or interrupted #887 fix(rgw): make RGW disable converge when repeated or interrupted
  8. feat(placement): accept the RGW object in the policy and keep its secrets out #888 feat(placement): accept the RGW object in the policy and keep its secrets out
  9. feat(placement): reconcile RGW across the cluster #889 feat(placement): reconcile RGW across the cluster
  10. test(robot): add the single-VM RGW placement suite #890 test(robot): add the single-VM RGW placement suite
  11. test(robot): add the three-VM RGW placement suite #891 test(robot): add the three-VM RGW placement suite (this PR)
  12. docs: keep the RGW placement contract in HACKING.md for now #892 docs: keep the RGW placement contract in HACKING.md for now
  13. fix(rgw): do not trust a pending-apply marker the operator completed by hand #893 fix(rgw): do not trust a pending-apply marker the operator completed by hand

Reviewer note: microceph_api_delete_in_vm (in microceph_harness.py) is defined but has zero callers anywhere in the Robot tree (verified with a repo-wide grep) — dead code as of this suite.

Type of change

  • Clean code (code refactor, test updates; does not introduce functional changes)

How has this been tested?

  • Unit tests pass at this stack's cumulative tip
  • Robot tests pass

Contributor checklist

Please check that you have:

  • self-reviewed the code in this PR
  • added code comments, particularly in less straightforward areas
  • checked and added or updated relevant documentation
  • checked and added or updated relevant release notes
  • added tests to verify effectiveness of this change

@johnramsden
johnramsden added this pull request to stack #894 September 23, 2026 04:20
@johnramsden johnramsden changed the title rgw stack/11 robot multivm test(robot): add the three-VM RGW placement suite Sep 23, 2026
@johnramsden
johnramsden marked this pull request as ready for review September 23, 2026 04:30
@johnramsden
johnramsden marked this pull request as draft September 23, 2026 06:12
@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from 54de19d to 60d0bd3 Compare September 23, 2026 18:19
@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from 60d0bd3 to 469f5ba Compare September 24, 2026 19:32
@johnramsden
johnramsden marked this pull request as ready for review September 25, 2026 23:06
@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from 469f5ba to a7a6581 Compare September 29, 2026 18:43
@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from a7a6581 to ce3af35 Compare September 29, 2026 19:50

@sabaini sabaini left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some testing nits

Comment thread tests/robot/resources/rgw_placement.py Outdated
Comment thread tests/robot/rgw-placement-multivm-tests/rgw_placement_multivm_tests.robot Outdated
Comment thread tests/robot/rgw-placement-multivm-tests/rgw_placement_multivm_tests.robot Outdated
johnramsden added a commit that referenced this pull request Oct 2, 2026
Replace detached requests and marker files with a guest-side runner that owns sampling and concurrent PUT workers. Read gateways in handover order and accept either lock winner.

Review: #891 (comment)

Review: #891 (comment)

Review: #891 (comment)

Assisted-by: omp:openrouter/openai/gpt-6-astra
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
johnramsden added a commit that referenced this pull request Oct 2, 2026
Require the RGW action and exact member name so the keep-one message cannot satisfy both assertions.

Review: #891 (comment)

Assisted-by: omp:openrouter/openai/gpt-6-astra
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from ce3af35 to 90dd7cb Compare October 2, 2026 02:35
@johnramsden
johnramsden requested a review from sabaini October 2, 2026 04:09
@johnramsden

Copy link
Copy Markdown
Member Author

I restructured the tests that need to run concurrently to be more resilient and easier to understand.

@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from 90dd7cb to ce56f2f Compare October 6, 2026 00:47
johnramsden and others added 5 commits October 9, 2026 17:27
Some behaviour only shows with real, separate machines, so this suite runs three LXD VMs as independent cluster members: a policy sent to one member enabling a gateway on another, a third member reading S3 from it, a port change requested from yet another member, and failures that only exist across a real network. Its 9 cases cover a migration during which an in-guest sampler reads one object without pause and every read must succeed on at least one gateway; two applies started together on different members ending as one 200 and one 409; a member that is switched off still reporting its last applied frontend, failing the apply with 500, not starving the other addition, and holding back the paired removal; a keep-one refusal reported together with an unreachable member; and scale to zero, twice.

resources/rgw_placement.py gains start_placement_put_in_vm and start_concurrent_placement_puts_in_vm, which start detached PUTs inside a guest, and RGW_MIGRATION_SAMPLER with start_rgw_migration_sampler_in_vm and collect_rgw_migration_samples_in_vm, which run the read sampler inside a guest rather than on the host: a migration finishes in under a second, and a sampler on the host is too slow to catch a gap that short. resources/microceph_harness.py gains the multi-VM lifecycle helpers (launch_guest_test_vm, stop_named_vm, start_named_vm, teardown_named_vms) and cluster-readiness waits (wait_for_cluster_members_in_vm, wait_for_cluster_health_ok_in_vm, wait_for_osd_count_in_vm, mon_count_in_vm). wait_for_microceph_ready_in_vm checks the daemon actually answers again after a guest is stopped and started, since the control socket file itself survives that and is not proof the daemon behind it does. An optional vm_name on copy_snap_to_vm, install_tools, install_microceph_from_local_snap and wait_for_microceph_control_socket lets each existing, unchanged caller keep targeting the outer VM implicitly while a new caller names a guest.

resources/placement_status.py's cluster_member_names now matches exact member names rather than prefixes, and the new migration_samples detects an outage or an unfinished sampler in the collected read log, both covered by pytest in test_harness_helpers.py alongside every parser above.

Co-authored-by: Peter Sabaini <peter.sabaini@canonical.com>
Assisted-by: claude-code:claude-fable-5-1
Assisted-by: pi:gpt-6-astra
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
Adds rgw-placement-multivm-tests to the robot-tests matrix in .github/workflows/tests.yml. The suite keeps three nested guests running at once, so it sets runner: self-hosted-linux-amd64-jammy-xlarge, the runner deferred-ceph-multinode-tests already uses.

Assisted-by: claude-code:claude-fable-5-1
Assisted-by: pi:gpt-6-astra
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
The three guests are separate LXD VMs whose clocks are not NTP-synced when the mons first form quorum, and the leader re-checks skew only every 300 s, so the 5-minute HEALTH_OK wait fails on MON_CLOCK_SKEW alone. The wait now reads health as JSON, accepts a HEALTH_WARN made only of the checks the caller names, and on timeout logs ceph health detail with the last health output in the message.

Failing job: https://github.com/canonical/microceph/actions/runs/35817330723/job/107046162999

Assisted-by: claude-code:claude-fable-5-1
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
Replace detached requests and marker files with a guest-side runner that owns sampling and concurrent PUT workers. Read gateways in handover order and accept either lock winner.

Review: #891 (comment)

Review: #891 (comment)

Review: #891 (comment)

Assisted-by: omp:openrouter/openai/gpt-6-astra
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
Require the RGW action and exact member name so the keep-one message cannot satisfy both assertions.

Review: #891 (comment)

Assisted-by: omp:openrouter/openai/gpt-6-astra
Signed-off-by: John Ramsden <john.ramsden@canonical.com>
@johnramsden
johnramsden force-pushed the rgw-stack/11-robot-multivm branch from ce56f2f to abe4436 Compare October 10, 2026 00:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants