main 33a243c

engine_test.go RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3package container
4
5import (
6	"net/http"
7	"net/http/httptest"
8	"testing"
9
10	"github.com/moby/moby/client"
11)
12
13// infoDaemon plays the two endpoints Info reads. versionBody "" makes /version
14// fail with a 500.
15func infoDaemon(t *testing.T, versionBody string) *dockerEngine {
16	t.Helper()
17	mux := http.NewServeMux()
18	mux.HandleFunc("/info", func(w http.ResponseWriter, _ *http.Request) {
19		w.Header().Set("Content-Type", "application/json")
20		_, _ = w.Write([]byte(`{"OSType":"linux","SecurityOptions":["name=seccomp,profile=builtin"],"Runtimes":{"runc":{"path":"runc"}}}`))
21	})
22	mux.HandleFunc("/version", func(w http.ResponseWriter, _ *http.Request) {
23		if versionBody == "" {
24			http.Error(w, `{"message":"boom"}`, http.StatusInternalServerError)
25			return
26		}
27		w.Header().Set("Content-Type", "application/json")
28		_, _ = w.Write([]byte(versionBody))
29	})
30	srv := httptest.NewServer(http.StripPrefix("/v1.43", mux))
31	t.Cleanup(srv.Close)
32	cli, err := client.New(client.WithHost("tcp://"+srv.Listener.Addr().String()), client.WithAPIVersion("1.43"))
33	if err != nil {
34		t.Fatal(err)
35	}
36	t.Cleanup(func() { _ = cli.Close() })
37	return &dockerEngine{cli: cli}
38}
39
40// GO-004: the Podman flag comes from the version components' names; a daemon
41// whose /version fails (or names no Podman) is treated as Docker.
42func TestInfoDetectsPodman(t *testing.T) {
43	for name, tc := range map[string]struct {
44		version string
45		podman  bool
46	}{
47		"podman":         {`{"Version":"6.1.3","Components":[{"Name":"Podman Engine","Version":"6.1.3"},{"Name":"Conmon","Version":"2.2.1"}]}`, true},
48		"podman later":   {`{"Components":[{"Name":"Conmon","Version":"2"},{"Name":"Podman Engine","Version":"6"}]}`, true},
49		"docker":         {`{"Version":"29.9.0","Components":[{"Name":"Engine","Version":"29.9.0"},{"Name":"containerd","Version":"2"}]}`, false},
50		"no components":  {`{"Version":"29.9.0"}`, false},
51		"lower case":     {`{"Components":[{"Name":"podman engine","Version":"1"}]}`, false}, // the name is "Podman Engine": exact prefix
52		"version fails":  {"", false},
53		"malformed json": {`{not json`, false},
54	} {
55		t.Run(name, func(t *testing.T) {
56			di, err := infoDaemon(t, tc.version).Info(t.Context())
57			if err != nil {
58				t.Fatalf("a /version failure must not fail Info: %v", err)
59			}
60			if di.Podman != tc.podman {
61				t.Fatalf("Podman=%v want %v", di.Podman, tc.podman)
62			}
63			if di.OSType != "linux" || len(di.Runtimes) != 1 || di.Rootless {
64				t.Fatalf("the rest of Info is unchanged: %+v", di)
65			}
66		})
67	}
68}
69
70func TestIsPodman(t *testing.T) {
71	if isPodman(nil) {
72		t.Fatal("no components is not podman")
73	}
74}

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 4

Tags 11

↑↓ moveenter openesc close