lazydocker/pkg/commands/socket_detection_test.go
DeiAsPie cb517d9e09
Implement proper detection with Podman support and enhance error handling across platforms
Signed-off-by: DeiAsPie <93835541+DeiAsPie@users.noreply.github.com>
2025-12-27 13:19:14 +05:30

180 lines
4.7 KiB
Go

//go:build !windows
package commands
import (
"context"
"errors"
"os"
"testing"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
func TestGetSocketCandidates(t *testing.T) {
// Save env vars
oldXdg := os.Getenv("XDG_RUNTIME_DIR")
oldHome := os.Getenv("HOME")
defer func() {
os.Setenv("XDG_RUNTIME_DIR", oldXdg)
os.Setenv("HOME", oldHome)
}()
os.Setenv("XDG_RUNTIME_DIR", "/tmp/runtime")
os.Setenv("HOME", "/home/user")
candidates := getSocketCandidates()
// Check some expected candidates
foundDocker := false
foundPodman := false
for _, c := range candidates {
if c.Path == "unix:///var/run/docker.sock" {
foundDocker = true
}
if c.Path == "unix:///tmp/runtime/podman/podman.sock" {
foundPodman = true
}
}
assert.True(t, foundDocker, "Standard Docker socket should be in candidates")
assert.True(t, foundPodman, "Rootless Podman socket should be in candidates")
}
func TestDetectDockerHost_DOCKER_HOST_Priority(t *testing.T) {
// Save env var
oldDockerHost := os.Getenv("DOCKER_HOST")
defer os.Setenv("DOCKER_HOST", oldDockerHost)
expectedHost := "unix:///tmp/custom.sock"
os.Setenv("DOCKER_HOST", expectedHost)
// Reset cache for test
ResetDockerHostCache()
log := logrus.NewEntry(logrus.New())
host, _, err := DetectDockerHost(log)
assert.NoError(t, err)
assert.Equal(t, expectedHost, host)
}
func TestDetectDockerHost_Caching(t *testing.T) {
// Save env var
oldDockerHost := os.Getenv("DOCKER_HOST")
defer os.Setenv("DOCKER_HOST", oldDockerHost)
os.Setenv("DOCKER_HOST", "unix:///tmp/first.sock")
// Reset cache for test
ResetDockerHostCache()
log := logrus.NewEntry(logrus.New())
host1, _, _ := DetectDockerHost(log)
// Change env var - should still return first one from cache
os.Setenv("DOCKER_HOST", "unix:///tmp/second.sock")
host2, _, _ := DetectDockerHost(log)
assert.Equal(t, host1, host2)
assert.Equal(t, "unix:///tmp/first.sock", host2)
}
func TestDetectDockerHost_Context_Invalid(t *testing.T) {
// Save env vars
oldDockerHost := os.Getenv("DOCKER_HOST")
oldDockerContext := os.Getenv("DOCKER_CONTEXT")
defer func() {
os.Setenv("DOCKER_HOST", oldDockerHost)
os.Setenv("DOCKER_CONTEXT", oldDockerContext)
}()
os.Setenv("DOCKER_HOST", "")
os.Setenv("DOCKER_CONTEXT", "nonexistent-context-12345")
// Reset cache for test
ResetDockerHostCache()
log := logrus.NewEntry(logrus.New())
_, _, err := DetectDockerHost(log)
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to use DOCKER_CONTEXT")
}
func TestGetHostFromContext(t *testing.T) {
// This test is tricky because it depends on the Docker CLI config.
// We'll skip it if we can't easily mock the config directory.
// But we can at least test the "default" case.
host, err := getHostFromContext()
if err == nil {
// If it succeeded, it should be empty or a valid host
assert.True(t, host == "" || host != "")
}
}
func TestValidateSocket_Failures(t *testing.T) {
ctx := context.Background()
// Test non-existent path
err := validateSocket(ctx, "unix:///tmp/nonexistent-12345.sock", false)
assert.Error(t, err)
// Test invalid schema
err = validateSocket(ctx, "invalid:///tmp/test.sock", false)
assert.Error(t, err)
}
func TestDetectPlatformCandidates_Unix(t *testing.T) {
// Mock validateSocketFunc to always fail
oldValidate := validateSocketFunc
defer func() { validateSocketFunc = oldValidate }()
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
return errors.New("mock failure")
}
// Mock environment to ensure no candidates are found
oldXdg := os.Getenv("XDG_RUNTIME_DIR")
oldHome := os.Getenv("HOME")
defer func() {
os.Setenv("XDG_RUNTIME_DIR", oldXdg)
os.Setenv("HOME", oldHome)
}()
os.Setenv("XDG_RUNTIME_DIR", "/tmp/nonexistent-xdg")
os.Setenv("HOME", "/tmp/nonexistent-home")
log := logrus.NewEntry(logrus.New())
_, _, err := detectPlatformCandidates(log)
assert.Error(t, err)
assert.Contains(t, err.Error(), ErrNoDockerSocket.Error())
}
func TestDetectPlatformCandidates_Unix_Success(t *testing.T) {
// Mock validateSocketFunc to succeed for a specific path
oldValidate := validateSocketFunc
oldStat := statFunc
defer func() {
validateSocketFunc = oldValidate
statFunc = oldStat
}()
expectedPath := "unix:///var/run/docker.sock"
statFunc = func(name string) (os.FileInfo, error) {
if name == "/var/run/docker.sock" {
return nil, nil // Mock success
}
return nil, os.ErrNotExist
}
validateSocketFunc = func(ctx context.Context, host string, useEnv bool) error {
if host == expectedPath {
return nil
}
return errors.New("mock failure")
}
log := logrus.NewEntry(logrus.New())
host, runtime, err := detectPlatformCandidates(log)
assert.NoError(t, err)
assert.Equal(t, expectedPath, host)
assert.Equal(t, RuntimeDocker, runtime)
}