Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
1cdee64
feat: Add AWS RDS hostgroups config and runtime tables
wazir-ahmed Jun 15, 2026
83b5901
feat: Add AWS RDS topology monitor thread
wazir-ahmed Jun 15, 2026
a531473
feat: Wire read_only monitor to AWS RDS blue/green monitoring
wazir-ahmed Jun 17, 2026
c4aa572
feat: Add DNS cache IP pinning
wazir-ahmed Jun 21, 2026
1fd472e
feat: Add helper to shun a server with shun recovery disabled
wazir-ahmed Jun 22, 2026
cd89f42
feat: Perform the AWS RDS blue/green switchover in the RDS monitor
wazir-ahmed Jun 22, 2026
3b2fe9a
fix: Ignore `Table doesn't exist` error for `mysql.rds_topology`
wazir-ahmed Jun 22, 2026
198e323
refactor: Use green writer IP in AWS RDS to poll for topology switcho…
wazir-ahmed Jun 22, 2026
be9187d
fix: Suspend read_only monitor actions during AWS RDS BGD switchover
wazir-ahmed Jun 23, 2026
1f530ab
fix: Rename shadowed variable in `DNS_Cache::lookup()`
wazir-ahmed Jun 24, 2026
8fcda28
fix: Avoid calling `read_only_action_v2` for unexpected resultset
wazir-ahmed Jun 26, 2026
d425ec3
fix: Ignore monitor query timeouts after resolved IP changes
wazir-ahmed Jun 26, 2026
4f7ed9a
feat: Add expiry for pinned IPs in `DNS_Cache`
wazir-ahmed Jun 27, 2026
4092797
feat: Add new server status `SHUNNED_AWS_BGD`
wazir-ahmed Jun 29, 2026
63dca4b
feat: Drain backend connections during AWS BGD switchover
wazir-ahmed Jun 29, 2026
d0dbcd3
fix: Make `DNS_Cache` honor IP pins with no expire time
wazir-ahmed Jun 30, 2026
252897c
fix: Clear affected-row hostgroup before destroying backend
wazir-ahmed Jun 30, 2026
9b3903f
feat: Fast polling for RDS blue/green servers in read_only monitor
wazir-ahmed Jul 1, 2026
4eac77d
Fix gaps in handling new server status `SHUNNED_AWS_BGD`
wazir-ahmed Jul 2, 2026
085785d
fix: Move AWS RDS blue readers to SHUNNED after switchover
wazir-ahmed Jul 2, 2026
e2cfb42
fix: Remove unused columns from `mysql_aws_rds_bgd_hostgroups` table
wazir-ahmed Jul 2, 2026
4e04ee8
fix: Defer AWS RDS BGD switchover teardown until the rds_topology tab…
wazir-ahmed Jul 3, 2026
e8905ff
refactor: Reconfigure reader HG properly during AWS RDS BGD switchover
wazir-ahmed Jul 6, 2026
696607f
feat: Add runtime column `status` to `mysql_aws_rds_bgd_hostgroups` t…
wazir-ahmed Jul 6, 2026
912b03a
feat: Drain AWS RDS BGD green hostgroups after switchover
wazir-ahmed Jul 6, 2026
17dff95
Merge branch 'v3.0' into feature/aws-rds-monitor
wazir-ahmed Jul 6, 2026
72516ed
fix: Drain blue server connections across all hostgroups during switc…
wazir-ahmed Jul 7, 2026
8bdb921
refactor: Drive hostgroup migration from AWS RDS BGD monitor
wazir-ahmed Jul 8, 2026
22ea5c4
fix: Move AWS RDS BGD switchover-in-progress flag from HGM to Monitor
wazir-ahmed Jul 10, 2026
ded81f8
fix: Abort `async_connect` when server goes offline or unhealthy
wazir-ahmed Jul 12, 2026
b1fd57b
feat: Handle AWS RDS BGD switchover rollbacks
wazir-ahmed Jul 13, 2026
b574e36
fix: Normalize AWS BGD shunned status in cluster sync
wazir-ahmed Jul 13, 2026
0a37316
Merge branch 'v3.0' into feature/aws-rds-monitor
wazir-ahmed Jul 13, 2026
7d27207
fix: Track BGD green-writer ownership and skip green-HG drain on roll…
wazir-ahmed Jul 15, 2026
20247dc
fix: Use writer port and SSL for AWS BGD green probes
wazir-ahmed Jul 15, 2026
727b216
fix: Track green hosts in AWS RDS BGD checksum
wazir-ahmed Jul 15, 2026
d45c953
fix: Refresh AWS RDS BGD checksum after mysql_servers commits
wazir-ahmed Jul 16, 2026
cdffd77
fix: Revise AWS RDS BGD green drain policy
wazir-ahmed Jul 16, 2026
ac4167c
fix: Exclude `OFFLINE_SOFT` servers from AWS RDS BGD action
wazir-ahmed Jul 16, 2026
0a1bc28
docs: Establish AWS RDS BGD validation contract
renecannao Jul 16, 2026
177a4bb
fix: Refresh `mysql_servers_to_monitor` after adding discovered green…
wazir-ahmed Jul 16, 2026
b05b907
Fixes for AWS RDS BGD topology probe and auto-discovery
wazir-ahmed Jul 17, 2026
e259f2c
docs: Define AWS RDS BGD simulator design
wazir-ahmed Jul 19, 2026
ffc07ed
fix: Retire unhealthy AWS RDS BGD connections
wazir-ahmed Jul 21, 2026
4147c73
test: Add unit test for unhealthy MySQL connection retirement
wazir-ahmed Jul 22, 2026
7204726
fix: Select explicit green writer TLS by probe tuple
wazir-ahmed Jul 22, 2026
d5581c0
docs: Refine AWS RDS BGD simulator coverage
wazir-ahmed Jul 19, 2026
3ff57f4
test: Add TAP-controlled RDS BGD simulator helpers
wazir-ahmed Jul 19, 2026
11e0368
test: Add TEST_RDS_BGD SQLite simulator
wazir-ahmed Jul 19, 2026
a04c4fc
fix: Stop dispatch after simulated BGD errors
wazir-ahmed Jul 19, 2026
8ef0e9b
test: Add RDS BGD simulator smoke coverage
wazir-ahmed Jul 19, 2026
46592fe
fix: Use AWS BGD topology role values
wazir-ahmed Jul 19, 2026
9acdf65
docs: Mark AWS RDS BGD simulator complete
wazir-ahmed Jul 19, 2026
66e8188
fix: Ensure simulated backend address is initialized
wazir-ahmed Jul 19, 2026
8f1dec3
fix: Reuse read-only simulation for AWS RDS BGD
wazir-ahmed Jul 21, 2026
f59abc7
test: Simplify AWS RDS BGD simulator helpers
wazir-ahmed Jul 22, 2026
0eca84a
fix: Align AWS RDS BGD simulator probe handling
wazir-ahmed Jul 23, 2026
e8bbc5c
fix: Retry AWS RDS BGD DNS pinning in same phase
wazir-ahmed Jul 23, 2026
251f820
ci: Add workflow for cluster simulation groups
wazir-ahmed Jul 24, 2026
1633b07
ci: Simplify cluster simulator job names
wazir-ahmed Jul 24, 2026
1de71f9
fix: Isolate AWS RDS BGD workers by hostgroup
wazir-ahmed Jul 27, 2026
b44594b
Merge branch 'v3.0' into feature/aws-rds-monitor
wazir-ahmed Jul 27, 2026
75ee872
fix: preserve RDS BGD runtime status on reload
wazir-ahmed Jul 28, 2026
61790f9
fix: stabilize RDS BGD monitor transitions
wazir-ahmed Jul 28, 2026
a646af9
fix: preserve TLS-specific monitor connections
wazir-ahmed Jul 28, 2026
c163855
fix: track offline RDS BGD green writers
wazir-ahmed Jul 28, 2026
8886603
test: wait for ProxySQL simulator ports
wazir-ahmed Jul 28, 2026
d24d64f
test: add shared RDS BGD simulator support
wazir-ahmed Jul 28, 2026
84e416c
test: modernize RDS BGD smoke coverage
wazir-ahmed Jul 28, 2026
0471cd6
test: cover RDS BGD discovery and configuration
wazir-ahmed Jul 28, 2026
6843d78
test: cover RDS BGD lifecycle and rollback
wazir-ahmed Jul 28, 2026
7d2e462
test: cover RDS BGD late entry and topology failures
wazir-ahmed Jul 28, 2026
b61de4c
test: cover RDS BGD server and connection policies
wazir-ahmed Jul 28, 2026
630de5f
test: cover RDS BGD worker configuration refresh
wazir-ahmed Jul 28, 2026
55449f2
test: cover repeated and concurrent RDS BGD lifecycles
wazir-ahmed Jul 28, 2026
6304c18
docs: align RDS BGD simulator documentation
wazir-ahmed Jul 28, 2026
1688214
fix: stabilize RDS BGD read_only suppression
wazir-ahmed Jul 28, 2026
1995c84
docs: finalize RDS BGD monitor documentation
wazir-ahmed Jul 28, 2026
56f7c45
Merge origin/v3.0 into feature/aws-rds-monitor
renecannao Jul 28, 2026
13cd483
Add BGD cluster sync plumbing, unit test, and fix int/bool type incon…
renecannao Jul 29, 2026
1d8be51
Fix groups.json sorting for cluster_sync_unit-t
renecannao Jul 29, 2026
74ecfcb
Fix MySQL integer variable initialization
renecannao Jul 29, 2026
f6a0ee4
Merge branch 'v3.0' into feature/aws-rds-monitor
renecannao Jul 29, 2026
67d4a20
Fix duplicate groups entry
renecannao Jul 29, 2026
c59fd8a
Fix RDS BGD simulator workflows
renecannao Jul 29, 2026
a899fd9
Fix Galera simulator expected state comments
renecannao Jul 29, 2026
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
129 changes: 129 additions & 0 deletions .github/workflows/CI-cluster-simulator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Builds ProxySQL once with every cluster simulation flag enabled, then runs
# each registered cluster_sim_* TAP group as an independent matrix job.
#
# Maintenance notes:
# - Groups and TAP binaries are discovered from test/tap/groups/groups.json.
# - `testall` is intentional: every matrix job shares one ProxySQL binary built
# with all simulation flags.
# - Registering a new simulation group and TAP binary requires no YAML changes.
# - The exact-SHA cache contains only the runtime files used by matrix jobs.
# - Command details and local examples: test/infra/control/cluster-simulator-ci.bash help.

name: CI-cluster-simulator
run-name: '${{ github.head_ref || github.ref_name }} ${{ github.workflow }} ${{ github.sha }}'

on:
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref_name }}
cancel-in-progress: true

env:
BUILD_CACHE_KEY: cluster-simulator-v3-ubuntu22-${{ github.sha }}
RUNTIME_CACHE_DIR: .cluster-simulator-runtime

jobs:
build:
name: build
runs-on: ubuntu-22.04
outputs:
groups: ${{ steps.simulator-groups.outputs.groups }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Discover simulation groups
id: simulator-groups
run: test/infra/control/cluster-simulator-ci.bash discover

- name: Restore simulation build
id: simulator-build
uses: actions/cache/restore@v4
with:
key: ${{ env.BUILD_CACHE_KEY }}
path: ${{ env.RUNTIME_CACHE_DIR }}

- name: Install cached simulation runtime
if: steps.simulator-build.outputs.cache-hit == 'true'
run: test/infra/control/cluster-simulator-ci.bash install

- name: Build simulation test runtime
if: steps.simulator-build.outputs.cache-hit != 'true'
run: test/infra/control/cluster-simulator-ci.bash build

- name: Verify simulation build
run: test/infra/control/cluster-simulator-ci.bash verify

- name: Stage simulation runtime
if: steps.simulator-build.outputs.cache-hit != 'true'
run: test/infra/control/cluster-simulator-ci.bash stage

- name: Save simulation build
if: steps.simulator-build.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
key: ${{ env.BUILD_CACHE_KEY }}
path: ${{ env.RUNTIME_CACHE_DIR }}

test:
name: test / ${{ matrix.group }}
needs: build
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
group: ${{ fromJSON(needs.build.outputs.groups) }}
env:
INFRA_ID: ${{ matrix.group }}-${{ github.run_id }}-${{ github.run_attempt }}
TAP_GROUP: ${{ matrix.group }}

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Restore simulation build
uses: actions/cache/restore@v4
with:
key: ${{ env.BUILD_CACHE_KEY }}
fail-on-cache-miss: true
path: ${{ env.RUNTIME_CACHE_DIR }}

- name: Install simulation runtime
run: test/infra/control/cluster-simulator-ci.bash install

- name: Verify simulation build
run: test/infra/control/cluster-simulator-ci.bash verify "${TAP_GROUP}"

- name: Build CI base image
run: docker build --network host -t proxysql-ci-base:latest test/infra/docker-base

- name: Start infrastructure
run: test/infra/control/ensure-infras.bash

- name: Run simulation tests
run: test/infra/control/run-tests-isolated.bash

- name: Cleanup
if: always()
run: |
test/infra/control/stop-proxysql-isolated.bash || true
test/infra/control/destroy-infras.bash || true

- name: Archive failure logs
if: ${{ failure() && !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.group }}-${{ github.sha }}-logs-run${{ github.run_number }}
path: ci_infra_logs/
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ pkgroot/

#files generated during CI run
proxysql-save.cfg
.cluster-simulator-binaries
.cluster-simulator-runtime/
test/tap/tests/test_cluster_sync_config/cluster_sync_node_stderr.txt
test/tap/tests/test_cluster_sync_config/proxysql*.pem
test/tap/tests/test_cluster_sync_config/test_cluster_sync.cnf
Expand Down
16 changes: 14 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ testreadonly: build_src_testreadonly build_cluster_simulator
.PHONY: testreplicationlag
testreplicationlag: build_src_testreplicationlag build_cluster_simulator

.PHONY: test_rds_bgd
test_rds_bgd: build_src_test_rds_bgd
cd test/tap && OPTZ="${O0} -ggdb -DDEBUG" CC=${CC} CXX=${CXX} ${MAKE} debug

.PHONY: testall
testall: build_src_testall

Expand Down Expand Up @@ -337,13 +341,21 @@ build_src_testreplicationlag: build_lib_testreplicationlag
build_lib_testreplicationlag: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_REPLICATIONLAG" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_src_test_rds_bgd
build_src_test_rds_bgd: build_lib_test_rds_bgd
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_RDS_BGD" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_lib_test_rds_bgd
build_lib_test_rds_bgd: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_RDS_BGD" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_src_testall
build_src_testall: build_lib_testall
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP -DTEST_READONLY -DTEST_REPLICATIONLAG" CC=${CC} CXX=${CXX} ${MAKE}
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP -DTEST_READONLY -DTEST_REPLICATIONLAG -DTEST_RDS_BGD" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_lib_testall
build_lib_testall: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP -DTEST_READONLY -DTEST_REPLICATIONLAG" CC=${CC} CXX=${CXX} ${MAKE}
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP -DTEST_READONLY -DTEST_REPLICATIONLAG -DTEST_RDS_BGD" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_tap_test
build_tap_test: build_tap_tests
Expand Down
157 changes: 157 additions & 0 deletions bgd-test-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# AWS RDS BGD TAP Style Rules

These rules apply to every new or refactored AWS RDS BGD TAP file.

## Test Scope And Documentation

- Use one TAP executable per independently reportable behavior.
- Keep each TAP executable focused on the behavior named by the file. Do not
add connection-pool, TLS, server-status, or other property mutations unless
that behavior requires them.
- Move independently useful coverage into a dedicated TAP executable instead
of carrying it through an unrelated scenario.
- File and test headers must name the exact BGD configuration change, topology
state, and expected ProxySQL result.
- Use names from the BGD implementation and Admin tables. Avoid generic wording
such as "surface", "departure", or "input replacement".
- Document multi-step tests with setup, mutation, and verification bullets.
- Test public configuration and observable routing, runtime, connection-pool,
and probe behavior. Do not test or document non-public internal server states.

## Local Test Harness

- Every BGD TAP file defines local `setup()` and `cleanup()` functions.
- `setup()` initializes only the test harness: load the TAP environment,
connect to ProxySQL Admin, and connect to the SQLite simulator.
- `setup()` must not configure BGD topology, Admin rows, simulated writer
state, or other scenario prerequisites.
- `setup()` must not contain TAP assertions.
- `setup()` releases any partially created connection before returning a
failure. `main()` then returns `exit_status()` without calling `cleanup()`.
- `cleanup()` clears the ProxySQL Admin/runtime and simulator state created by
the test, then closes test connections.
- `cleanup()` is called only after `setup()` succeeds and may assume its
connections are valid.
- `cleanup()` attempts every cleanup operation, closes test connections, and
returns `EXIT_FAILURE` if any Admin or simulator cleanup operation fails.
- A cleanup failure must fail the TAP executable so the developer and CI can
see that the test did not leave a clean state.
- Store the Admin and simulator cleanup results separately. Log each failure
with an `Error:` diagnostic, continue with the remaining cleanup operations,
and return one combined result.
- Close the Admin connection immediately after its cleanup operation. Do not
skip connection closure because cleanup failed.
- Do not wait for probe quiescence during cleanup.
- After harness setup succeeds, failures must flow to a single
`exit_cleanup:` label in `main()`. That label always calls the local
`cleanup()` function.
- Declare the TAP plan before calling `setup()`. After `exit_cleanup:`, return
`EXIT_FAILURE` when cleanup fails; otherwise return `exit_status()`. A setup
failure is then reported as missing planned assertions instead of bypassing
TAP result handling.
- At `exit_cleanup:`, check `cleanup()` directly without a temporary result.
Return `EXIT_FAILURE` immediately when cleanup fails.
- Do not use `BAIL_OUT()` after test resources have been created or test state
has been changed. Log the failure, set the process result, and continue to
`exit_cleanup:`.
- Do not register global pointers or `atexit` handlers for test cleanup.
- A test assumes clean ProxySQL and simulator state at entry. Do not clear
state at the start of `setup()` or the test function.
- Scenario topology, ProxySQL configuration, mutations, waits, and TAP
assertions belong in the named test function.
- Keep `main()` limited to `plan()`, `setup()`, the named test, the
`exit_cleanup:` path, and the TAP exit status.

## C++ Layout

- Do not wrap TAP test files in an anonymous namespace. Each TAP file builds as
its own executable, so file-local namespace isolation is unnecessary.
- When phases share local state, name the struct `TestState`. Do not include
the test or file name in the local state type.
- Call the named test phases directly from `main()`. Do not add a wrapper test
function whose only job is to call the phases.
- The comment before each phase call in `main()` must make the phase
understandable without opening the function. State the concrete simulator
or ProxySQL configuration, the BGD status or server placement being
produced, and the observable result being verified.
- Do not write call-site comments that merely restate the function name or use
vague verbs such as "establish", "prepare", "handle", or "process".
- Keep call-site phase comments concise, but use exact BGD statuses,
hostgroups, tables, or server roles where they matter.
- Name simulator state helpers after the exact variable and value being set,
such as `set_writer_read_only_0()`. Avoid interpreted names such as
`set_writers_writable()`.
- Organize phase comments by the system being acted on, using labels such as
`Simulator:`, `ProxySQL:`, `Client:`, and `Verify:`. Include only the
applicable systems, and state the concrete action or expected result for
each one.
- Always use braces for `if` statements, including one-line bodies:

```cpp
if (condition) {
action();
}
```

- Keep complete function declarations, definitions, and calls on one line
whenever they remain readable. Use 120 characters as a guideline, not a
hard limit; prefer a small overrun to splitting a simple call across lines.
Wrap only when the complete statement is materially too long.
- Do not add `const` qualifiers to function parameters in these TAP files.
Prefer shorter, simpler signatures over strict const-correctness in
test-local helpers.
- Build SQL strings, expected-result text, and list arguments in named local
variables before calling a helper. Do not mix string concatenation,
temporary lists, and the function call in one statement.
- Format query helpers in four visible blocks separated by blank lines:
construct the query, construct related arguments, call the helper, and
return the stored result.
- When a helper call must wrap, group related arguments across as few lines as
possible and place the closing `);` on its own line.
- Keep return statements simple. Store a function result in a local variable
and return that variable instead of returning a large function call or a
heavily combined expression.
- Do not create duplicate query helpers that differ only by one expected
value. Pass that expected value as an argument to one clearly named helper.
- Do not place multiple function calls inside one `ok()` condition. Evaluate
each call into a clearly named local variable first, then combine those
boolean variables in the assertion.
- When a helper performs multiple function calls, execute them one at a time.
Return `EXIT_FAILURE` immediately after the specific call that fails, then
return `EXIT_SUCCESS` after all calls succeed. Do not combine calls with
`&&` and a ternary return.
- Apply the same sequential pattern inside test phases. Separate each
call-and-failure-check block with a blank line; do not conditionally invoke
later operations through ternary expressions.
- Before returning `EXIT_FAILURE` from setup, helper, phase, or `main()`, emit
a diagnostic beginning with `Error:` that names the failed operation.
Cleanup may log its individual failures before returning one combined
result.
- Shared condition and probe wait helpers must only return their result. They
must not dump timeout diagnostics; the calling phase logs the relevant
`Error:` message.
- Use `bgd_expect_no_table_check()` and `bgd_expect_no_metadata_probe()` for
negative probe checks instead of duplicating timeout logic in TAP files.
Pass the bounded timeout explicitly; these helpers return success only when
the unwanted probe wait returns `ETIMEDOUT`.
- Pass wait helpers only the values required to perform the wait. Do not pass
scenario names, phase names, expected text, probe sequences, or hostgroup
lists solely for generic diagnostics.
- Do not add `ok(false, ...)` to a failure-return path. Emit the `Error:`
diagnostic and return `EXIT_FAILURE`; the incomplete TAP plan will fail the
executable.
- Assertion messages and phase names must identify concrete BGD statuses,
hostgroups, tables, or server movements. Avoid undefined relational wording
such as "original definition", "current state", or "changed setup".
- In assertion messages, describe a runtime BGD status as
`BGD status for wHG <id>` instead of the longer
`runtime BGD row for writer hostgroup <id>`.
- Separate environment loading, Admin connection, and simulator connection
into distinct blocks with blank lines.
- Separate setup, test execution, and cleanup calls in `main()` with blank
lines.
- Use `RDS_BGD_Cluster::get_endpoints()`, `get_blue_endpoints()`, and
`get_green_endpoints()` instead of rebuilding endpoint lists with reader
loops in individual tests.
- Keep positive condition and probe waits at three seconds or less. Use bounded
waits instead of fixed sleeps.
Loading
Loading