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}