Skip to content

test(rain): add mysql integration coverage#17

Merged
cungminh2710 merged 2 commits into
mainfrom
codex/linear-mention-qc-233-add-mysql-integration-tests-for-rain
Mar 29, 2026
Merged

test(rain): add mysql integration coverage#17
cungminh2710 merged 2 commits into
mainfrom
codex/linear-mention-qc-233-add-mysql-integration-tests-for-rain

Conversation

@cungminh2710
Copy link
Copy Markdown
Contributor

Motivation

  • Provide MySQL-backed integration coverage for the pkg/rain runtime paths so CI and local devs can verify behavior against a real MySQL server.
  • Match existing integration style used for SQLite and Postgres and keep the tests beginner-friendly and skip-able when MySQL is unavailable.
  • Ensure the MySQL dialect and schema paths (DDL, insert/select/scan, join) are exercised against a real driver.

Description

  • Add a new integration test file pkg/rain/mysql_integration_test.go that defines simple users/posts table models and tests table creation, inserts (defaults and explicit overrides), selects/scans, and an aliased join path.
  • Resolve MySQL connection settings from environment variables with mysqlIntegrationDSN() supporting RAIN_MYSQL_DSN or RAIN_MYSQL_HOST/RAIN_MYSQL_USER/RAIN_MYSQL_DB (and optional RAIN_MYSQL_PORT and RAIN_MYSQL_PASSWORD), and skip tests cleanly when configuration is missing.
  • Add the MySQL driver dependency github.com/go-sql-driver/mysql to go.mod/go.sum and import it in the test.
  • Update README.md to document the local command and environment variables to run the MySQL integration test (RAIN_MYSQL_DSN=... go test -race ./pkg/rain -run "^TestMySQLIntegration").

Testing

  • Ran make fmt which completed successfully.
  • Ran make lint which reported 0 issues.
  • Ran make test which executed the test suite successfully (ok for packages and coverage reports generated).
  • The MySQL integration test is designed to t.Skip when MySQL env vars are not provided; the test was not run against a live MySQL instance in this environment.

Codex Task

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 29, 2026

Greptile Summary

This PR adds MySQL-backed integration coverage for pkg/rain by introducing pkg/rain/mysql_integration_test.go, adds the github.com/go-sql-driver/mysql driver dependency, and documents the new test command in README.md. The implementation closely mirrors the existing Postgres integration test pattern — suffix-isolated table names, environment-variable-driven connection settings with a graceful t.Skip() when MySQL is unavailable, forward/reverse DDL ordering for FK-safe cleanup, and backtick quoting correct for MySQL identifiers.

Key observations:

  • The test structure, table definitions, insert/select/scan/join flow, and cleanup logic are consistent with the Postgres counterpart and should exercise the MySQL dialect paths correctly.
  • mysql.Config in mysqlIntegrationDSN() does not set ParseTime: true, so DATETIME columns are returned as []byte rather than time.Time. The test deliberately uses string for CreatedAt to avoid a scan error, but this is a subtle footgun for users who copy the env-var DSN builder and expect time.Time columns to work without a DSN-level override.
  • The go-sql-driver/mysql package is imported by name (not as a blank import _) because mysql.Config is used directly to programmatically build the DSN — this is the correct approach.
  • DROP TABLE cleanup correctly reverses the creation order (posts before users) to respect the FK constraint without needing CASCADE, which MySQL does not support in DROP TABLE.
  • The joinedPostRow type is reused from sqlite_integration_test.go (same rain_test package) rather than re-declared — correct and tidy.

Confidence Score: 5/5

Safe to merge — the only finding is a P2 style suggestion (missing ParseTime in the programmatic DSN builder) that does not affect test correctness.

All findings are P2 (non-blocking style/improvement suggestions). The test logic, DDL generation, cleanup ordering, and driver wiring are all correct. No data-integrity or correctness issues were identified.

No files require special attention.

Important Files Changed

Filename Overview
pkg/rain/mysql_integration_test.go New MySQL integration test mirroring the Postgres pattern; well-structured with env-based skip logic and suffix-isolated table names. Minor: mysql.Config lacks ParseTime: true, so DATETIME columns are returned as byte slices rather than time.Time; the test sidesteps this by using string for CreatedAt, but it's a footgun for adopters.
go.mod Adds github.com/go-sql-driver/mysql v1.7.1 as a direct dependency; minimal and correct change.
go.sum Adds the expected checksum entries for the MySQL driver; straightforward and correct.
README.md Documents the new MySQL integration test command and env vars; consistent with the existing Postgres section and accurate.

Sequence Diagram

sequenceDiagram
    participant Test as TestMySQLIntegrationInsertSelectAndJoin
    participant DSN as mysqlIntegrationDSN()
    participant Env as Environment Variables
    participant DB as rain.DB (MySQL)
    participant MySQL as MySQL Server

    Test->>DSN: resolve connection string
    DSN->>Env: check RAIN_MYSQL_DSN
    alt DSN env var set
        Env-->>DSN: return raw DSN
    else component vars set
        Env-->>DSN: HOST / USER / DB / PORT / PASSWORD
        DSN->>DSN: build via mysql.Config.FormatDSN()
    else nothing set
        DSN-->>Test: ok=false → t.Skip()
    end
    DSN-->>Test: dsn string

    Test->>DB: rain.Open("mysql", dsn)
    DB->>MySQL: open connection

    Test->>DB: CreateTableSQL(users) + Exec
    DB->>MySQL: CREATE TABLE users_<suffix>
    Test->>DB: CreateTableSQL(posts) + Exec
    DB->>MySQL: CREATE TABLE posts_<suffix>

    Test->>DB: Insert user (defaults)
    DB->>MySQL: INSERT INTO users_<suffix>
    Test->>DB: Insert user (overrides)
    DB->>MySQL: INSERT INTO users_<suffix>

    Test->>DB: Select + Scan (first user)
    DB->>MySQL: SELECT WHERE email = 'defaults@example.com'
    MySQL-->>DB: row
    DB-->>Test: mysqlUserRow{Name:"guest", Active:true, Nickname:"buddy"}

    Test->>DB: Insert post (userID=first.ID)
    DB->>MySQL: INSERT INTO posts_<suffix>

    Test->>DB: Select + Join + Scan
    DB->>MySQL: SELECT p.title, u.email FROM posts p JOIN users u ON p.user_id=u.id
    MySQL-->>DB: joined row
    DB-->>Test: joinedPostRow{Title:"Hello", Email:"defaults@example.com"}

    Note over Test,MySQL: t.Cleanup: DROP TABLE posts_<suffix>, DROP TABLE users_<suffix>
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: pkg/rain/mysql_integration_test.go
Line: 164-172

Comment:
**`ParseTime` not set in programmatic DSN builder**

When constructing the DSN from individual env vars (`RAIN_MYSQL_HOST` / `RAIN_MYSQL_USER` / `RAIN_MYSQL_DB`), `mysql.Config.ParseTime` defaults to `false`. With this setting the MySQL driver returns `DATETIME`/`TIMESTAMP` column values as `[]byte` (a string representation) rather than `time.Time`.

The test sidesteps a direct failure by declaring `mysqlUserRow.CreatedAt` as `string` instead of `time.Time`, but the omission is a footgun: anyone who copies this env-var path and expects `TimestampTZ` / `time.Time` columns to round-trip as proper Go time values will hit a runtime scan error. Adding `ParseTime: true` to the config struct is the conventional fix and matches what most ORM users would expect from an integration helper.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "test(rain): add mysql integration covera..." | Re-trigger Greptile

Comment on lines +164 to +172
cfg := mysql.Config{
Net: "tcp",
Addr: net.JoinHostPort(host, port),
User: user,
Passwd: strings.TrimSpace(os.Getenv("RAIN_MYSQL_PASSWORD")),
DBName: dbName,
}

return cfg.FormatDSN(), true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 ParseTime not set in programmatic DSN builder

When constructing the DSN from individual env vars (RAIN_MYSQL_HOST / RAIN_MYSQL_USER / RAIN_MYSQL_DB), mysql.Config.ParseTime defaults to false. With this setting the MySQL driver returns DATETIME/TIMESTAMP column values as []byte (a string representation) rather than time.Time.

The test sidesteps a direct failure by declaring mysqlUserRow.CreatedAt as string instead of time.Time, but the omission is a footgun: anyone who copies this env-var path and expects TimestampTZ / time.Time columns to round-trip as proper Go time values will hit a runtime scan error. Adding ParseTime: true to the config struct is the conventional fix and matches what most ORM users would expect from an integration helper.

Prompt To Fix With AI
This is a comment left during a code review.
Path: pkg/rain/mysql_integration_test.go
Line: 164-172

Comment:
**`ParseTime` not set in programmatic DSN builder**

When constructing the DSN from individual env vars (`RAIN_MYSQL_HOST` / `RAIN_MYSQL_USER` / `RAIN_MYSQL_DB`), `mysql.Config.ParseTime` defaults to `false`. With this setting the MySQL driver returns `DATETIME`/`TIMESTAMP` column values as `[]byte` (a string representation) rather than `time.Time`.

The test sidesteps a direct failure by declaring `mysqlUserRow.CreatedAt` as `string` instead of `time.Time`, but the omission is a footgun: anyone who copies this env-var path and expects `TimestampTZ` / `time.Time` columns to round-trip as proper Go time values will hit a runtime scan error. Adding `ParseTime: true` to the config struct is the conventional fix and matches what most ORM users would expect from an integration helper.

How can I resolve this? If you propose a fix, please make it concise.

@cungminh2710 cungminh2710 merged commit bef66d4 into main Mar 29, 2026
1 check passed
@cungminh2710 cungminh2710 deleted the codex/linear-mention-qc-233-add-mysql-integration-tests-for-rain branch March 29, 2026 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant