gui/pkg/container/tim_test.go
Snider 74d429f471
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
Add missing GUI unit coverage
2026-04-15 22:59:42 +01:00

299 lines
7.8 KiB
Go

package container
import (
"context"
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestTIMManager_NewTIMManager_Good(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Detect: func() ContainerRuntime {
return RuntimeDocker
},
})
state := manager.State()
assert.Equal(t, "coregui-tim", state.Name)
assert.Equal(t, "ghcr.io/lthn/core/tim:latest", state.Image)
assert.Equal(t, RuntimeDocker, state.Runtime)
assert.Equal(t, "stopped", state.Status)
assert.Empty(t, state.StartedAt)
}
func TestTIMManager_NewTIMManager_Bad(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Name: " ",
Image: " ",
Detect: func() ContainerRuntime {
return RuntimeNone
},
})
state := manager.State()
assert.Equal(t, "coregui-tim", state.Name)
assert.Equal(t, "ghcr.io/lthn/core/tim:latest", state.Image)
assert.Equal(t, RuntimeNone, state.Runtime)
assert.Equal(t, "stopped", state.Status)
}
func TestTIMManager_NewTIMManager_Ugly(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Name: "worker-node",
Image: "ghcr.io/example/tim:edge",
Command: []string{"alpha", "beta"},
DataDir: "/var/lib/tim",
Runtime: RuntimePodman,
Resources: TIMResources{CPUCores: 2, MemoryMB: 512, GPU: "all"},
Detect: func() ContainerRuntime {
return RuntimeDocker
},
})
state := manager.State()
assert.Equal(t, "worker-node", state.Name)
assert.Equal(t, "ghcr.io/example/tim:edge", state.Image)
assert.Equal(t, RuntimePodman, state.Runtime)
assert.Equal(t, []string{"alpha", "beta"}, state.Command)
assert.Equal(t, "/var/lib/tim", state.DataDir)
assert.Equal(t, TIMResources{CPUCores: 2, MemoryMB: 512, GPU: "all"}, state.Resources)
}
func TestTIMManager_Start_Good(t *testing.T) {
var calls []string
manager := NewTIMManager(TIMOptions{
Name: "coregui-tim",
Image: "ghcr.io/example/tim:latest",
Command: []string{"sleep", "1"},
Detect: func() ContainerRuntime {
return RuntimeDocker
},
Exec: func(_ context.Context, name string, args ...string) error {
calls = append(calls, append([]string{name}, args...)...)
return nil
},
Now: func() time.Time {
return time.Unix(456, 0).UTC()
},
})
state, err := manager.Start(context.Background())
require.NoError(t, err)
assert.Equal(t, "running", state.Status)
assert.Equal(t, time.Unix(456, 0).UTC(), state.StartedAt)
assert.Equal(t, "docker", calls[0])
assert.Contains(t, calls, "run")
assert.Contains(t, calls, "--rm")
assert.Contains(t, calls, "--name")
assert.Contains(t, calls, "coregui-tim")
assert.Contains(t, calls, "ghcr.io/example/tim:latest")
}
func TestTIMManager_Start_Bad(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Detect: func() ContainerRuntime {
return RuntimeNone
},
})
state, err := manager.Start(context.Background())
require.Error(t, err)
assert.Equal(t, RuntimeNone, state.Runtime)
assert.Equal(t, "stopped", state.Status)
assert.Contains(t, err.Error(), "no supported container runtime detected")
}
func TestTIMManager_Start_Ugly(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Detect: func() ContainerRuntime {
return RuntimeDocker
},
Exec: func(context.Context, string, ...string) error {
return errors.New("docker failed")
},
})
state, err := manager.Start(context.Background())
require.Error(t, err)
assert.Equal(t, "error", state.Status)
assert.Contains(t, err.Error(), "docker failed")
}
func TestTIMManager_Stop_Good(t *testing.T) {
var calls []string
manager := NewTIMManager(TIMOptions{
Detect: func() ContainerRuntime {
return RuntimeDocker
},
Exec: func(_ context.Context, name string, args ...string) error {
calls = append(calls, append([]string{name}, args...)...)
return nil
},
})
started, err := manager.Start(context.Background())
require.NoError(t, err)
assert.Equal(t, "running", started.Status)
stopped, err := manager.Stop(context.Background())
require.NoError(t, err)
assert.Equal(t, "stopped", stopped.Status)
require.GreaterOrEqual(t, len(calls), 3)
assert.Equal(t, "docker", calls[len(calls)-3])
assert.Equal(t, "stop", calls[len(calls)-2])
assert.Equal(t, "coregui-tim", calls[len(calls)-1])
}
func TestTIMManager_Stop_Bad(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Detect: func() ContainerRuntime {
return RuntimeDocker
},
Exec: func(context.Context, string, ...string) error {
return errors.New("stop failed")
},
})
_, err := manager.Start(context.Background())
require.Error(t, err)
state, err := manager.Stop(context.Background())
require.Error(t, err)
assert.Equal(t, "error", state.Status)
assert.Contains(t, err.Error(), "stop failed")
}
func TestTIMManager_Stop_Ugly(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Detect: func() ContainerRuntime {
return RuntimeNone
},
})
state, err := manager.Stop(context.Background())
require.NoError(t, err)
assert.Equal(t, "stopped", state.Status)
}
func TestTIMManager_runtimeCommand_Good(t *testing.T) {
cases := []struct {
name string
runtime ContainerRuntime
verb string
wantBin string
wantArgs []string
}{
{
name: "docker run",
runtime: RuntimeDocker,
verb: "run",
wantBin: "docker",
wantArgs: []string{"run", "-d", "--rm", "--name", "tim"},
},
{
name: "apple stop",
runtime: RuntimeApple,
verb: "stop",
wantBin: "container",
wantArgs: []string{"stop", "tim"},
},
{
name: "podman run",
runtime: RuntimePodman,
verb: "run",
wantBin: "podman",
wantArgs: []string{"run", "-d", "--replace", "--name", "tim"},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Name: "tim",
Image: "image",
Runtime: tc.runtime,
Detect: func() ContainerRuntime {
return RuntimeDocker
},
})
gotBin, gotArgs := manager.runtimeCommand(tc.runtime, tc.verb)
assert.Equal(t, tc.wantBin, gotBin)
assert.Equal(t, tc.wantArgs, gotArgs[:len(tc.wantArgs)])
if tc.verb == "run" {
assert.Contains(t, gotArgs, "image")
}
})
}
}
func TestTIMManager_runtimeCommand_Bad(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Name: "tim",
Image: "image",
Runtime: RuntimeNone,
Detect: func() ContainerRuntime {
return RuntimeDocker
},
})
bin, args := manager.runtimeCommand(RuntimeNone, "run")
assert.Equal(t, "docker", bin)
assert.Contains(t, args, "--rm")
}
func TestTIMManager_runtimeCommand_Ugly(t *testing.T) {
manager := NewTIMManager(TIMOptions{
Name: "tim",
Image: "image",
Resources: TIMResources{
CPUCores: 2,
MemoryMB: 512,
GPU: "all",
},
Detect: func() ContainerRuntime {
return RuntimeDocker
},
})
bin, args := manager.runtimeCommand(RuntimeDocker, "run")
require.Equal(t, "docker", bin)
assert.Contains(t, args, "--cpus")
assert.Contains(t, args, "2")
assert.Contains(t, args, "--memory")
assert.Contains(t, args, "512m")
assert.Contains(t, args, "--gpus")
assert.Contains(t, args, "all")
}
func TestTIMManager_resourceArgs_Good(t *testing.T) {
assert.Nil(t, resourceArgs(TIMResources{}))
}
func TestTIMManager_resourceArgs_Bad(t *testing.T) {
args := resourceArgs(TIMResources{CPUCores: 2})
assert.Equal(t, []string{"--cpus", "2"}, args)
}
func TestTIMManager_resourceArgs_Ugly(t *testing.T) {
args := resourceArgs(TIMResources{CPUCores: 2, MemoryMB: 512, GPU: "all"})
assert.Equal(t, []string{"--cpus", "2", "--memory", "512m", "--gpus", "all"}, args)
}
func TestTIMManager_coalesceRuntime_Good(t *testing.T) {
assert.Equal(t, RuntimeApple, coalesceRuntime(RuntimeApple, RuntimeDocker))
}
func TestTIMManager_coalesceRuntime_Bad(t *testing.T) {
assert.Equal(t, RuntimeDocker, coalesceRuntime(RuntimeNone, RuntimeDocker))
}
func TestTIMManager_coalesceRuntime_Ugly(t *testing.T) {
assert.Equal(t, RuntimeNone, coalesceRuntime(RuntimeNone, RuntimeNone))
}