v3.3.2 9697f9d

runtime_devices_test.go RawHistoryFolder

1package docker
2
3import (
4	"context"
5	"errors"
6	"fmt"
7	"testing"
8
9	"github.com/moby/moby/api/types/container"
10	"github.com/moby/moby/api/types/system"
11	"github.com/moby/moby/client"
12	"github.com/stretchr/testify/assert"
13	"github.com/stretchr/testify/require"
14
15	"github.com/bnema/gordon/internal/domain"
16)
17
18func podmanVersion(version string) client.ServerVersionResult {
19	return client.ServerVersionResult{
20		Version:    version,
21		Components: []system.ComponentVersion{{Name: "Podman Engine", Version: version}},
22	}
23}
24
25func dockerVersion(version string) client.ServerVersionResult {
26	return client.ServerVersionResult{
27		Version:    version,
28		Components: []system.ComponentVersion{{Name: "Engine", Version: version}},
29	}
30}
31
32func TestBuildDeviceRequests_EmptyIsNil(t *testing.T) {
33	assert.Nil(t, buildDeviceRequests(&domain.ContainerConfig{}))
34	assert.Nil(t, buildDeviceRequests(&domain.ContainerConfig{CDIDevices: nil}))
35}
36
37func TestBuildDeviceRequests_OneNativeCDIRequest(t *testing.T) {
38	requests := buildDeviceRequests(&domain.ContainerConfig{
39		CDIDevices: []string{"example.com/gpu=GPU-b", "example.com/gpu=GPU-a"},
40	})
41	require.Len(t, requests, 1, "all CDI IDs travel in one native DeviceRequest")
42	request := requests[0]
43	assert.Equal(t, container.DeviceRequest{
44		Driver:    "cdi",
45		DeviceIDs: []string{"example.com/gpu=GPU-a", "example.com/gpu=GPU-b"},
46	}, request, "driver is cdi, capabilities/options stay empty, count stays 0, IDs sorted")
47}
48
49func TestBuildDeviceRequests_DoesNotMutateConfig(t *testing.T) {
50	config := &domain.ContainerConfig{CDIDevices: []string{"example.com/gpu=GPU-b", "example.com/gpu=GPU-a"}}
51	_ = buildDeviceRequests(config)
52	assert.Equal(t, []string{"example.com/gpu=GPU-b", "example.com/gpu=GPU-a"}, config.CDIDevices)
53}
54
55func TestCheckCDISupportMatrix(t *testing.T) {
56	cases := []struct {
57		name      string
58		version   client.ServerVersionResult
59		hint      string
60		wantError bool
61	}{
62		{"podman 6.1.1", podmanVersion("6.1.1"), "", false},
63		{"podman 5.4 exact", podmanVersion("5.4.0"), "", false},
64		{"podman 4.9 refused", podmanVersion("4.9.5"), "", true},
65		{"docker 28.3", dockerVersion("28.3.2"), "", false},
66		{"docker 27 refused", dockerVersion("27.5.1"), "", true},
67		{"unknown engine refused", client.ServerVersionResult{Version: "9.9.9"}, "unknown", true},
68		{"socket hint podman accepted", client.ServerVersionResult{Version: "6.1.1"}, "podman", false},
69		{"unparsable version refused", podmanVersion("not-a-version"), "", true},
70		{"prerelease minor refused", podmanVersion("5.4-rc1"), "", true},
71	}
72	for _, tc := range cases {
73		t.Run(tc.name, func(t *testing.T) {
74			err := checkCDISupport(tc.version, tc.hint)
75			if tc.wantError {
76				require.Error(t, err)
77				assert.ErrorIs(t, err, domain.ErrRuntimeUnsupported)
78			} else {
79				require.NoError(t, err)
80			}
81		})
82	}
83}
84
85func TestCompareEngineVersion(t *testing.T) {
86	assert.Greater(t, compareEngineVersion("6.1.1", "5.4"), 0)
87	assert.Less(t, compareEngineVersion("4.9.5", "5.4"), 0)
88	assert.Equal(t, 0, compareEngineVersion("5.4.0", "5.4"))
89	assert.Less(t, compareEngineVersion("not-a-version", "5.4"), 0)
90	assert.Equal(t, 0, compareEngineVersion("28.3.2", "28.3"), "patch releases do not affect the gate")
91
92	// A prerelease suffix must never lift an engine above the gate: the
93	// minor component has to be numeric on its own.
94	assert.Less(t, compareEngineVersion("5.4-rc1", "5.4"), 0)
95	assert.Less(t, compareEngineVersion("28.3-rc1", "28.3"), 0)
96	assert.Less(t, compareEngineVersion("5.", "5.4"), 0)
97}
98
99// TestEngineProbeError proves a failed /version probe keeps cancellation
100// recognizable while every other cause collapses to the unsupported
101// sentinel without the daemon endpoint in the text.
102func TestEngineProbeError(t *testing.T) {
103	t.Run("canceled probe keeps the sentinel and drops the endpoint", func(t *testing.T) {
104		ctx, cancel := context.WithCancel(context.Background())
105		cancel()
106
107		err := engineProbeError(ctx, errors.New("dial unix /run/podman/podman.sock: i/o timeout"))
108		require.ErrorIs(t, err, context.Canceled)
109		require.ErrorIs(t, err, domain.ErrRuntimeUnsupported)
110		assert.NotContains(t, err.Error(), "podman.sock")
111	})
112
113	t.Run("canceled adapter cause is preserved", func(t *testing.T) {
114		err := engineProbeError(context.Background(), fmt.Errorf("probe: %w", context.Canceled))
115		require.ErrorIs(t, err, context.Canceled)
116	})
117
118	t.Run("other probe failures stay redacted", func(t *testing.T) {
119		err := engineProbeError(context.Background(), errors.New("dial unix /run/podman/podman.sock: connection refused"))
120		require.ErrorIs(t, err, domain.ErrRuntimeUnsupported)
121		assert.False(t, errors.Is(err, context.Canceled))
122		assert.NotContains(t, err.Error(), "podman.sock")
123	})
124}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close