lazydocker/pkg/commands/docker_test.go
2026-06-04 08:40:21 +05:30

108 lines
3.8 KiB
Go

package commands
import (
"os"
"os/exec"
"testing"
"github.com/docker/docker/client"
"github.com/jesseduffield/lazydocker/pkg/config"
"github.com/stretchr/testify/assert"
)
// TestNewDockerClientVersionNegotiation verifies that newDockerClient allows
// API version negotiation even when DOCKER_API_VERSION is set.
//
// This is a regression test for https://github.com/jesseduffield/lazydocker/issues/715
// where users got "client version 1.25 is too old" errors because FromEnv()
// includes WithVersionFromEnv() which sets manualOverride=true, preventing
// API version negotiation.
func TestNewDockerClientVersionNegotiation(t *testing.T) {
// Save original env var and restore after test
originalAPIVersion := os.Getenv("DOCKER_API_VERSION")
defer func() {
if originalAPIVersion == "" {
os.Unsetenv("DOCKER_API_VERSION")
} else {
os.Setenv("DOCKER_API_VERSION", originalAPIVersion)
}
}()
// Set DOCKER_API_VERSION to an old version that would cause
// "client version 1.25 is too old" errors if negotiation is disabled
os.Setenv("DOCKER_API_VERSION", "1.25")
t.Run("FromEnv locks version preventing negotiation", func(t *testing.T) {
// This demonstrates the problematic behavior we're avoiding.
// When using FromEnv with DOCKER_API_VERSION set, the client
// version gets locked to 1.25 and negotiation is disabled.
cli, err := client.NewClientWithOpts(
client.FromEnv,
client.WithAPIVersionNegotiation(),
)
assert.NoError(t, err)
defer cli.Close()
// Version is locked to the env var value
assert.Equal(t, "1.25", cli.ClientVersion())
})
t.Run("newDockerClient allows version negotiation", func(t *testing.T) {
// Test the actual production function.
// Use DefaultDockerHost for cross-platform compatibility
// (unix socket on Linux/macOS, named pipe on Windows).
cli, err := newDockerClient(client.DefaultDockerHost)
assert.NoError(t, err)
defer cli.Close()
// Version is NOT locked to the env var value (1.25).
// Instead, it uses the library's default version and will negotiate
// with the server on first request. This is the key difference that
// fixes the "version too old" error.
assert.NotEqual(t, "1.25", cli.ClientVersion(),
"client version should not be locked to DOCKER_API_VERSION env var")
})
}
// TestIsProjectScoped covers the predicate that drives whether the
// project/services panels appear and whether the containers panel filters by
// project. The "outside compose dir + -p" case is the regression we fixed
// after PR #776 silently disabled it.
func TestIsProjectScoped(t *testing.T) {
cases := []struct {
name string
inDockerComposeProject bool
projectName string
want bool
}{
{"inside compose dir, no -p", true, "", true},
{"inside compose dir, with -p", true, "myproject", true},
{"outside compose dir, no -p", false, "", false},
{"outside compose dir, with -p", false, "myproject", true},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
c := &DockerCommand{
InDockerComposeProject: tc.inDockerComposeProject,
Config: &config.AppConfig{ProjectName: tc.projectName},
}
assert.Equal(t, tc.want, c.IsProjectScoped())
})
}
}
func TestSetDockerComposeCommandKeepsDefaultForRemoteDockerHost(t *testing.T) {
t.Setenv(dockerHostEnvKey, "ssh://example.com")
userConfig := config.GetDefaultConfig()
appConfig := &config.AppConfig{UserConfig: &userConfig}
osCommand := NewOSCommand(NewDummyLog(), appConfig)
osCommand.SetCommand(func(string, ...string) *exec.Cmd {
return exec.Command("sh", "-c", "exit 1")
})
dockerCommand := &DockerCommand{OSCommand: osCommand}
dockerCommand.setDockerComposeCommand(appConfig)
assert.Equal(t, "docker compose", appConfig.UserConfig.CommandTemplates.DockerCompose)
}