github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/reload_test.go (about) 1 // +build !solaris 2 3 package daemon 4 5 import ( 6 "reflect" 7 "sort" 8 "testing" 9 "time" 10 11 "github.com/docker/docker/daemon/config" 12 "github.com/docker/docker/pkg/discovery" 13 _ "github.com/docker/docker/pkg/discovery/memory" 14 "github.com/docker/docker/registry" 15 ) 16 17 func TestDaemonReloadLabels(t *testing.T) { 18 daemon := &Daemon{} 19 daemon.configStore = &config.Config{ 20 CommonConfig: config.CommonConfig{ 21 Labels: []string{"foo:bar"}, 22 }, 23 } 24 25 valuesSets := make(map[string]interface{}) 26 valuesSets["labels"] = "foo:baz" 27 newConfig := &config.Config{ 28 CommonConfig: config.CommonConfig{ 29 Labels: []string{"foo:baz"}, 30 ValuesSet: valuesSets, 31 }, 32 } 33 34 if err := daemon.Reload(newConfig); err != nil { 35 t.Fatal(err) 36 } 37 38 label := daemon.configStore.Labels[0] 39 if label != "foo:baz" { 40 t.Fatalf("Expected daemon label `foo:baz`, got %s", label) 41 } 42 } 43 44 func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) { 45 daemon := &Daemon{ 46 configStore: &config.Config{}, 47 } 48 49 // Initialize daemon with some registries. 50 daemon.RegistryService = registry.NewService(registry.ServiceOptions{ 51 AllowNondistributableArtifacts: []string{ 52 "127.0.0.0/8", 53 "10.10.1.11:5000", 54 "10.10.1.22:5000", // This will be removed during reload. 55 "docker1.com", 56 "docker2.com", // This will be removed during reload. 57 }, 58 }) 59 60 registries := []string{ 61 "127.0.0.0/8", 62 "10.10.1.11:5000", 63 "10.10.1.33:5000", // This will be added during reload. 64 "docker1.com", 65 "docker3.com", // This will be added during reload. 66 } 67 68 newConfig := &config.Config{ 69 CommonConfig: config.CommonConfig{ 70 ServiceOptions: registry.ServiceOptions{ 71 AllowNondistributableArtifacts: registries, 72 }, 73 ValuesSet: map[string]interface{}{ 74 "allow-nondistributable-artifacts": registries, 75 }, 76 }, 77 } 78 79 if err := daemon.Reload(newConfig); err != nil { 80 t.Fatal(err) 81 } 82 83 actual := []string{} 84 serviceConfig := daemon.RegistryService.ServiceConfig() 85 for _, value := range serviceConfig.AllowNondistributableArtifactsCIDRs { 86 actual = append(actual, value.String()) 87 } 88 for _, value := range serviceConfig.AllowNondistributableArtifactsHostnames { 89 actual = append(actual, value) 90 } 91 92 sort.Strings(registries) 93 sort.Strings(actual) 94 if !reflect.DeepEqual(registries, actual) { 95 t.Fatalf("expected %v, got %v\n", registries, actual) 96 } 97 } 98 99 func TestDaemonReloadMirrors(t *testing.T) { 100 daemon := &Daemon{} 101 daemon.RegistryService = registry.NewService(registry.ServiceOptions{ 102 InsecureRegistries: []string{}, 103 Mirrors: []string{ 104 "https://mirror.test1.com", 105 "https://mirror.test2.com", // this will be removed when reloading 106 "https://mirror.test3.com", // this will be removed when reloading 107 }, 108 }) 109 110 daemon.configStore = &config.Config{} 111 112 type pair struct { 113 valid bool 114 mirrors []string 115 after []string 116 } 117 118 loadMirrors := []pair{ 119 { 120 valid: false, 121 mirrors: []string{"10.10.1.11:5000"}, // this mirror is invalid 122 after: []string{}, 123 }, 124 { 125 valid: false, 126 mirrors: []string{"mirror.test1.com"}, // this mirror is invalid 127 after: []string{}, 128 }, 129 { 130 valid: false, 131 mirrors: []string{"10.10.1.11:5000", "mirror.test1.com"}, // mirrors are invalid 132 after: []string{}, 133 }, 134 { 135 valid: true, 136 mirrors: []string{"https://mirror.test1.com", "https://mirror.test4.com"}, 137 after: []string{"https://mirror.test1.com/", "https://mirror.test4.com/"}, 138 }, 139 } 140 141 for _, value := range loadMirrors { 142 valuesSets := make(map[string]interface{}) 143 valuesSets["registry-mirrors"] = value.mirrors 144 145 newConfig := &config.Config{ 146 CommonConfig: config.CommonConfig{ 147 ServiceOptions: registry.ServiceOptions{ 148 Mirrors: value.mirrors, 149 }, 150 ValuesSet: valuesSets, 151 }, 152 } 153 154 err := daemon.Reload(newConfig) 155 if !value.valid && err == nil { 156 // mirrors should be invalid, should be a non-nil error 157 t.Fatalf("Expected daemon reload error with invalid mirrors: %s, while get nil", value.mirrors) 158 } 159 160 if value.valid { 161 if err != nil { 162 // mirrors should be valid, should be no error 163 t.Fatal(err) 164 } 165 registryService := daemon.RegistryService.ServiceConfig() 166 167 if len(registryService.Mirrors) != len(value.after) { 168 t.Fatalf("Expected %d daemon mirrors %s while get %d with %s", 169 len(value.after), 170 value.after, 171 len(registryService.Mirrors), 172 registryService.Mirrors) 173 } 174 175 dataMap := map[string]struct{}{} 176 177 for _, mirror := range registryService.Mirrors { 178 if _, exist := dataMap[mirror]; !exist { 179 dataMap[mirror] = struct{}{} 180 } 181 } 182 183 for _, address := range value.after { 184 if _, exist := dataMap[address]; !exist { 185 t.Fatalf("Expected %s in daemon mirrors, while get none", address) 186 } 187 } 188 } 189 } 190 } 191 192 func TestDaemonReloadInsecureRegistries(t *testing.T) { 193 daemon := &Daemon{} 194 // initialize daemon with existing insecure registries: "127.0.0.0/8", "10.10.1.11:5000", "10.10.1.22:5000" 195 daemon.RegistryService = registry.NewService(registry.ServiceOptions{ 196 InsecureRegistries: []string{ 197 "127.0.0.0/8", 198 "10.10.1.11:5000", 199 "10.10.1.22:5000", // this will be removed when reloading 200 "docker1.com", 201 "docker2.com", // this will be removed when reloading 202 }, 203 }) 204 205 daemon.configStore = &config.Config{} 206 207 insecureRegistries := []string{ 208 "127.0.0.0/8", // this will be kept 209 "10.10.1.11:5000", // this will be kept 210 "10.10.1.33:5000", // this will be newly added 211 "docker1.com", // this will be kept 212 "docker3.com", // this will be newly added 213 } 214 215 valuesSets := make(map[string]interface{}) 216 valuesSets["insecure-registries"] = insecureRegistries 217 218 newConfig := &config.Config{ 219 CommonConfig: config.CommonConfig{ 220 ServiceOptions: registry.ServiceOptions{ 221 InsecureRegistries: insecureRegistries, 222 }, 223 ValuesSet: valuesSets, 224 }, 225 } 226 227 if err := daemon.Reload(newConfig); err != nil { 228 t.Fatal(err) 229 } 230 231 // After Reload, daemon.RegistryService will be changed which is useful 232 // for registry communication in daemon. 233 registries := daemon.RegistryService.ServiceConfig() 234 235 // After Reload(), newConfig has come to registries.InsecureRegistryCIDRs and registries.IndexConfigs in daemon. 236 // Then collect registries.InsecureRegistryCIDRs in dataMap. 237 // When collecting, we need to convert CIDRS into string as a key, 238 // while the times of key appears as value. 239 dataMap := map[string]int{} 240 for _, value := range registries.InsecureRegistryCIDRs { 241 if _, ok := dataMap[value.String()]; !ok { 242 dataMap[value.String()] = 1 243 } else { 244 dataMap[value.String()]++ 245 } 246 } 247 248 for _, value := range registries.IndexConfigs { 249 if _, ok := dataMap[value.Name]; !ok { 250 dataMap[value.Name] = 1 251 } else { 252 dataMap[value.Name]++ 253 } 254 } 255 256 // Finally compare dataMap with the original insecureRegistries. 257 // Each value in insecureRegistries should appear in daemon's insecure registries, 258 // and each can only appear exactly ONCE. 259 for _, r := range insecureRegistries { 260 if value, ok := dataMap[r]; !ok { 261 t.Fatalf("Expected daemon insecure registry %s, got none", r) 262 } else if value != 1 { 263 t.Fatalf("Expected only 1 daemon insecure registry %s, got %d", r, value) 264 } 265 } 266 267 // assert if "10.10.1.22:5000" is removed when reloading 268 if value, ok := dataMap["10.10.1.22:5000"]; ok { 269 t.Fatalf("Expected no insecure registry of 10.10.1.22:5000, got %d", value) 270 } 271 272 // assert if "docker2.com" is removed when reloading 273 if value, ok := dataMap["docker2.com"]; ok { 274 t.Fatalf("Expected no insecure registry of docker2.com, got %d", value) 275 } 276 } 277 278 func TestDaemonReloadNotAffectOthers(t *testing.T) { 279 daemon := &Daemon{} 280 daemon.configStore = &config.Config{ 281 CommonConfig: config.CommonConfig{ 282 Labels: []string{"foo:bar"}, 283 Debug: true, 284 }, 285 } 286 287 valuesSets := make(map[string]interface{}) 288 valuesSets["labels"] = "foo:baz" 289 newConfig := &config.Config{ 290 CommonConfig: config.CommonConfig{ 291 Labels: []string{"foo:baz"}, 292 ValuesSet: valuesSets, 293 }, 294 } 295 296 if err := daemon.Reload(newConfig); err != nil { 297 t.Fatal(err) 298 } 299 300 label := daemon.configStore.Labels[0] 301 if label != "foo:baz" { 302 t.Fatalf("Expected daemon label `foo:baz`, got %s", label) 303 } 304 debug := daemon.configStore.Debug 305 if !debug { 306 t.Fatal("Expected debug 'enabled', got 'disabled'") 307 } 308 } 309 310 func TestDaemonDiscoveryReload(t *testing.T) { 311 daemon := &Daemon{} 312 daemon.configStore = &config.Config{ 313 CommonConfig: config.CommonConfig{ 314 ClusterStore: "memory://127.0.0.1", 315 ClusterAdvertise: "127.0.0.1:3333", 316 }, 317 } 318 319 if err := daemon.initDiscovery(daemon.configStore); err != nil { 320 t.Fatal(err) 321 } 322 323 expected := discovery.Entries{ 324 &discovery.Entry{Host: "127.0.0.1", Port: "3333"}, 325 } 326 327 select { 328 case <-time.After(10 * time.Second): 329 t.Fatal("timeout waiting for discovery") 330 case <-daemon.discoveryWatcher.ReadyCh(): 331 } 332 333 stopCh := make(chan struct{}) 334 defer close(stopCh) 335 ch, errCh := daemon.discoveryWatcher.Watch(stopCh) 336 337 select { 338 case <-time.After(1 * time.Second): 339 t.Fatal("failed to get discovery advertisements in time") 340 case e := <-ch: 341 if !reflect.DeepEqual(e, expected) { 342 t.Fatalf("expected %v, got %v\n", expected, e) 343 } 344 case e := <-errCh: 345 t.Fatal(e) 346 } 347 348 valuesSets := make(map[string]interface{}) 349 valuesSets["cluster-store"] = "memory://127.0.0.1:2222" 350 valuesSets["cluster-advertise"] = "127.0.0.1:5555" 351 newConfig := &config.Config{ 352 CommonConfig: config.CommonConfig{ 353 ClusterStore: "memory://127.0.0.1:2222", 354 ClusterAdvertise: "127.0.0.1:5555", 355 ValuesSet: valuesSets, 356 }, 357 } 358 359 expected = discovery.Entries{ 360 &discovery.Entry{Host: "127.0.0.1", Port: "5555"}, 361 } 362 363 if err := daemon.Reload(newConfig); err != nil { 364 t.Fatal(err) 365 } 366 367 select { 368 case <-time.After(10 * time.Second): 369 t.Fatal("timeout waiting for discovery") 370 case <-daemon.discoveryWatcher.ReadyCh(): 371 } 372 373 ch, errCh = daemon.discoveryWatcher.Watch(stopCh) 374 375 select { 376 case <-time.After(1 * time.Second): 377 t.Fatal("failed to get discovery advertisements in time") 378 case e := <-ch: 379 if !reflect.DeepEqual(e, expected) { 380 t.Fatalf("expected %v, got %v\n", expected, e) 381 } 382 case e := <-errCh: 383 t.Fatal(e) 384 } 385 } 386 387 func TestDaemonDiscoveryReloadFromEmptyDiscovery(t *testing.T) { 388 daemon := &Daemon{} 389 daemon.configStore = &config.Config{} 390 391 valuesSet := make(map[string]interface{}) 392 valuesSet["cluster-store"] = "memory://127.0.0.1:2222" 393 valuesSet["cluster-advertise"] = "127.0.0.1:5555" 394 newConfig := &config.Config{ 395 CommonConfig: config.CommonConfig{ 396 ClusterStore: "memory://127.0.0.1:2222", 397 ClusterAdvertise: "127.0.0.1:5555", 398 ValuesSet: valuesSet, 399 }, 400 } 401 402 expected := discovery.Entries{ 403 &discovery.Entry{Host: "127.0.0.1", Port: "5555"}, 404 } 405 406 if err := daemon.Reload(newConfig); err != nil { 407 t.Fatal(err) 408 } 409 410 select { 411 case <-time.After(10 * time.Second): 412 t.Fatal("timeout waiting for discovery") 413 case <-daemon.discoveryWatcher.ReadyCh(): 414 } 415 416 stopCh := make(chan struct{}) 417 defer close(stopCh) 418 ch, errCh := daemon.discoveryWatcher.Watch(stopCh) 419 420 select { 421 case <-time.After(1 * time.Second): 422 t.Fatal("failed to get discovery advertisements in time") 423 case e := <-ch: 424 if !reflect.DeepEqual(e, expected) { 425 t.Fatalf("expected %v, got %v\n", expected, e) 426 } 427 case e := <-errCh: 428 t.Fatal(e) 429 } 430 } 431 432 func TestDaemonDiscoveryReloadOnlyClusterAdvertise(t *testing.T) { 433 daemon := &Daemon{} 434 daemon.configStore = &config.Config{ 435 CommonConfig: config.CommonConfig{ 436 ClusterStore: "memory://127.0.0.1", 437 }, 438 } 439 valuesSets := make(map[string]interface{}) 440 valuesSets["cluster-advertise"] = "127.0.0.1:5555" 441 newConfig := &config.Config{ 442 CommonConfig: config.CommonConfig{ 443 ClusterAdvertise: "127.0.0.1:5555", 444 ValuesSet: valuesSets, 445 }, 446 } 447 expected := discovery.Entries{ 448 &discovery.Entry{Host: "127.0.0.1", Port: "5555"}, 449 } 450 451 if err := daemon.Reload(newConfig); err != nil { 452 t.Fatal(err) 453 } 454 455 select { 456 case <-daemon.discoveryWatcher.ReadyCh(): 457 case <-time.After(10 * time.Second): 458 t.Fatal("Timeout waiting for discovery") 459 } 460 stopCh := make(chan struct{}) 461 defer close(stopCh) 462 ch, errCh := daemon.discoveryWatcher.Watch(stopCh) 463 464 select { 465 case <-time.After(1 * time.Second): 466 t.Fatal("failed to get discovery advertisements in time") 467 case e := <-ch: 468 if !reflect.DeepEqual(e, expected) { 469 t.Fatalf("expected %v, got %v\n", expected, e) 470 } 471 case e := <-errCh: 472 t.Fatal(e) 473 } 474 }