Skip to content

feat: add TiDB module#3575

Merged
mdelapenya merged 2 commits intotestcontainers:mainfrom
iyiola-dev:feat/tidb-module
Mar 9, 2026
Merged

feat: add TiDB module#3575
mdelapenya merged 2 commits intotestcontainers:mainfrom
iyiola-dev:feat/tidb-module

Conversation

@iyiola-dev
Copy link
Copy Markdown
Contributor

Add a new Testcontainers module for TiDB, a MySQL-compatible distributed SQL database.

  • TiDB container with ports 4000 (MySQL protocol) and 10080 (REST API)
  • HTTP wait strategy on /status endpoint
  • ConnectionString and MustConnectionString methods
  • Tests and testable examples
  • Documentation and config updates (mkdocs, dependabot)

What does this PR do?

Adds a new tidb module under modules/tidb/, modeled after the Java TiDB module. The module provides:

  • TiDBContainer struct embedding testcontainers.Container
  • Run() entrypoint using pingcap/tidb image with exposed ports 4000/tcp (MySQL protocol) and 10080/tcp (REST API)
  • HTTP wait strategy on /status endpoint (port 10080), matching the Java implementation
  • ConnectionString() and MustConnectionString() methods returning MySQL-compatible DSNs
  • Driver-agnostic design — the MySQL driver (go-sql-driver/mysql) is only a test dependency
  • 3 tests (TestTiDB, TestTiDBWithDDLAndDML, TestTiDBSelect1) and 2 testable examples (ExampleRun, ExampleRun_connect)
  • Documentation at docs/modules/tidb.md
  • Config updates to mkdocs.yml and .github/dependabot.yml

Why is it important?

TiDB is a popular MySQL-compatible distributed SQL database with no existing Go module in testcontainers-go, while it already exists for Java. This module allows Go developers to use TiDB out of the box without needing to configure generic containers manually.

Related issues

How to test this PR

cd modules/tidb
go test -v -timeout 10m ./...

@iyiola-dev iyiola-dev requested a review from a team as a code owner March 9, 2026 11:43
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 9, 2026

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit 0d5f5fb
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/69aec231d86890000823dc32
😎 Deploy Preview https://deploy-preview-3575--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e20e07a7-e4c3-495e-814b-4378bde34afd

📥 Commits

Reviewing files that changed from the base of the PR and between 48ee3c5 and 0d5f5fb.

📒 Files selected for processing (2)
  • .github/dependabot.yml
  • mkdocs.yml
🚧 Files skipped from review as they are similar to previous changes (2)
  • mkdocs.yml
  • .github/dependabot.yml

Summary by CodeRabbit

  • New Features

    • Added a TiDB module to run a MySQL-compatible database container and obtain connection strings for tests.
  • Documentation

    • Added TiDB module docs with usage, configuration, and connection examples.
  • Tests

    • Added integration tests and example snippets demonstrating container lifecycle and database queries.
  • Chores

    • Updated project navigation and dependency monitoring; added module test invocation support.

Walkthrough

Adds a new TiDB module to testcontainers-go: implementation, examples, integration tests, documentation, Makefile fragment, and Dependabot config to include the module in gomod updates.

Changes

Cohort / File(s) Summary
Module Implementation
modules/tidb/tidb.go, modules/tidb/go.mod
New TiDB container wrapper: Container type, Run(ctx,img,opts...), ConnectionString/MustConnectionString, Go module file and deps (includes local replace).
Tests & Examples
modules/tidb/tidb_test.go, modules/tidb/examples_test.go
Adds three integration tests exercising DDL/DML and connectivity plus two example functions demonstrating startup and querying via the connection string.
Documentation & Site
docs/modules/tidb.md, mkdocs.yml
New module documentation file and registration in mkdocs navigation.
Build & CI
modules/tidb/Makefile, .github/dependabot.yml
Makefile fragment to run tidb tests (test -> test-tidb) and Dependabot configured to monitor /modules/tidb for gomod updates.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant Run as Run()
    participant Container as TiDB Container
    participant Wait as HTTP Wait Strategy
    participant MySQL as MySQL Driver
    participant DB as TiDB

    User->>Run: Run(ctx, img, opts...)
    Run->>Container: Create container (expose ports, env)
    Run->>Wait: Configure HTTP readiness (port 10080)
    Wait->>Container: Poll /health (HTTP)
    Wait-->>Run: Ready
    Run-->>User: *Container

    User->>Container: ConnectionString(ctx)
    Container-->>User: DSN

    User->>MySQL: Open(DSN) / Ping
    MySQL->>DB: Connect & Query
    DB-->>MySQL: Result
    MySQL-->>User: Query result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A tiny rabbit taps the keys tonight,
Spinning TiDB containers, all set to flight,
Connection strings snug like carrots in a row,
Tests hop along, watching queries go,
Hooray — the module blooms, soft and bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add TiDB module' clearly and concisely describes the main change in the changeset—adding a new TiDB module to testcontainers-go.
Description check ✅ Passed The description comprehensively explains the purpose, implementation details, and benefits of adding the TiDB module, directly relating to the changeset.
Linked Issues check ✅ Passed The PR fully addresses issue #3543's requirements: provides a native TiDB module with suitable defaults (image, ports, wait strategy), enables out-of-the-box support, and follows the Java reference implementation.
Out of Scope Changes check ✅ Passed All changes are scoped to the TiDB module implementation and documentation: module code, tests, examples, docs, and configuration updates for dependabot and mkdocs—all directly supporting the feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
modules/tidb/tidb_test.go (1)

62-70: Avoid duplicating the profile schema in two places.

modules/tidb/testdata/schema.sql already defines and seeds profile, so keeping the same DDL/DML inline here creates an easy drift point. Either load the fixture in this test or drop the unused file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@modules/tidb/tidb_test.go` around lines 62 - 70, The test in tidb_test.go
duplicates the profile DDL/DML via direct db.Exec calls for "CREATE TABLE ...
profile" and "INSERT INTO profile", which conflicts with
modules/tidb/testdata/schema.sql; replace the inline db.Exec calls by loading
and executing the SQL fixture from modules/tidb/testdata/schema.sql (read the
file contents and run db.Exec or a helper like loadTestFixture) or remove the
unused schema.sql file — update the code paths referencing db.Exec in
tidb_test.go and the "profile" setup so the schema is defined only once.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/modules/tidb.md`:
- Around line 13-15: The fenced code block containing the command "go get
github.com/testcontainers/testcontainers-go/modules/tidb" in
docs/modules/tidb.md lacks a language identifier; update the block opener to
include a language (e.g., "```bash") so the snippet is rendered with proper
syntax highlighting while keeping the command text unchanged.

In `@modules/tidb/tidb.go`:
- Around line 57-61: The current readiness only waits for the HTTP endpoint
(wait.ForHTTP("/status").WithPort(restAPIPort)) so Run() can return before the
SQL port (defaultPort) is accepting connections; update the container options in
moduleOpts to combine checks using wait.ForAll(...) so both
wait.ForListeningPort(defaultPort) and
wait.ForHTTP("/status").WithPort(restAPIPort) are awaited (replace the single
wait.ForHTTP call with wait.ForAll(wait.ForListeningPort(defaultPort),
wait.ForHTTP("/status").WithPort(restAPIPort))). Ensure you keep
testcontainers.WithExposedPorts(defaultPort, restAPIPort) and pass the composed
wait strategy to testcontainers.WithWaitStrategy.

---

Nitpick comments:
In `@modules/tidb/tidb_test.go`:
- Around line 62-70: The test in tidb_test.go duplicates the profile DDL/DML via
direct db.Exec calls for "CREATE TABLE ... profile" and "INSERT INTO profile",
which conflicts with modules/tidb/testdata/schema.sql; replace the inline
db.Exec calls by loading and executing the SQL fixture from
modules/tidb/testdata/schema.sql (read the file contents and run db.Exec or a
helper like loadTestFixture) or remove the unused schema.sql file — update the
code paths referencing db.Exec in tidb_test.go and the "profile" setup so the
schema is defined only once.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4ac04d0c-4e24-47ca-8c63-ed56e47ece18

📥 Commits

Reviewing files that changed from the base of the PR and between c4e345e and 72dc05e.

⛔ Files ignored due to path filters (1)
  • modules/tidb/go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • .github/dependabot.yml
  • docs/modules/tidb.md
  • mkdocs.yml
  • modules/tidb/Makefile
  • modules/tidb/examples_test.go
  • modules/tidb/go.mod
  • modules/tidb/testdata/schema.sql
  • modules/tidb/tidb.go
  • modules/tidb/tidb_test.go

Comment thread docs/modules/tidb.md
Comment thread modules/tidb/tidb.go Outdated
Copy link
Copy Markdown
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution! A few changes are needed to align with the project conventions. Please check the inline comments.

Copy link
Copy Markdown
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution! A few changes are needed to align with the project conventions. Please check the inline comments.

Comment thread modules/tidb/tidb.go Outdated
Comment thread modules/tidb/go.mod Outdated
Comment thread modules/tidb/tidb.go Outdated
Comment thread modules/tidb/examples_test.go
Comment thread modules/tidb/testdata/schema.sql Outdated
Comment thread modules/tidb/examples_test.go Outdated
Add a new Testcontainers module for TiDB, a MySQL-compatible distributed SQL database.

- Container struct with Run(), ConnectionString(), MustConnectionString()
- Ports 4000/tcp (MySQL protocol) and 10080/tcp (REST API)
- wait.ForAll with ForListeningPort and ForHTTP(/status) readiness strategy
- Tests and testable examples
- Documentation and config updates (mkdocs, dependabot)
- Go 1.25 / toolchain go1.25.7

Closes testcontainers#3543
@iyiola-dev
Copy link
Copy Markdown
Contributor Author

hi @mdelapenya this has been updated according to the changes requested

@mdelapenya mdelapenya self-assigned this Mar 9, 2026
@mdelapenya mdelapenya added the feature New functionality or new behaviors on the existing one label Mar 9, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
docs/modules/tidb.md (1)

13-15: ⚠️ Potential issue | 🟡 Minor

Add a language to the install snippet.

This fence is still untyped, so it keeps failing MD040 and loses syntax highlighting.

📝 Proposed fix
-```
+```bash
 go get github.com/testcontainers/testcontainers-go/modules/tidb
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/modules/tidb.md around lines 13 - 15, The code fence in the docs
example is untyped causing MD040; update the fenced block in tidb.md by adding
the language identifier (bash) to the opening fence so it reads ```bash and
preserves syntax highlighting for the go get snippet.


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>modules/tidb/tidb.go (1)</summary><blockquote>

`37-40`: **Match the MySQL module's query-arg assembly.**

Using `len(args) > 0` here means `ConnectionString(ctx, "")` emits a dangling `?`. Joining first and only prefixing when the result is non-empty keeps TiDB aligned with `modules/mysql/mysql.go`.

<details>
<summary>🔧 Proposed refactor</summary>

```diff
 	extraArgs := ""
 	if len(args) > 0 {
-		extraArgs = "?" + strings.Join(args, "&")
+		extraArgs = strings.Join(args, "&")
+	}
+	if extraArgs != "" {
+		extraArgs = "?" + extraArgs
 	}
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@modules/tidb/tidb.go` around lines 37 - 40, The code assembling query args in
modules/tidb (extraArgs := "" / if len(args) > 0 ...) can emit a dangling "?";
change the logic to first join args (e.g., joined := strings.Join(args, "&"))
and only prefix with "?" when joined is non-empty so ConnectionString (or the
function building the DSN in tidb.go) matches the behavior in
modules/mysql/mysql.go; update the code that constructs extraArgs in the same
function to use this check.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @docs/modules/tidb.md:

  • Around line 13-15: The code fence in the docs example is untyped causing
    MD040; update the fenced block in tidb.md by adding the language identifier
    (bash) to the opening fence so it reads ```bash and preserves syntax
    highlighting for the go get snippet.

Nitpick comments:
In @modules/tidb/tidb.go:

  • Around line 37-40: The code assembling query args in modules/tidb (extraArgs
    := "" / if len(args) > 0 ...) can emit a dangling "?"; change the logic to first
    join args (e.g., joined := strings.Join(args, "&")) and only prefix with "?"
    when joined is non-empty so ConnectionString (or the function building the DSN
    in tidb.go) matches the behavior in modules/mysql/mysql.go; update the code that
    constructs extraArgs in the same function to use this check.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `8eff5284-5141-4012-abdc-eda4cf0bfbb8`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 72dc05e81cb0c7ffe7a0ebcb821699b6895dcf51 and 48ee3c5620befd61f63a06626199d9bec15c4fe7.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `modules/tidb/go.sum` is excluded by `!**/*.sum`

</details>

<details>
<summary>📒 Files selected for processing (8)</summary>

* `.github/dependabot.yml`
* `docs/modules/tidb.md`
* `mkdocs.yml`
* `modules/tidb/Makefile`
* `modules/tidb/examples_test.go`
* `modules/tidb/go.mod`
* `modules/tidb/tidb.go`
* `modules/tidb/tidb_test.go`

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary>

* mkdocs.yml
* .github/dependabot.yml

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Copy Markdown
Member

@mdelapenya mdelapenya left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for adding this module

@mdelapenya mdelapenya merged commit c411ba4 into testcontainers:main Mar 9, 2026
17 checks passed
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…48.0

* main:
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)

# Conflicts:
#	go.sum
mdelapenya added a commit that referenced this pull request Mar 9, 2026
* main:
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)

# Conflicts:
#	go.mod
#	go.sum
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…m-v2

* upstream/main: (269 commits)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/grafana-lgtm (#3563)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/toxiproxy (#3564)
  feat(azure): add lowkey vault container (#3542)
  feat(chroma): update to chroma 1.x (#3552)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3547)
  chore(deps): bump tj-actions/changed-files from 47.0.0 to 47.0.1 (#3546)
  chore(deps): bump actions/upload-artifact from 4.6.2 to 6.0.0 (#3545)
  ...
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…archive-temp

* upstream/main:
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/grafana-lgtm (#3563)
  chore(deps): bump go.opentelemetry.io/otel/sdk in /modules/toxiproxy (#3564)
mdelapenya added a commit that referenced this pull request Mar 9, 2026
…-temp

* upstream/main:
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
mdelapenya added a commit that referenced this pull request Mar 10, 2026
…lugin

* upstream/main:
  chore(deps): bump golang.org/x/mod in /modules/localstack (#3587)
  chore(deps): bump golang.org/x/mod in /modules/elasticsearch (#3585)
  chore(deps): bump golang.org/x/mod in /modules/redpanda (#3588)
  chore(deps): bump golang.org/x/mod in /modules/kafka (#3586)
  chore(deps): bump github.com/shirou/gopsutil/v4 from 4.25.12 to 4.26.2 (#3576)
  chore(deps): bump github.com/moby/go-archive from 0.1.0 to 0.2.0 (#3548)
  chore(deps): bump github.com/moby/term from 0.5.0 to 0.5.2 (#3081)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
mdelapenya added a commit that referenced this pull request Mar 10, 2026
…-action

* upstream/main: (22 commits)
  chore(deps): bump golang.org/x/mod in /modules/localstack (#3587)
  chore(deps): bump golang.org/x/mod in /modules/elasticsearch (#3585)
  chore(deps): bump golang.org/x/mod in /modules/redpanda (#3588)
  chore(deps): bump golang.org/x/mod in /modules/kafka (#3586)
  chore(deps): bump github.com/shirou/gopsutil/v4 from 4.25.12 to 4.26.2 (#3576)
  chore(deps): bump github.com/moby/go-archive from 0.1.0 to 0.2.0 (#3548)
  chore(deps): bump github.com/moby/term from 0.5.0 to 0.5.2 (#3081)
  chore(deps): bump actions/checkout from 6.0.1 to 6.0.2 (#3560)
  chore(deps): bump go.opentelemetry.io/otel/sdk to v1.41.0 (#3589)
  feat: add TiDB module (#3575)
  feat: add Forgejo module (#3556)
  feat: improve container conflict detection (#3574)
  chore(deps): bump go to 1.25 everywhere (#3572)
  chore(pulsar): bump base image to 4.x, replacing the wait for log strategy with wait for listening port (deterministic) (#3573)
  chore(deps): bump github.com/sigstore/sigstore in /modules/compose (#3571)
  chore(compose): update to compose-v5 (#3568)
  chore(deps): bump github.com/modelcontextprotocol/go-sdk (#3557)
  chore(deps): bump mkdocs-codeinclude-plugin from 0.2.1 to 0.3.1 (#3561)
  chore: update usage metrics (2026-03-02) (#3565)
  chore(deps): bump mkdocs-include-markdown-plugin from 7.2.0 to 7.2.1 (#3562)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New functionality or new behaviors on the existing one

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add TiDB module

2 participants