fix(ci-mysqlx): cache runtime deps + unblock soak listener bind#5852
Conversation
CI-mysqlx.yml: extend the build cache to include the deps shared
libraries that test/tap/tap/libtap.so DT_NEEDEDs at runtime — without
them, downstream jobs restore the linked binaries but the loader
fails with "libre2.so.10: cannot open shared object file". libtap.so
pulls libre2.so.10 (from deps/re2/re2/obj/so/) and libpq.so.5 (from
deps/postgresql/.../libpq/) via -Wl,-rpath at build time, so the
exact .so siblings must be cached alongside the binaries that link
to them. Surfaced by test_mysqlx_e2e_handshake-t in the e2e-tests
job — the unit-tests binaries don't link libtap.so so they were
fine.
mysqlx-soak/setup-infras.bash: SELECT runtime_mysql_users and
runtime_mysql_servers before LOAD MYSQLX {USERS,BACKEND ENDPOINTS,
ROUTES} TO RUNTIME. The mysqlx plugin's install_*_from_admin
helpers query those tables directly via SQLite, but admin only
populates them on its lazy SELECT-trigger refresh — not by LOAD
MYSQL {USERS,SERVERS} TO RUNTIME. Without the COUNT(*) nudge here
the plugin sees empty source rows, the route never resolves to a
usable hostgroup, and the listener never binds on the soak port —
surfacing as "ERROR: mysqlx listener did not bind on port 6603
within 10s" in CI.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughCI now stages ChangesMySQLX Test Infrastructure Enhancement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates the setup-infras.bash script for the mysqlx-soak test group. It adds SELECT COUNT(*) queries on runtime_mysql_users and runtime_mysql_servers to force a lazy-refresh of these tables before loading MySQLX configurations, preventing empty source rows. There are no review comments to address, and I have no additional feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/CI-mysqlx.yml:
- Around line 57-58: The RE2 runtime location is misaligned: ensure the cached
path deps/re2/re2/obj/so/ is the canonical runtime dir and update build/link
flags to point at its "so" subdir; specifically, set RE2_LDIR references (or the
places that form -L and -Wl,-rpath) to use $(RE2_LDIR)/so where libre2.so*
actually lives, and/or add explicit -L$(RE2_LDIR)/so and
-Wl,-rpath,$(RE2_LDIR)/so in targets that link -lre2 (notably the linkage in
test/tap/tap/Makefile and any targets like
test/tap/tests_with_deps/deprecate_eof_support/Makefile that perform dynamic
linking), so libtap.so and executables can resolve libre2.so from the cached
obj/so directory.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 837d57ca-cac0-4b46-832f-1ee31fb2d36b
📒 Files selected for processing (2)
.github/workflows/CI-mysqlx.ymltest/tap/groups/mysqlx-soak/setup-infras.bash
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
{test/infra/**/*.bash,test/tap/**/Makefile,.github/workflows/**/*.yml}
📄 CodeRabbit inference engine (CLAUDE.md)
ALWAYS use
run-tests-isolated.bashfor running TAP tests. It handles infrastructure setup, ProxySQL start, test execution, and cleanup. Never manually create Docker networks, start containers, or run init scripts.
Files:
.github/workflows/CI-mysqlx.yml
🔇 Additional comments (2)
.github/workflows/CI-mysqlx.yml (1)
57-58: LGTM!Also applies to: 150-151, 214-215, 428-429
test/tap/groups/mysqlx-soak/setup-infras.bash (1)
85-95: LGTM!
The previous attempt added deps/re2/re2/obj/so/ and deps/postgresql/ .../libpq/libpq.so* to the build cache, but tar can't restore those on the downstream jobs: /usr/bin/tar: deps/re2/re2/obj: Cannot mkdir: No such file or directory `deps/re2/re2` is a symlink to `re2-2022-12-01/`, which is the extracted tarball and not part of the git tree. Sparse-checkout materialises the symlink but not its target, so tar can't traverse into deps/re2/re2/obj/ on restore. Sidestep the symlink chain: at the end of the build step copy the two SONAMEs libtap.so DT_NEEDEDs — libre2.so.10 and libpq.so.5 — into test/tap/tap/_runtime_libs/. That path is under test/, which the cache already preserves, and lives entirely inside the git tree (no symlinks to chase). The unit-tests and e2e-tests run steps then prepend that directory to LD_LIBRARY_PATH so the loader resolves libtap.so's deps without needing the deps/ tree materialised. soak-tests is unaffected — those binaries run inside Docker containers with their own library path.
…effect
Pre-existing caches keyed `build-${SHA}` were written by the run that
auto-fired BEFORE my staging step landed — i.e. they contain
src/proxysql + test/ + plugin.so but NOT
test/tap/tap/_runtime_libs/. With `if: cache-hit != 'true'` guarding
the build step, a hit on the legacy key skips the build (and
therefore the mkdir/cp staging) entirely. The e2e-tests step then
exports LD_LIBRARY_PATH=…/test/tap/tap/_runtime_libs which doesn't
exist on the runner, and test_mysqlx_e2e_handshake-t fails again
with `libre2.so.10: cannot open shared object file` — exactly the
symptom this PR was supposed to fix.
Manual cache-bust: prefix the key with `runtime-libs-v1-` so the
next run is a clean miss, the build step runs end-to-end including
the staging cp, and the new cache lays out _runtime_libs/
alongside the binaries. Bump the suffix again if the staging
layout changes incompatibly.
The Bring up infrastructure step pipes the SQL block to `mysql` via docker exec -i with stdin redirected from a heredoc. With stdin not attached to a tty `mysql` switches to a silent default that suppresses header + row output for non-error queries, so the existing SELECT COUNT(*) probes left no trace in the CI log — making it impossible to tell whether the lazy-refresh nudge ran, whether LOAD MYSQLX TO RUNTIME returned errors, or whether the install_*_from_admin path saw zero source rows. Two surgical changes: * `mysql --table` forces boxed output regardless of stdin shape, so SELECT results land in the runner log. * Add a final UNION SELECT that counts rows in runtime_mysqlx_users / runtime_mysqlx_routes / runtime_mysqlx_ backend_endpoints after the LOAD statements run. Zero in any of those columns localises the bind failure to install_*_from_admin having seen empty source rows.
1. env.sh racing $GITHUB_ENV — MYSQLX_E2E_PORT was overwritten
The Verify X Protocol step writes the dynamically-discovered
sandbox X port (e.g. 18408 for MySQL 8.4.8) into $GITHUB_ENV
so the test step sees the right port. The test step then runs
`source test/tap/groups/mysqlx-e2e/env.sh` which unconditionally
`export MYSQLX_E2E_PORT=33060`. After the source the port has
been clobbered back to the env.sh default and tests connect to
nothing on 33060. Capture the discovered port BEFORE sourcing,
restore it after.
Surfaced in run 27476177152's e2e-tests step:
not ok 1 - TCP connect to X port 33060 succeeds
2. mysqlx_thread.cpp::add_listener swallows bind/listen errors
The reconcile path calls add_listener which returns -1 on any
failure but logs nothing. The soak-tests "Bring up infrastructure"
step waits 10s for the listener and fails with
ERROR: mysqlx listener did not bind on port 6603 within 10s
with zero diagnostic in the proxysql container log. Add
fprintf(stderr, ...) on socket()/bind()/listen() failures so the
actual syscall errno makes it into the log on the next run.
3. Cache-key bump to v2 — pre-existing v1 caches are stale
The plugin .so source changed (new add_listener logging) and
the previous v1 cache for this SHA was written without the env.sh
workaround. A v1 cache hit would skip both the new staging path
and the corrected mysqlx_thread.cpp. Bump to v2; comment block
updated to record bump reasons.
Diagnostic milestone from 27476177152: the soak post-LOAD probes
showed runtime_mysqlx_users=1, runtime_mysqlx_routes=1,
runtime_mysqlx_backend_endpoints=1 — confirming the SELECT-nudge
fix DOES work and the listener-bind failure is independent of
the lazy-refresh chain. The add_listener errno will identify what
actually fails (port in use, permission denied, or something else).
Run 27479228546 confirmed e2e-tests now passes (env.sh port-override fix landed). soak-tests still fails on listener bind, but the add_listener errno log we added in v2 produced ZERO output — meaning add_listener was never called. The bind isn't failing, it isn't being attempted. To localise the bail-out, log on three frames: 1. `load_routes_to_runtime` (mysqlx_admin_schema.cpp) — log the COUNT(*) row count from mysqlx_routes WHERE active=1, and whether the weak `mysqlx_reconcile_listeners` symbol resolved to the strong def or to null. 2. `mysqlx_reconcile_listeners_impl` entry — log threads.size() and route_to_thread.size(). The function returns early when threads is empty. 3. Per-route loop in step 1 of reconcile_listeners_impl — log the raw bind spec from the store, the parsed host and port for each desired route. Cache key bumped to v3 because plugin .so changed.
Re-run of soak-tests for run 27482049216 finally captured the
diagnostic trace:
mysqlx: load_routes_to_runtime: mysqlx_routes active row_count=1,
reconcile_listeners=resolved
mysqlx: reconcile_listeners entered: threads=4 route_to_thread=0
mysqlx: reconcile_listeners: store has 1 active routes
mysqlx: reconcile_listeners: desired route name='r1' host='0.0.0.0'
port=6603 (raw bind='0.0.0.0:6603')
So:
- LOAD MYSQLX ROUTES TO RUNTIME runs ✓
- weak symbol resolves ✓
- reconcile sees 4 threads and 0 existing listeners ✓
- store has the route, parsed correctly to 0.0.0.0:6603 ✓
…and then nothing. No add_listener line, success or failure. Step 3
of reconcile must be bailing without calling add_listener at all,
OR add_listener succeeds (its success path was previously silent).
Disambiguate with three new fprintfs:
* `step3: pool=N desired_count=M route_to_thread_count=K` at the
top of the add loop — confirms we reach step 3 with a non-zero
desired set.
* `step3: route '...' -> tidx=N threads[tidx]=<non-null|NULL>`
per iteration — surfaces the bail-out if threads[tidx] is null
or if route_to_thread already had the route.
* `step3: add_listener rc=N` after the call so a successful bind
also leaves a trace.
* `add_listener entered: …` AND `add_listener(…): bind+listen OK,
fd=N` at the top and end of the add_listener function so we know
whether it ran at all and whether bind/listen completed.
Cache key bumped to v4.
Run 27484657649's v4 diagnostics in the plugin captured the full reconcile chain end-to-end: mysqlx: load_routes_to_runtime: ... row_count=1, reconcile_listeners=resolved mysqlx: reconcile_listeners entered: threads=4 route_to_thread=0 mysqlx: reconcile_listeners: store has 1 active routes mysqlx: reconcile_listeners: desired route name='r1' host='0.0.0.0' port=6603 mysqlx: reconcile_listeners step3: pool=4 desired_count=1 route_to_thread_count=0 mysqlx: reconcile_listeners step3: route 'r1' -> tidx=0 threads[tidx]=non-null mysqlx: add_listener entered: bind=0.0.0.0 port=6603 route=r1 mysqlx: add_listener(0.0.0.0:6603, route=r1): bind+listen OK, fd=90 mysqlx: reconcile_listeners step3: add_listener rc=0 So the listener IS up. The wait-loop probe is wrong. It runs `docker exec ... sh -c "exec 3<>/dev/tcp/127.0.0.1/PORT"` — but `/dev/tcp/<host>/<port>` is a bash builtin, and the proxysql container's /bin/sh is dash (Ubuntu default), which silently fails the redirection regardless of whether the listener is up. The loop times out every time and the step reports "mysqlx listener did not bind" even when the bind succeeded seconds earlier. Swap `sh -c` for `bash -c`. No other change.
…warning
The plugin had 22 fprintf(stderr,...) calls — 11 from this PR's
listener-reconcile diagnostic dig, 11 pre-existing for backend NOTICE
handling, TLS handshake failures, and missing-services. All are now
routed through ProxySQL's standard logger via proxy_info /
proxy_error / proxy_warning macros from include/proxysql_debug.h.
Why this is even possible: the plugin .so links proxy_error_func as
an undefined symbol; the main `src/proxysql` binary is built with
-Wl,--export-dynamic (lib/Makefile line 133), so the symbol resolves
at dlopen time from the host binary. Top-level `make debug` already
passes -DDEBUG into the plugin (Makefile line 288); that's the
codepath CI uses, so the DEBUG-format prefix
(file:line:func(): [INFO]) lights up in CI logs.
Severity mapping:
* proxy_error — auth failures (empty/malformed/unknown-type NOTICE
during backend auth, malformed NOTICE during data plane and
SESS_RESET), socket/bind/listen failures in add_listener, threads
empty bailing in reconcile_listeners, TLS handshake failures,
missing services in admin schema registration, add_listener rc!=0
and null-thread cases in the per-route reconcile loop.
* proxy_warning — backend-emitted WARNING and
GROUP_REPLICATION_STATE_CHANGED NOTICE frames during auth (drained
but operationally interesting).
* proxy_info — reconcile_listeners entry and active-route count,
per-route desired-bind log, add_listener entry and bind+listen OK,
load_routes_to_runtime row_count and weak-symbol resolution. These
fire once per LOAD MYSQLX ROUTES TO RUNTIME and once per chassis
start — low volume.
Also stripped the temporary verbose step3 traces in
mysqlx_reconcile_listeners_impl that helped narrow the soak
listener-bind diagnostic; the remaining INFO logs cover the same
information without the per-iteration noise.
Validated locally end-to-end:
- ./test/infra/control/destroy-infras.bash + ensure-infras.bash
with TAP_GROUP=mysqlx-soak brings up dbdeployer-mysql84 (3 nodes)
and proxysql with the new .so.
- docker logs proxysql.dev-soak-rene shows entries like:
2026-06-14 02:41:48 .../mysqlx_thread.cpp:377:add_listener():
[INFO] mysqlx: add_listener(0.0.0.0:6603, route=r1): bind+listen
OK, fd=96
confirming proxy_info routes through the proxysql logger.
- setup-infras.bash listener probe reports
>>> mysqlx listener is up on port 6603
Cache key bumped to v5 since the plugin .so changed.
Five blockers surfaced once the bash/sh listener-wait probe stopped lying: 1. test_mysqlx_route_drop_inflight-t.cpp — handshake protocol bugs identical to the pre-PR-#5823 state of test_mysqlx_e2e_handshake-t: reads an unsolicited Capabilities frame that never arrives, sends `CapabilitiesSet(authentication.mechanisms=MYSQL41)` which is read- only (X Plugin returns ER_X_CAPABILITIES_PREPARE_FAILED 5001), hex-decodes the raw 20-byte challenge, and uses the wrong AuthenticateContinue payload shape. Apply the same fix pattern from PR #5823: drop the unsolicited read, drop the CapabilitiesSet step, treat AuthenticateContinue.auth_data as raw bytes, send `\0schema\0user` on AuthStart and `*hex_scramble` on AuthContinue (ProxySQL plugin format). 2. test/infra/docker-base/Dockerfile — pip3 install pulled mysql-connector-python==9.7.0 by default, which dropped the X DevAPI `mysqlx` module (Oracle split it into a separate package from v9.x). The behavioral and stress harnesses then fail at `import mysqlx`. Add mysqlx-connector-python alongside. 3. test/tap/tests/test_mysqlx_soak_{behavioral,stress}-t.sh — two wrapper-script bugs that masked their own failure: - PROXYSQL_PATH walked up from $PWD which is /var/lib/proxysql inside the test-runner container; the harness lookup would always fall through to "." and python3 would silently report "No such file or directory". Walk up from $(dirname "$0") instead — the script's own location is mounted from the host worktree so its parent chain reaches src/proxysql_global.cpp. - The wrappers ran `python3 ${HARNESS} ... 2>&1 | sed '...'` without `set -o pipefail`, so a failing python3 left the pipeline exiting 0 (the sed exit) and the wrapper printed `ok 1` regardless. Add pipefail. Both tests previously reported false-PASS on every run. 4. test/scripts/mysqlx/behavioral_validation.py — the SIGTERM scenario calls `find_proxysql_pid()` which does `pidof proxysql` locally. In the docker-isolated harness ProxySQL runs in a separate container; the test-runner container has no `proxysql` process to find, so pidof exits 1 and the whole harness crashes before observing any client behaviour. Add a `--external-kill` flag: with it set, the harness skips the local pidof + os.kill path and just lets steady-traffic threads accumulate observations of the disconnect delivered by the wrapper's `docker kill -s TERM` in the background. Wire the behavioral .sh wrapper to pass --external-kill. 5. test/tap/groups/mysqlx-soak/setup-infras.bash — the `alice` fixture user was only created in ProxySQL's mysql_users + mysqlx_users. With backend_auth_mode='mapped' the mysqlx plugin then tries to authenticate alice on the BACKEND MySQL 8.4 X listener (port 33060), and the backend rejects with "Access denied for user 'alice'". Every forwarded session fails — surfaced as 100% error rate in the stress harness and "pre-drop SELECT 1 succeeded on 0/N sessions" in route_drop_inflight. Provision alice on each dbdeployer-mysql84 sandbox (master + 2 replicas) with mysql_native_password and GRANT ALL. Local end-to-end validation: - destroy-infras.bash + ensure-infras.bash + run-tests-isolated.bash against the rebuilt proxysql-ci-base image. - alice now authenticates on the backend (`docker exec proxysql.dev-soak-rene mysql -h <backend> -u alice -palicepass -e 'SELECT 1'` returns 1). - Stage 1 of test_mysqlx_route_drop_inflight-t now opens 5/5 sessions (was 0/5). - Stages 3-6 (admin drop + reload, listener teardown, TCP refusal, restore) all pass. REMAINING: Stage 2 (`pre-drop SELECT 1 succeeded on 0/5 sessions`) still fails. Same root cause as PR #5823's deferred follow-up note: mysqlx_session.cpp::forward_to_backend never drives server_ds() to XDS_READY for SQL frames, so the SELECT enqueued from the client side never reaches the backend or its response never returns. Affects both the C++ TAP test and Python mysqlx-connector-python clients identically. Out of scope for this PR (#5852) which is bounded to CI infrastructure + test-harness fixes; tracked alongside the deferred routing test from PR #5823.
…ed pwd) Three independent bugs, each of which on its own broke every off-the-shelf X-Protocol client against ProxySQL's mysqlx plugin. All three surfaced once the soak harness started running mysql-connector-python instead of the in-tree TAP test's bespoke wire emitter; the TAP test happened to sidestep them by sending the legacy ProxySQL shapes. 1. handler_auth_challenge_response only accepted MYSQL41 AuthContinue in the legacy bare `*hex_scramble` shape — the form our TAP test emits. Real X-Protocol clients send `<authzid>\0<authcid>\0<response>` where the response is either 20 raw bytes (the upstream MySQL X plugin's canonical shape) or `*<40 hex>`, optionally NUL-padded. Pre-fix, every stock client got 1045 with a valid scramble. Now parses all three shapes; also harvests authcid from the AuthContinue prefix when the AuthStart leg left username_ empty (stock clients put no credentials at all in AuthStart for MYSQL41). 2. MysqlxConnection::start_connect rejected anything that wasn't an IPv4 dotted-quad — the prior code's "hostnames are not supported here" stance. mysqlx_backend_endpoints.hostname accepts arbitrary strings and operators routinely populate it with DNS names (docker-compose service names, k8s services, etc.), so the session emitted 2003 for every first query. Adds a getaddrinfo fallback after the inet_pton fast path so already-resolved dotted-quads still skip DNS while names resolve cleanly. 3. handler_connecting_server unconditionally used identity_->backend_password when setting backend creds, but the mapped-mode contract is the symmetric counterpart of the existing backend_username pick: service_account rows carry both fields explicitly, mapped rows leave both empty and reuse the frontend credentials. Without the fallback, mapped sessions sent an empty password to the backend X plugin and backend auth always failed 1045 even when frontend auth succeeded. env.sh: the dbdeployer X-protocol port convention is classic+10000 not classic+20000, so the prior MYSQLX_BACKEND_X_PORT=23306 pointed every backend connection at a closed port. Verified via the sandbox's my.sandbox.cnf (mysqlx-port=13306).
Without an explicit ref: on actions/checkout under a workflow_run trigger, GitHub defaults to the workflow file's branch — v3.0 — even though workflow_run.head_sha points at the PR commit that fired CI-trigger. Net effect: every workflow_run-driven CI-mysqlx run since the workflow landed has built and tested v3.0 mainline while the run-name, cache key, and check display name all advertised the PR's head_sha. PR authors saw stable red across iterations because their fixes were never compiled. Adds the explicit ref to all four checkout steps (build, unit-tests, e2e-tests, soak-tests) so the four jobs run against the same SHA the rest of the workflow already names. Bumps the cache prefix to v6 because the v5 entries are wrong-source: keyed by PR SHA but containing v3.0 binaries. Without the bump the corrected workflow would cache-hit those stale entries and continue testing v3.0 indefinitely.
CI-mysqlx on v3.0 was the only test workflow that defined its jobs
inline instead of delegating to a reusable on this branch. Under
workflow_run, GitHub does not auto-decorate the PR with check_runs from
the calling workflow's own jobs — only the explicit
LouisBrunner/checks-action POST inside the dedicated-reusable pattern
does that. Net effect: every CI-mysqlx run since the workflow landed
was invisible on the PR status rollup, even on failure, so PR authors
saw "all green" while soak-tests and e2e-tests were red.
This file is the mirror of CI-mysqlx.yml@v3.0 in the same shape every
other CI test workflow follows (ci-legacy-g4.yml is the canonical
template): workflow_call interface, SHA derived from the trigger JSON,
permissions: write-all on each job, in_progress check posted at job
entry, conclusion check posted at job exit. The four job bodies (build,
unit-tests, e2e-tests, soak-tests) are migrated verbatim with their
existing comments preserved; the only structural changes are:
- cache key prefix bumped v6 -> v7 so the new reusable's runs don't
inherit v6 entries that were written by the old inline workflow
- ref/cache key/checkout all keyed off `env.SHA` (derived once at the
workflow level) instead of the long inline expression
- the soak-tests cache restore's fail-on-cache-miss gate moves from
`github.event_name == 'workflow_run'` to `inputs.trigger != ''`
since under workflow_call the event itself is no longer workflow_run
This file is half of the pair; the matching thin caller lands on v3.0
in PR #5852.
…er CI-*) CI-mysqlx was the only test workflow on v3.0 that defined its jobs inline instead of delegating to a dedicated reusable on the GH-Actions branch. Under workflow_run, GitHub only attaches check_runs to the originating PR when the running workflow explicitly POSTs them via LouisBrunner/checks-action — which every other CI-* does via its callee on GH-Actions, but the inline CI-mysqlx never did. Net effect: every CI-mysqlx run since the workflow landed was invisible on the PR status rollup. This PR's own iteration history is the proof: CI-mysqlx kept failing on b8a710c and d8c9448 with red soak/e2e jobs while the PR view showed 60 green checks and no mysqlx checks at all. Replaces the 554-line inline workflow with the 20-line caller that every other test workflow uses (see CI-legacy-g4.yml on v3.0 for the canonical shape, doc/GH-Actions/README.md § "The two-branch architecture" for the rationale). The matching ci-mysqlx.yml callee landed on GH-Actions in commit a0e783e with the four job bodies migrated verbatim and the LouisBrunner check_run posts added at job entry and exit. Net effect on this PR: CI-mysqlx's build/unit-tests/e2e-tests/soak-tests will now show up as four checks on the PR commit, with conclusions, so authors can see at a glance whether the workflow is actually green.
The unit-test Makefile's PROXYSQL40-gated block adds 14 genai_*_unit-t binaries to UNIT_TESTS. Each one statically links 30+ plugins/genai/ src/*.cpp files at debug -O0 -ggdb, landing at ~160 MB compiled (~2 GB for the full set). Combined with the rest of the chassis build, this blows past the ~14 GB free disk on the GitHub-hosted ubuntu-22.04 runner that ci-builds.yml@GH-Actions uses for the new -tap-mysqlx matrix variant. Add an opt-in env var SKIP_GENAI_UNIT_TESTS that cuts the genai_*_unit-t block from the unit-test build without touching the mysqlx_/plugin_/ test_mysqlx_ ones (which CI-mysqlx does run). The knob flows from ci-builds.yml's matrix-conditional sed-into-docker-compose -> the _build service's env passthrough list -> entrypoint.bash's EXTRA make args -> the unit Makefile's ifneq guard. Leaving the var unset on every other CI variant (everywhere except -tap-mysqlx in CI-builds, plus local PROXYSQL40 dev builds where the genai tests are wanted) keeps the full unit-test suite buildable when CI-unittests is re-enabled. This is the third refactor of how CI-mysqlx gets its artefacts (after the workflow_run check_run plumbing and the dedicated-reusable pattern). All three commits together get CI-mysqlx onto the same docker-compose build path every other CI workflow uses.
…ll path
Replaces -lprotobuf with $(PROTOBUF_LIB) -- the same approach
plugins/mysqlx/Makefile already uses -- in all 11 link rules of
test/tap/tests/unit/Makefile.
Root cause of the regression caught by CI-builds run 27585217607:
* The vendored protobuf 3.21.12 is built static-only
(protobuf_BUILD_SHARED_LIBS=OFF in deps/Makefile).
* The deb-compliant entrypoint installs libprotobuf-dev (system
v3.12) when PROXYSQL40=1. With both present in the link search
path, `-Bdynamic -lprotobuf` resolves to the system .so first
(.so > .a in ld's default search order) and never reaches the
vendored .a.
* The proto-generated .pb.o references symbols only in v3.21.12
(ZeroFieldsBase, AddDescriptorsRunner, ArenaStringPtr::Destroy,
...), so the link fails with thousands of undefined references
against the system v3.12.
Previously this worked only on hosts where libprotobuf-dev was NOT
installed system-wide (the fallback path inside ld: no .so found ->
use .a). That covers most developer machines but not the CI-builds
container, which apt-installs libprotobuf-dev unconditionally for
PROXYSQL40 builds via the existing pkg-config sanity branch in
entrypoint.bash.
Local dev not running ci-builds keeps working the same way; CI now
builds the unit tests successfully under -tap-mysqlx.
…as unit) Run 27587366723 of CI-builds got past the unit-test linker errors fixed in f65323b but stopped on the same protobuf 3.12 vs 3.21 mismatch at the next layer up: make[2]: *** [Makefile:401: test_mysqlx_e2e_routing-t] Error 1 ZeroFieldsBase, AddDescriptorsRunner, ArenaStringPtr::Set, ... /opt/proxysql/deps/protobuf/protobuf-3.21.12/install/include/.../arenastring.h:409: undefined reference Same root cause: test_mysqlx_e2e_handshake-t, test_mysqlx_e2e_routing-t, and test_mysqlx_route_drop_inflight-t in test/tap/tests/Makefile linked with -lprotobuf, which ld resolves against the system libprotobuf.so v3.12 that the deb-compliant entrypoint apt-installs for PROXYSQL40 builds. Switch all three rules to $(PROTOBUF_LIB) (full path to the vendored 3.21.12 static archive), mirroring what plugins/mysqlx/Makefile and test/tap/tests/unit/Makefile already do.
Run 27588618191 wrote a _src cache without libpq.so.5 + libre2.so.10, which broke the e2e-tests job in CI-mysqlx 27589710419. Those .so paths were added to ci-builds.yml@GH-Actions in commit 6b53c94, but re-dispatching CI-builds for the SAME SHA hits the existing cache via the lookup-only check and skips the build entirely. An empty commit bumps the SHA so CI-builds writes a fresh _src cache including the two .so files.
The previous _src cache for 2abbd6b had single-file paths for libpq.so.5 + libre2.so.10 which broke CI-mysqlx restore (missing symlink target, missing parent directories). Fixed in commit 8f52a91 on GH-Actions by switching to parent directory paths. Re-dispatching for the same SHA would hit the broken cache via cache-check; bump the SHA to write fresh.
The ci-builds.yml _src cache path was reverted to the original 2-path list in commit 54aeba8 on GH-Actions (it had been extended to include plugins/*.so which changed the cache version hash and broke ~40 downstream workflows). Bump SHA to force fresh CI-builds that saves under the correct version.
|




Summary
Two follow-up CI fixes surfaced after #5823 landed:
.github/workflows/CI-mysqlx.yml— add the shared libs thattest/tap/tap/libtap.soDT_NEEDEDs at runtime to every build-cache path. Withoutdeps/re2/re2/obj/so/libre2.so.10anddeps/postgresql/.../libpq.so.5in the cache, the downstreame2e-tests(andsoak-tests) jobs restore the test binaries but the dynamic loader fails with `error while loading shared libraries: libre2.so.10: cannot open shared object file`. The unit-test binaries don't link libtap.so, which is why the gap stayed hidden.test/tap/groups/mysqlx-soak/setup-infras.bash— `SELECT COUNT(*) FROM runtime_mysql_users` and `runtime_mysql_servers` between `LOAD MYSQL ... TO RUNTIME` and `LOAD MYSQLX ... TO RUNTIME`. The mysqlx plugin's `install_users_from_admin` / `install_endpoints_from_admin` query those tables directly via SQLite, but admin populates them only via its lazy SELECT-triggered refresh — not by `LOAD MYSQL {USERS,SERVERS} TO RUNTIME`. Without the nudge the plugin sees empty rows, the route can't resolve, and the listener never binds, surfacing as `ERROR: mysqlx listener did not bind on port 6603 within 10s`.Both diagnosed from the CI-mysqlx run for 3e80983 (PR #5823's pre-merge SHA).
Test plan
Summary by CodeRabbit
Tests
Chores
Bug Fixes