test(mysql): wire-protocol mock for the AllowCleartextPasswords gate - #2
Open
matt-royal wants to merge 1 commit into
Open
test(mysql): wire-protocol mock for the AllowCleartextPasswords gate#2matt-royal wants to merge 1 commit into
matt-royal wants to merge 1 commit into
Conversation
…words gate The AllowCleartextPasswords guard was covered only at the DSN-string and reconciler levels; nothing exercised go-sql-driver's actual client-side gate. That path can't be reproduced with a real MySQL server in CI: sha256_password is handled by the driver internally via RSA public-key exchange and never asks for cleartext, and the plugins that force a server to request mysql_clear_password (authentication_pam / authentication_ldap_simple) are MySQL Enterprise-only and absent from any community/CI image. This adds a self-contained TCP listener that speaks just enough of the MySQL wire protocol to advertise mysql_native_password in the initial handshake and then issue an AuthSwitchRequest to mysql_clear_password. The ordering is load-bearing: advertising cleartext in the initial handshake makes the driver silently fall back to native auth on ErrCleartextPassword, so only the auth-switch path returns the error without fallback and genuinely proves the gate rejects the connection. The test validates the double by asserting the same mock and query yield ErrCleartextPassword without allowCleartextPasswords and succeed with it set, which a fixed-response mock could not produce. This is the standing pattern for covering the RDS/Aurora IAM database-authentication (AWSAuthenticationPlugin) code path in real tests going forward.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a self-contained MySQL wire-protocol test double that exercises go-sql-driver's client-side
AllowCleartextPasswordsgate against a live TCP listener, plus a test that validates the double.Builds on the existing IAM-auth work in this branch (
feat(mysql): support AllowCleartextPasswords...and the reconciler-level guard test). Those cover the DSN string and theValidateAllowCleartextPasswordsguard; nothing exercised the driver's actual gate end to end.Why a mock instead of a real server
The cleartext path can't be reproduced with a real MySQL server in CI:
sha256_passwordis handled by the driver internally via RSA public-key exchange and never asks for cleartext.mysql_clear_password(authentication_pam/authentication_ldap_simple) are MySQL Enterprise-only and absent from any community/CI image (INSTALL PLUGIN ... authentication_pam.sofails with "cannot open shared object file").So a protocol-level mock is the only way to cover the gate in local/PR tests. This is the same gate RDS/Aurora IAM database authentication (
AWSAuthenticationPlugin) relies on in production.How it works
The listener advertises
mysql_native_passwordin the initial handshake, then issues anAuthSwitchRequesttomysql_clear_password. The ordering is load-bearing: if the initial handshake advertised cleartext directly, the driver silently falls back to native auth onErrCleartextPassword(connector.goConnect), so the gate would never be observed. Only the auth-switch path returns the error without fallback (handleAuthResult), so only it genuinely proves the gate is what rejects the connection.The test drives provider-sql's real
NewWithConfigat the mock and asserts the same server and query yieldErrCleartextPasswordwithoutallowCleartextPasswordsand succeed with it set. A fixed-response mock could not produce that differential.Reuse
The server helpers are unexported in the
mysqltest package, so they're available to any other_test.goinpkg/clients/mysql/today (e.g. a reconciler-levelConnect()test through the cleartext path). Promoting them to an exported helper or a small binary is the intended path for covering the IAM-auth code path in composition system tests later.Verification
go test ./pkg/clients/mysql/green, including under-race -count=5(no flakiness or data races).gofmtandgo vetclean.Generated with Claude Code 🤖