このプロジェクトについて
# go-docker-testsuite
Go製の統合テスト用ライブラリ。Dockerコンテナ内でサードパーティの依存関係を実行し、Goテストから接続できるようにする。データベース、キュー、キャッシュ、オブジェクトストレージなど、任意のDockerイメージを起動できる。
## 機能
- **Container** — 任意のDockerイメージを作成、実行、出力待機、クリーンアップする低レベルラッパー
- **Group** — 分離されたDockerネットワーク上で複数のコンテナをIPレベルで接続して実行
- **Applications** — 一般的なサービス(MySQL、PostgreSQL、Redis、Kafkaなど)向けの既製ラッパー
- **Hooks** — コンテナごとのライフサイクルコールバック(BeforeRun、AfterRun、BeforeClose、AfterClose)
- **Exec** — 実行中のコンテナ内でコマンドを実行し、stdout、stderr、終了コードを取得
- **ライフサイクルコマンド** — execによる起動時/準備完了後のコマンド実行
- **コンテナへのファイルコピー** — `WithFiles`で起動前にファイルをシード
- **コンテナからのファイルコピー** — 実行中のコンテナからtarストリームとしてファイルを読み出し
- **リソース制限** — CPU/メモリ/pidsを制限してホストとCIを保護
- **マッチャー** — 部分一致、完全一致、正規表現マッチャーでコンテナログを待機
- **待機戦略** — 合成可能な準備完了プローブ(ForLog、ForHTTPGet、ForCommand、ForTCPConnection)
- **環境ビルダー** — 型付き環境変数のための流暢なDSL
- **ポートバインディング** — ランダムまたは1対1割り当てによるDNATポートマッピング
- **ネットワークモード** — ホストまたはカスタムネットワークのサポート
- **IMAGE_PREFIX** — プロキシ/ミラー経由でイメージをルーティング
- **`*testing.T`バインディング** — 安全な`t.Parallel()`による自動ティアダウンとロギング
## 要件
- Go 1.26以上
- 実行中のDockerデーモン(`DOCKER_HOST`経由でリモートホストでも動作)
## インストール
マルチモジュールワークスペース:ルートがコアモジュールで、`applications/<name>`配下の各アプリケーションが独自のGoモジュール。必要なものだけを取得:
```sh
go get github.com/teran/go-docker-testsuite
# 特定のアプリケーションラッパー:
go get github.com/teran/go-docker-testsuite/applications/redis
go get github.com/teran/go-docker-testsuite/applications/postgres
```
## アプリケーション
既製ラッパー(それぞれ型付きクライアントインターフェースを返し、起動、ヘルスチェック、クリーンアップを処理):
- Ceph(RGW)+ AWS SDK v2
- ClickHouse + clickhouse-go
- Forgejo + SQLite
- FRRルーティングスイート + vtysh
- K3s + client-go
- Kafka + Sarama
- Memcache + gomemcache
- MinIO(S3互換)
- MongoDB + mongo-driver
- MySQL / MariaDB / Percona Server
- NetBox + PostgreSQL + Redis
- Nginx
- OpenSearch + opensearch-go
- Paperless-ngx + PostgreSQL + Valkey
- PostgreSQL + pgx
- Prometheus + prometheus/client_golang
- RabbitMQ(AMQP + 管理API)
- Redis + go-redis
- ScyllaDB + gocql
- Vault
- Libvirtd(KVM/QEMU)
多くのパッケージにはpkg.go.devでテスト可能な例が含まれています。
## 使用法
### クイックスタート — MySQL
```go
package main
import (
"context"
"database/sql"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/teran/go-docker-testsuite/applications/mysql"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
app, err := mysql.New(ctx, "index.docker.io/library/mysql:8.0.4")
if err != nil {
panic(err)
}
defer app.Close(ctx)
if err := app.CreateDB(ctx, "important_database"); err != nil {
panic(err)
}
db, err := sql.Open("mysql", app.MustDSN("important_database"))
if err != nil {
panic(err)
}
defer db.Close()
if _, err := db.ExecContext(ctx, "SELECT 1"); err != nil {
panic(err)
}
}
```
### マルチコンテナグループ
```go
package main
import (
"context"
"time"
"github.com/teran/go-docker-testsuite"
"github.com/teran/go-docker-testsuite/wait"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
app := docker.NewApplication(
c,
docker.HookFunc(func(ctx context.Context, ht docker.HookType, c docker.Container) error {
return wait.Wait(ctx, c, wait.ForLog(docker.NewSubstringMatcher("ready")))
}),
)
g, err := docker.NewGroup("my-services", app1, app2)
if err != nil {
panic(err)
}
if err := g.Run(ctx); err != nil {
panic(err)
}
defer g.Close(ctx)
}
```
### 待機戦略
```go
if err := wait.Wait(ctx, c, wait.ForHTTPGet(8080,
wait.WithPath("/health"),
wait.WithResponseStatuses(200),
)); err != nil {
panic(err)
}
```
その他の戦略:`ForLog`、`ForCommand`、`ForTCPConnection`。`ForAll` / `ForAny` / `ForAtLeast`と組み合わせ可能。
### `*testing.T`バインディング
```go
func TestRedis(t *testing.T) {
t.Parallel()
c, err := docker.NewContainerWithT(
t,
"redis",
images.Redis,
nil,
docker.NewEnvironment(),
docker.NewPortBindings().PortDNAT(docker.ProtoTCP, 6379),
)
if err != nil {
t.Fatal(err)
}
c.RunT(ctx) // フェイルファスト;t.Cleanupを登録
}
```
### ライフサイクルフック
```go
docker.HookTypeBeforeRun // コンテナ起動前
docker.HookTypeAfterRun // コンテナ起動後
docker.HookTypeBeforeClose // コンテナ停止前
docker.HookTypeAfterClose // コンテナ停止後
```
### Execとライフサイクルコマンド
```go
res, err := c.Exec(ctx, []string{"echo", "hello"})
if err != nil {
panic(err)
}
if err := res.Error(); err != nil {
panic(err)
}
fmt.Printf("exit code: %d\n", res.ExitCode)
fmt.Printf("stdout: %s", res.Stdout)
```
### コンテナへの/からのファイルコピー
小さなコンテンツには`FileFromBytes`を、大きなファイルには`io.Reader` + `Size`を`WithFiles`で使用。`docker.CopyFromContainer`でファイルを読み戻す。
### イメージプレフィックス / プロキシ
```sh
export IMAGE_PREFIX=registry-mirror.example.com
```
## モジュールとリリース
単一バージョン番号のマルチモジュールワークスペースで、個別にタグ付け(例:コア`v1.6.0`、アプリケーション`applications/redis/v1.6.0`)。リリース順序:コアが先、次にアプリケーション。タグ付けにはMakefileを使用。
## ライセンス
Apache License, Version 2.0
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.