mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
- Add comprehensive test coverage for agent report, flush buffer, and deps - Expand flow, HTTP, CPU, and swarm test coverage - Refactor registry access to use deps interface for better testability - Add container update and self-update test scenarios
170 lines
4.9 KiB
Go
170 lines
4.9 KiB
Go
package dockeragent
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
systemtypes "github.com/docker/docker/api/types/system"
|
|
"github.com/docker/docker/client"
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
func TestTryRuntimeCandidate(t *testing.T) {
|
|
t.Run("new client error", func(t *testing.T) {
|
|
swap(t, &newDockerClientFn, func(_ ...client.Opt) (dockerClient, error) {
|
|
return nil, errors.New("dial failed")
|
|
})
|
|
|
|
if _, _, err := tryRuntimeCandidate(nil); err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
})
|
|
|
|
t.Run("info error closes client", func(t *testing.T) {
|
|
closed := false
|
|
fake := &fakeDockerClient{
|
|
infoFunc: func(_ context.Context) (systemtypes.Info, error) {
|
|
return systemtypes.Info{}, errors.New("info failed")
|
|
},
|
|
closeFn: func() error {
|
|
closed = true
|
|
return nil
|
|
},
|
|
}
|
|
swap(t, &newDockerClientFn, func(_ ...client.Opt) (dockerClient, error) {
|
|
return fake, nil
|
|
})
|
|
|
|
if _, _, err := tryRuntimeCandidate(nil); err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
if !closed {
|
|
t.Fatal("expected Close to be called on error")
|
|
}
|
|
})
|
|
|
|
t.Run("success", func(t *testing.T) {
|
|
fake := &fakeDockerClient{
|
|
infoFunc: func(_ context.Context) (systemtypes.Info, error) {
|
|
return systemtypes.Info{ServerVersion: "24.0.0"}, nil
|
|
},
|
|
}
|
|
swap(t, &newDockerClientFn, func(_ ...client.Opt) (dockerClient, error) {
|
|
return fake, nil
|
|
})
|
|
|
|
gotClient, info, err := tryRuntimeCandidate(nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if gotClient != fake {
|
|
t.Fatal("expected returned client to match fake")
|
|
}
|
|
if info.ServerVersion != "24.0.0" {
|
|
t.Fatalf("expected info to be returned")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestConnectRuntime(t *testing.T) {
|
|
t.Run("no candidates", func(t *testing.T) {
|
|
swap(t, &buildRuntimeCandidatesFn, func(_ RuntimeKind) []runtimeCandidate {
|
|
return nil
|
|
})
|
|
|
|
if _, _, _, err := connectRuntime(RuntimeAuto, nil); err == nil {
|
|
t.Fatal("expected error with no candidates")
|
|
}
|
|
})
|
|
|
|
t.Run("candidate failure accumulates attempts", func(t *testing.T) {
|
|
swap(t, &buildRuntimeCandidatesFn, func(_ RuntimeKind) []runtimeCandidate {
|
|
return []runtimeCandidate{{label: "first"}}
|
|
})
|
|
swap(t, &tryRuntimeCandidateFn, func(_ []client.Opt) (dockerClient, systemtypes.Info, error) {
|
|
return nil, systemtypes.Info{}, errors.New("no socket")
|
|
})
|
|
|
|
if _, _, _, err := connectRuntime(RuntimeAuto, nil); err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
})
|
|
|
|
t.Run("preference mismatch returns error", func(t *testing.T) {
|
|
fake := &fakeDockerClient{daemonHost: "unix:///run/podman/podman.sock"}
|
|
swap(t, &buildRuntimeCandidatesFn, func(_ RuntimeKind) []runtimeCandidate {
|
|
return []runtimeCandidate{{label: "podman"}}
|
|
})
|
|
swap(t, &tryRuntimeCandidateFn, func(_ []client.Opt) (dockerClient, systemtypes.Info, error) {
|
|
return fake, systemtypes.Info{ServerVersion: "4.6.1"}, nil
|
|
})
|
|
|
|
_, _, _, err := connectRuntime(RuntimeDocker, nil)
|
|
if err == nil {
|
|
t.Fatal("expected error")
|
|
}
|
|
if !strings.Contains(err.Error(), "detected podman runtime") {
|
|
t.Fatalf("expected mismatch error, got %v", err)
|
|
}
|
|
})
|
|
|
|
t.Run("success with logger", func(t *testing.T) {
|
|
fake := &fakeDockerClient{daemonHost: "unix:///var/run/docker.sock"}
|
|
swap(t, &buildRuntimeCandidatesFn, func(_ RuntimeKind) []runtimeCandidate {
|
|
return []runtimeCandidate{{label: "docker"}}
|
|
})
|
|
swap(t, &tryRuntimeCandidateFn, func(_ []client.Opt) (dockerClient, systemtypes.Info, error) {
|
|
return fake, systemtypes.Info{ServerVersion: "24.0.0"}, nil
|
|
})
|
|
|
|
logger := zerolog.Nop()
|
|
cli, info, runtimeKind, err := connectRuntime(RuntimeAuto, &logger)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if cli != fake {
|
|
t.Fatalf("expected client to be returned")
|
|
}
|
|
if info.ServerVersion != "24.0.0" {
|
|
t.Fatalf("expected info to be returned")
|
|
}
|
|
if runtimeKind != RuntimeDocker {
|
|
t.Fatalf("expected runtime docker, got %v", runtimeKind)
|
|
}
|
|
})
|
|
|
|
t.Run("mismatch then success with host opts", func(t *testing.T) {
|
|
podman := &fakeDockerClient{daemonHost: "unix:///run/podman/podman.sock"}
|
|
docker := &fakeDockerClient{daemonHost: "unix:///var/run/docker.sock"}
|
|
|
|
swap(t, &buildRuntimeCandidatesFn, func(_ RuntimeKind) []runtimeCandidate {
|
|
return []runtimeCandidate{
|
|
{label: "podman", host: "unix:///run/podman/podman.sock", applyDockerEnv: true},
|
|
{label: "docker", host: "unix:///var/run/docker.sock"},
|
|
}
|
|
})
|
|
|
|
calls := 0
|
|
swap(t, &tryRuntimeCandidateFn, func(opts []client.Opt) (dockerClient, systemtypes.Info, error) {
|
|
calls++
|
|
if calls == 1 {
|
|
if len(opts) < 2 {
|
|
t.Fatalf("expected opts to include env and host")
|
|
}
|
|
return podman, systemtypes.Info{ServerVersion: "4.6.1"}, nil
|
|
}
|
|
return docker, systemtypes.Info{ServerVersion: "24.0.0"}, nil
|
|
})
|
|
|
|
cli, _, runtimeKind, err := connectRuntime(RuntimeDocker, nil)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if cli != docker || runtimeKind != RuntimeDocker {
|
|
t.Fatalf("expected docker runtime after mismatch")
|
|
}
|
|
})
|
|
}
|