github.com/rish1988/moby@v25.0.2+incompatible/cmd/dockerd/daemon_test.go (about) 1 package main 2 3 import ( 4 "testing" 5 6 "github.com/containerd/log" 7 "github.com/docker/docker/daemon/config" 8 "github.com/google/go-cmp/cmp/cmpopts" 9 "github.com/spf13/pflag" 10 "gotest.tools/v3/assert" 11 is "gotest.tools/v3/assert/cmp" 12 "gotest.tools/v3/fs" 13 ) 14 15 func defaultOptions(t *testing.T, configFile string) *daemonOptions { 16 cfg, err := config.New() 17 assert.NilError(t, err) 18 opts := newDaemonOptions(cfg) 19 opts.flags = &pflag.FlagSet{} 20 opts.installFlags(opts.flags) 21 err = installConfigFlags(opts.daemonConfig, opts.flags) 22 assert.NilError(t, err) 23 defaultDaemonConfigFile, err := getDefaultDaemonConfigFile() 24 assert.NilError(t, err) 25 opts.flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "") 26 opts.configFile = configFile 27 err = opts.flags.Parse([]string{}) 28 assert.NilError(t, err) 29 return opts 30 } 31 32 func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) { 33 opts := defaultOptions(t, "") 34 opts.Debug = true 35 36 loadedConfig, err := loadDaemonCliConfig(opts) 37 assert.NilError(t, err) 38 assert.Assert(t, loadedConfig != nil) 39 if !loadedConfig.Debug { 40 t.Fatalf("expected debug to be copied from the common flags, got false") 41 } 42 } 43 44 func TestLoadDaemonCliConfigWithTLS(t *testing.T) { 45 opts := defaultOptions(t, "") 46 opts.TLSOptions.CAFile = "/tmp/ca.pem" 47 opts.TLS = true 48 49 loadedConfig, err := loadDaemonCliConfig(opts) 50 assert.NilError(t, err) 51 assert.Assert(t, loadedConfig != nil) 52 assert.Check(t, is.Equal("/tmp/ca.pem", loadedConfig.TLSOptions.CAFile)) 53 } 54 55 func TestLoadDaemonCliConfigWithConflicts(t *testing.T) { 56 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"labels": ["l3=foo"]}`)) 57 defer tempFile.Remove() 58 configFile := tempFile.Path() 59 60 opts := defaultOptions(t, configFile) 61 flags := opts.flags 62 63 assert.Check(t, flags.Set("config-file", configFile)) 64 assert.Check(t, flags.Set("label", "l1=bar")) 65 assert.Check(t, flags.Set("label", "l2=baz")) 66 67 _, err := loadDaemonCliConfig(opts) 68 assert.Check(t, is.ErrorContains(err, "as a flag and in the configuration file: labels")) 69 } 70 71 func TestLoadDaemonCliWithConflictingNodeGenericResources(t *testing.T) { 72 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"node-generic-resources": ["foo=bar", "bar=baz"]}`)) 73 defer tempFile.Remove() 74 configFile := tempFile.Path() 75 76 opts := defaultOptions(t, configFile) 77 flags := opts.flags 78 79 assert.Check(t, flags.Set("config-file", configFile)) 80 assert.Check(t, flags.Set("node-generic-resource", "r1=bar")) 81 assert.Check(t, flags.Set("node-generic-resource", "r2=baz")) 82 83 _, err := loadDaemonCliConfig(opts) 84 assert.Check(t, is.ErrorContains(err, "as a flag and in the configuration file: node-generic-resources")) 85 } 86 87 func TestLoadDaemonCliWithConflictingLabels(t *testing.T) { 88 opts := defaultOptions(t, "") 89 flags := opts.flags 90 91 assert.Check(t, flags.Set("label", "foo=bar")) 92 assert.Check(t, flags.Set("label", "foo=baz")) 93 94 _, err := loadDaemonCliConfig(opts) 95 assert.Check(t, is.Error(err, "conflict labels for foo=baz and foo=bar")) 96 } 97 98 func TestLoadDaemonCliWithDuplicateLabels(t *testing.T) { 99 opts := defaultOptions(t, "") 100 flags := opts.flags 101 102 assert.Check(t, flags.Set("label", "foo=the-same")) 103 assert.Check(t, flags.Set("label", "foo=the-same")) 104 105 _, err := loadDaemonCliConfig(opts) 106 assert.Check(t, err) 107 } 108 109 func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) { 110 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"tlsverify": true}`)) 111 defer tempFile.Remove() 112 113 opts := defaultOptions(t, tempFile.Path()) 114 opts.TLSOptions.CAFile = "/tmp/ca.pem" 115 116 loadedConfig, err := loadDaemonCliConfig(opts) 117 assert.NilError(t, err) 118 assert.Assert(t, loadedConfig != nil) 119 assert.Check(t, is.Equal(*loadedConfig.TLS, true)) 120 } 121 122 func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) { 123 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"tlsverify": false}`)) 124 defer tempFile.Remove() 125 126 opts := defaultOptions(t, tempFile.Path()) 127 opts.TLSOptions.CAFile = "/tmp/ca.pem" 128 129 loadedConfig, err := loadDaemonCliConfig(opts) 130 assert.NilError(t, err) 131 assert.Assert(t, loadedConfig != nil) 132 assert.Check(t, *loadedConfig.TLS) 133 } 134 135 func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) { 136 tempFile := fs.NewFile(t, "config", fs.WithContent(`{}`)) 137 defer tempFile.Remove() 138 139 opts := defaultOptions(t, tempFile.Path()) 140 opts.TLSOptions.CAFile = "/tmp/ca.pem" 141 142 loadedConfig, err := loadDaemonCliConfig(opts) 143 assert.NilError(t, err) 144 assert.Assert(t, loadedConfig != nil) 145 assert.Check(t, loadedConfig.TLS == nil) 146 } 147 148 func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) { 149 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"log-level": "warn"}`)) 150 defer tempFile.Remove() 151 152 opts := defaultOptions(t, tempFile.Path()) 153 loadedConfig, err := loadDaemonCliConfig(opts) 154 assert.NilError(t, err) 155 assert.Assert(t, loadedConfig != nil) 156 assert.Check(t, is.Equal("warn", loadedConfig.LogLevel)) 157 } 158 159 func TestLoadDaemonCliConfigWithLogFormat(t *testing.T) { 160 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"log-format": "json"}`)) 161 defer tempFile.Remove() 162 163 opts := defaultOptions(t, tempFile.Path()) 164 loadedConfig, err := loadDaemonCliConfig(opts) 165 assert.NilError(t, err) 166 assert.Assert(t, loadedConfig != nil) 167 assert.Check(t, is.Equal(log.JSONFormat, loadedConfig.LogFormat)) 168 } 169 170 func TestLoadDaemonCliConfigWithInvalidLogFormat(t *testing.T) { 171 tempFile := fs.NewFile(t, "config", fs.WithContent(`{"log-format": "foo"}`)) 172 defer tempFile.Remove() 173 174 opts := defaultOptions(t, tempFile.Path()) 175 _, err := loadDaemonCliConfig(opts) 176 assert.Check(t, is.ErrorContains(err, "invalid log format: foo")) 177 } 178 179 func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) { 180 content := `{"tlscacert": "/etc/certs/ca.pem", "log-driver": "syslog"}` 181 tempFile := fs.NewFile(t, "config", fs.WithContent(content)) 182 defer tempFile.Remove() 183 184 opts := defaultOptions(t, tempFile.Path()) 185 loadedConfig, err := loadDaemonCliConfig(opts) 186 assert.NilError(t, err) 187 assert.Assert(t, loadedConfig != nil) 188 assert.Check(t, is.Equal("/etc/certs/ca.pem", loadedConfig.TLSOptions.CAFile)) 189 assert.Check(t, is.Equal("syslog", loadedConfig.LogConfig.Type)) 190 } 191 192 func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) { 193 content := `{ 194 "allow-nondistributable-artifacts": ["allow-nondistributable-artifacts.example.com"], 195 "registry-mirrors": ["https://mirrors.example.com"], 196 "insecure-registries": ["https://insecure-registry.example.com"] 197 }` 198 tempFile := fs.NewFile(t, "config", fs.WithContent(content)) 199 defer tempFile.Remove() 200 201 opts := defaultOptions(t, tempFile.Path()) 202 loadedConfig, err := loadDaemonCliConfig(opts) 203 assert.NilError(t, err) 204 assert.Assert(t, loadedConfig != nil) 205 206 assert.Check(t, is.Len(loadedConfig.AllowNondistributableArtifacts, 1)) 207 assert.Check(t, is.Len(loadedConfig.Mirrors, 1)) 208 assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1)) 209 } 210 211 func TestConfigureDaemonLogs(t *testing.T) { 212 conf := &config.Config{} 213 configureDaemonLogs(conf) 214 assert.Check(t, is.Equal(log.InfoLevel, log.GetLevel())) 215 216 // log level should not be changed when passing an invalid value 217 conf.LogLevel = "foobar" 218 configureDaemonLogs(conf) 219 assert.Check(t, is.Equal(log.InfoLevel, log.GetLevel())) 220 221 conf.LogLevel = "warn" 222 configureDaemonLogs(conf) 223 assert.Check(t, is.Equal(log.WarnLevel, log.GetLevel())) 224 } 225 226 func TestCDISpecDirs(t *testing.T) { 227 testCases := []struct { 228 description string 229 configContent string 230 specDirs []string 231 expectedCDISpecDirs []string 232 }{ 233 { 234 description: "CDI enabled and no spec dirs specified returns default", 235 specDirs: nil, 236 configContent: `{"features": {"cdi": true}}`, 237 expectedCDISpecDirs: []string{"/etc/cdi", "/var/run/cdi"}, 238 }, 239 { 240 description: "CDI enabled and specified spec dirs are returned", 241 specDirs: []string{"/foo/bar", "/baz/qux"}, 242 configContent: `{"features": {"cdi": true}}`, 243 expectedCDISpecDirs: []string{"/foo/bar", "/baz/qux"}, 244 }, 245 { 246 description: "CDI enabled and empty string as spec dir returns empty slice", 247 specDirs: []string{""}, 248 configContent: `{"features": {"cdi": true}}`, 249 expectedCDISpecDirs: []string{}, 250 }, 251 { 252 description: "CDI enabled and empty config option returns empty slice", 253 configContent: `{"cdi-spec-dirs": [], "features": {"cdi": true}}`, 254 expectedCDISpecDirs: []string{}, 255 }, 256 { 257 description: "CDI disabled and no spec dirs specified returns no cdi spec dirs", 258 specDirs: nil, 259 expectedCDISpecDirs: nil, 260 }, 261 { 262 description: "CDI disabled and specified spec dirs returns no cdi spec dirs", 263 specDirs: []string{"/foo/bar", "/baz/qux"}, 264 expectedCDISpecDirs: nil, 265 }, 266 } 267 268 for _, tc := range testCases { 269 t.Run(tc.description, func(t *testing.T) { 270 tempFile := fs.NewFile(t, "config", fs.WithContent(tc.configContent)) 271 defer tempFile.Remove() 272 273 opts := defaultOptions(t, tempFile.Path()) 274 275 flags := opts.flags 276 for _, specDir := range tc.specDirs { 277 assert.Check(t, flags.Set("cdi-spec-dir", specDir)) 278 } 279 280 loadedConfig, err := loadDaemonCliConfig(opts) 281 assert.NilError(t, err) 282 283 assert.Check(t, is.DeepEqual(tc.expectedCDISpecDirs, loadedConfig.CDISpecDirs, cmpopts.EquateEmpty())) 284 }) 285 } 286 }