Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e393c3af3f
commit
4978089aab
4963 changed files with 677545 additions and 0 deletions
217
testutil/container.go
Normal file
217
testutil/container.go
Normal file
|
@ -0,0 +1,217 @@
|
|||
//go:build !freebsd
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
type TestLogConsumer struct {
|
||||
Msgs []string
|
||||
}
|
||||
|
||||
func (g *TestLogConsumer) Accept(l testcontainers.Log) {
|
||||
g.Msgs = append(g.Msgs, string(l.Content))
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
Entrypoint []string
|
||||
Env map[string]string
|
||||
Files map[string]string
|
||||
HostAccessPorts []int
|
||||
HostConfigModifier func(*container.HostConfig)
|
||||
ExposedPorts []string
|
||||
Cmd []string
|
||||
Image string
|
||||
Name string
|
||||
Hostname string
|
||||
Networks []string
|
||||
WaitingFor wait.Strategy
|
||||
|
||||
Address string
|
||||
Ports map[string]string
|
||||
Logs TestLogConsumer
|
||||
|
||||
container testcontainers.Container
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (c *Container) Start() error {
|
||||
c.ctx = context.Background()
|
||||
|
||||
files := make([]testcontainers.ContainerFile, 0, len(c.Files))
|
||||
for k, v := range c.Files {
|
||||
files = append(files, testcontainers.ContainerFile{
|
||||
ContainerFilePath: k,
|
||||
HostFilePath: v,
|
||||
FileMode: 0o755,
|
||||
})
|
||||
}
|
||||
|
||||
req := testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: testcontainers.ContainerRequest{
|
||||
Entrypoint: c.Entrypoint,
|
||||
Env: c.Env,
|
||||
ExposedPorts: c.ExposedPorts,
|
||||
Files: files,
|
||||
HostAccessPorts: c.HostAccessPorts,
|
||||
HostConfigModifier: c.HostConfigModifier,
|
||||
Cmd: c.Cmd,
|
||||
Image: c.Image,
|
||||
Name: c.Name,
|
||||
Hostname: c.Hostname,
|
||||
Networks: c.Networks,
|
||||
WaitingFor: c.WaitingFor,
|
||||
},
|
||||
Started: true,
|
||||
}
|
||||
|
||||
cntnr, err := testcontainers.GenericContainer(c.ctx, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("container failed to start: %w", err)
|
||||
}
|
||||
c.container = cntnr
|
||||
|
||||
c.Logs = TestLogConsumer{}
|
||||
c.container.FollowOutput(&c.Logs)
|
||||
if err := c.container.StartLogProducer(c.ctx); err != nil {
|
||||
return fmt.Errorf("log producer failed: %w", err)
|
||||
}
|
||||
|
||||
c.Address = "localhost"
|
||||
|
||||
info, err := c.GetInfo()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting info failed: %w", err)
|
||||
}
|
||||
fmt.Println("Started container:", info)
|
||||
|
||||
if err := c.LookupMappedPorts(); err != nil {
|
||||
c.Terminate()
|
||||
return fmt.Errorf("port lookup failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LookupMappedPorts creates a lookup table of exposed ports to mapped ports
|
||||
func (c *Container) LookupMappedPorts() error {
|
||||
if len(c.ExposedPorts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(c.Ports) == 0 {
|
||||
c.Ports = make(map[string]string)
|
||||
}
|
||||
|
||||
for _, port := range c.ExposedPorts {
|
||||
// strip off leading host port: 80:8080 -> 8080
|
||||
if strings.Contains(port, ":") {
|
||||
port = strings.Split(port, ":")[1]
|
||||
}
|
||||
|
||||
p, err := c.container.MappedPort(c.ctx, nat.Port(port))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find %q: %w", port, err)
|
||||
}
|
||||
|
||||
// strip off the transport: 80/tcp -> 80
|
||||
if strings.Contains(port, "/") {
|
||||
port = strings.Split(port, "/")[0]
|
||||
}
|
||||
|
||||
fmt.Printf("mapped container port %q to host port %q\n", port, p.Port())
|
||||
c.Ports[port] = p.Port()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) Exec(cmds []string) (int, io.Reader, error) {
|
||||
return c.container.Exec(c.ctx, cmds)
|
||||
}
|
||||
|
||||
func (c *Container) PrintLogs() {
|
||||
fmt.Println("--- Container Logs Start ---")
|
||||
for _, msg := range c.Logs.Msgs {
|
||||
fmt.Print(msg)
|
||||
}
|
||||
fmt.Println("--- Container Logs End ---")
|
||||
}
|
||||
|
||||
func (c *Container) Terminate() {
|
||||
if err := c.container.StopLogProducer(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
if err := c.container.Terminate(c.ctx); err != nil {
|
||||
fmt.Printf("failed to terminate the container: %s", err)
|
||||
}
|
||||
c.PrintLogs()
|
||||
}
|
||||
|
||||
func (c *Container) Pause() error {
|
||||
provider, err := testcontainers.NewDockerProvider()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting provider failed: %w", err)
|
||||
}
|
||||
|
||||
return provider.Client().ContainerPause(c.ctx, c.container.GetContainerID())
|
||||
}
|
||||
|
||||
func (c *Container) Resume() error {
|
||||
provider, err := testcontainers.NewDockerProvider()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting provider failed: %w", err)
|
||||
}
|
||||
|
||||
return provider.Client().ContainerUnpause(c.ctx, c.container.GetContainerID())
|
||||
}
|
||||
|
||||
func (c *Container) GetInfo() (string, error) {
|
||||
dc, ok := c.container.(*testcontainers.DockerContainer)
|
||||
if !ok {
|
||||
return "not a docker container", nil
|
||||
}
|
||||
|
||||
ci, err := dc.Inspect(c.ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("inspecting container failed: %w", err)
|
||||
}
|
||||
|
||||
provider, err := testcontainers.NewDockerProvider()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting provider failed: %w", err)
|
||||
}
|
||||
|
||||
summaries, err := provider.Client().ImageList(c.ctx, image.ListOptions{})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("listing images failed: %w", err)
|
||||
}
|
||||
|
||||
for _, s := range summaries {
|
||||
if s.ID != ci.ContainerJSONBase.Image {
|
||||
continue
|
||||
}
|
||||
var digest []string
|
||||
for _, d := range s.RepoDigests {
|
||||
if _, suffix, found := strings.Cut(d, "@"); found {
|
||||
digest = append(digest, suffix)
|
||||
} else {
|
||||
digest = append(digest, d)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%s (%s)", dc.Image, strings.Join(digest, ",")), nil
|
||||
}
|
||||
|
||||
return "unknown", nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue