Sobre el proyecto
# go-docker-testsuite
Una biblioteca Go para ejecutar dependencias de terceros en contenedores Docker para pruebas de integración. Permite levantar cualquier imagen Docker (bases de datos, colas, cachés o almacenamiento de objetos) y conectarse a ellas desde tus pruebas Go.
## Características
- **Container** — envoltorio de bajo nivel para crear, ejecutar, esperar salida y limpiar cualquier imagen Docker
- **Group** — ejecuta múltiples contenedores en una red Docker aislada con conectividad a nivel de IP
- **Applications** — envoltorios listos para servicios populares (MySQL, PostgreSQL, Redis, Kafka, etc.)
- **Hooks** — callbacks del ciclo de vida (BeforeRun, AfterRun, BeforeClose, AfterClose) por contenedor
- **Exec** — ejecuta comandos dentro de un contenedor en ejecución y captura stdout, stderr y código de salida
- **Comandos de ciclo de vida** — ejecuta comandos de inicio / post-listos mediante exec
- **Copiar archivos a contenedores** — siembra archivos antes de iniciar con `WithFiles`
- **Copiar archivos desde contenedores** — lee archivos de un contenedor en ejecución como flujo tar
- **Límites de recursos** — limita CPU/memoria/pids para proteger el host y CI
- **Matchers** — espera registros de contenedor con matchers de subcadena, exactos o regexp
- **Estrategias de espera** — sondas de preparación componibles (ForLog, ForHTTPGet, ForCommand, ForTCPConnection)
- **Constructor de entorno** — DSL fluido para variables de entorno tipadas
- **Enlaces de puertos** — mapeo de puertos DNAT con asignación aleatoria o uno a uno
- **Modo de red** — soporte de red host o personalizada
- **IMAGE_PREFIX** — enruta imágenes a través de un proxy/mirror
- **Enlace `*testing.T`** — limpieza automática y registro con `t.Parallel()` seguro
## Requisitos
- Go 1.26+
- Un demonio Docker en ejecución (funciona con hosts remotos mediante `DOCKER_HOST`)
## Instalación
Espacio de trabajo multimódulo: la raíz es el módulo central, y cada aplicación bajo `applications/<nombre>` es su propio módulo Go. Extrae solo lo que necesites:
```sh
go get github.com/teran/go-docker-testsuite
# Envoltorio de aplicación específico:
go get github.com/teran/go-docker-testsuite/applications/redis
go get github.com/teran/go-docker-testsuite/applications/postgres
```
## Aplicaciones
Envoltorios listos (cada uno devuelve una interfaz de cliente tipada y maneja inicio, verificaciones de salud y limpieza):
- Ceph (RGW) con AWS SDK v2
- ClickHouse con clickhouse-go
- Forgejo con SQLite
- Suite de enrutamiento FRR con vtysh
- K3s con client-go
- Kafka con Sarama
- Memcache con gomemcache
- MinIO (compatible con S3)
- MongoDB con mongo-driver
- MySQL / MariaDB / Percona Server
- NetBox con PostgreSQL + Redis
- Nginx
- OpenSearch con opensearch-go
- Paperless-ngx con PostgreSQL + Valkey
- PostgreSQL con pgx
- Prometheus con prometheus/client_golang
- RabbitMQ (AMQP + API de gestión)
- Redis con go-redis
- ScyllaDB con gocql
- Vault
- Libvirtd (KVM/QEMU)
Muchos paquetes incluyen ejemplos comprobables en pkg.go.dev.
## Uso
### Inicio rápido — 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)
}
}
```
### Grupo de múltiples contenedores
```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)
}
```
### Estrategias de espera
```go
if err := wait.Wait(ctx, c, wait.ForHTTPGet(8080,
wait.WithPath("/health"),
wait.WithResponseStatuses(200),
)); err != nil {
panic(err)
}
```
Otras estrategias: `ForLog`, `ForCommand`, `ForTCPConnection`. Combínalas con `ForAll` / `ForAny` / `ForAtLeast`.
### Enlace `*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) // fail-fast; registra t.Cleanup
}
```
### Hooks del ciclo de vida
```go
docker.HookTypeBeforeRun // antes de que el contenedor inicie
docker.HookTypeAfterRun // después de que el contenedor inicie
docker.HookTypeBeforeClose // antes de que el contenedor se detenga
docker.HookTypeAfterClose // después de que el contenedor se detenga
```
### Exec y comandos de ciclo de vida
```go
res, err := c.Exec(ctx, []string{"echo", "hello"})
if err != nil {
panic(err)
}
if err := res.Error(); err != nil {
panic(err)
}
fmt.Printf("código de salida: %d\n", res.ExitCode)
fmt.Printf("stdout: %s", res.Stdout)
```
### Copiar archivos hacia/desde contenedores
Usa `WithFiles` con `FileFromBytes` para contenido pequeño o un `io.Reader` + `Size` para archivos grandes. Lee archivos de vuelta con `docker.CopyFromContainer`.
### Prefijo de imagen / proxy
```sh
export IMAGE_PREFIX=registry-mirror.example.com
```
## Módulos y versiones
Espacio de trabajo multimódulo con un solo número de versión, etiquetado por separado (por ejemplo, núcleo `v1.6.0`, aplicación `applications/redis/v1.6.0`). Orden de lanzamiento: primero el núcleo, luego las aplicaciones. Usa el Makefile para etiquetar.
## Licencia
Apache License, Versión 2.0
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.