Skip to content

test(mysql): wire-protocol mock for the AllowCleartextPasswords gate - #2

Open
matt-royal wants to merge 1 commit into
gusto-mainfrom
wb-253-cleartext-mock
Open

test(mysql): wire-protocol mock for the AllowCleartextPasswords gate#2
matt-royal wants to merge 1 commit into
gusto-mainfrom
wb-253-cleartext-mock

Conversation

@matt-royal

Copy link
Copy Markdown

What

Adds a self-contained MySQL wire-protocol test double that exercises go-sql-driver's client-side AllowCleartextPasswords gate 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 the ValidateAllowCleartextPasswords guard; 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_password is handled by the driver internally via RSA public-key exchange and never asks for cleartext.
  • 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 (INSTALL PLUGIN ... authentication_pam.so fails 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_password in the initial handshake, then issues an AuthSwitchRequest to mysql_clear_password. The ordering is load-bearing: if the initial handshake advertised cleartext directly, the driver silently falls back to native auth on ErrCleartextPassword (connector.go Connect), 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 NewWithConfig at the mock and asserts the same server and query yield ErrCleartextPassword without allowCleartextPasswords and succeed with it set. A fixed-response mock could not produce that differential.

Reuse

The server helpers are unexported in the mysql test package, so they're available to any other _test.go in pkg/clients/mysql/ today (e.g. a reconciler-level Connect() 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).
  • gofmt and go vet clean.
  • golangci-lint (repo-pinned v2.10.1) reports no issues on the new file.

Generated with Claude Code 🤖

…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.

@gusto-fresh-eyes gusto-fresh-eyes Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM, approved.

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.

1 participant