github.com/netdata/go.d.plugin@v0.58.1/modules/docker/docker_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package docker 4 5 import ( 6 "context" 7 "errors" 8 "testing" 9 10 "github.com/docker/docker/api/types" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestDocker_Init(t *testing.T) { 16 tests := map[string]struct { 17 config Config 18 wantFail bool 19 }{ 20 "default config": { 21 wantFail: false, 22 config: New().Config, 23 }, 24 "unset 'address'": { 25 wantFail: false, 26 config: Config{ 27 Address: "", 28 }, 29 }, 30 } 31 32 for name, test := range tests { 33 t.Run(name, func(t *testing.T) { 34 d := New() 35 d.Config = test.config 36 37 if test.wantFail { 38 assert.False(t, d.Init()) 39 } else { 40 assert.True(t, d.Init()) 41 } 42 }) 43 } 44 } 45 46 func TestDocker_Charts(t *testing.T) { 47 assert.Equal(t, len(summaryCharts), len(*New().Charts())) 48 } 49 50 func TestDocker_Cleanup(t *testing.T) { 51 tests := map[string]struct { 52 prepare func(d *Docker) 53 wantClose bool 54 }{ 55 "after New": { 56 wantClose: false, 57 prepare: func(d *Docker) {}, 58 }, 59 "after Init": { 60 wantClose: false, 61 prepare: func(d *Docker) { d.Init() }, 62 }, 63 "after Check": { 64 wantClose: true, 65 prepare: func(d *Docker) { d.Init(); d.Check() }, 66 }, 67 "after Collect": { 68 wantClose: true, 69 prepare: func(d *Docker) { d.Init(); d.Collect() }, 70 }, 71 } 72 73 for name, test := range tests { 74 t.Run(name, func(t *testing.T) { 75 m := &mockClient{} 76 d := New() 77 d.newClient = prepareNewClientFunc(m) 78 79 test.prepare(d) 80 81 require.NotPanics(t, d.Cleanup) 82 83 if test.wantClose { 84 assert.True(t, m.closeCalled) 85 } else { 86 assert.False(t, m.closeCalled) 87 } 88 }) 89 } 90 } 91 92 func TestDocker_Check(t *testing.T) { 93 tests := map[string]struct { 94 prepare func() *Docker 95 wantFail bool 96 }{ 97 "case success": { 98 wantFail: false, 99 prepare: func() *Docker { 100 return prepareCaseSuccess() 101 }, 102 }, 103 "case success without container size": { 104 wantFail: false, 105 prepare: func() *Docker { 106 return prepareCaseSuccessWithoutContainerSize() 107 }, 108 }, 109 "fail on case err on Info()": { 110 wantFail: true, 111 prepare: func() *Docker { 112 return prepareCaseErrOnInfo() 113 }, 114 }, 115 "fail on case err on ImageList()": { 116 wantFail: true, 117 prepare: func() *Docker { 118 return prepareCaseErrOnImageList() 119 }, 120 }, 121 "fail on case err on ContainerList()": { 122 wantFail: true, 123 prepare: func() *Docker { 124 return prepareCaseErrOnContainerList() 125 }, 126 }, 127 "fail on case err on creating Docker client": { 128 wantFail: true, 129 prepare: func() *Docker { 130 return prepareCaseErrCreatingClient() 131 }, 132 }, 133 } 134 135 for name, test := range tests { 136 t.Run(name, func(t *testing.T) { 137 d := test.prepare() 138 139 require.True(t, d.Init()) 140 141 if test.wantFail { 142 assert.False(t, d.Check()) 143 } else { 144 assert.True(t, d.Check()) 145 } 146 }) 147 } 148 } 149 150 func TestDocker_Collect(t *testing.T) { 151 tests := map[string]struct { 152 prepare func() *Docker 153 expected map[string]int64 154 }{ 155 "case success": { 156 prepare: func() *Docker { 157 return prepareCaseSuccess() 158 }, 159 expected: map[string]int64{ 160 "container_container10_health_status_healthy": 0, 161 "container_container10_health_status_none": 0, 162 "container_container10_health_status_not_running_unhealthy": 1, 163 "container_container10_health_status_starting": 0, 164 "container_container10_health_status_unhealthy": 0, 165 "container_container10_size_root_fs": 0, 166 "container_container10_size_rw": 0, 167 "container_container10_state_created": 0, 168 "container_container10_state_dead": 1, 169 "container_container10_state_exited": 0, 170 "container_container10_state_paused": 0, 171 "container_container10_state_removing": 0, 172 "container_container10_state_restarting": 0, 173 "container_container10_state_running": 0, 174 "container_container11_health_status_healthy": 0, 175 "container_container11_health_status_none": 0, 176 "container_container11_health_status_not_running_unhealthy": 0, 177 "container_container11_health_status_starting": 1, 178 "container_container11_health_status_unhealthy": 0, 179 "container_container11_size_root_fs": 0, 180 "container_container11_size_rw": 0, 181 "container_container11_state_created": 0, 182 "container_container11_state_dead": 0, 183 "container_container11_state_exited": 0, 184 "container_container11_state_paused": 0, 185 "container_container11_state_removing": 1, 186 "container_container11_state_restarting": 0, 187 "container_container11_state_running": 0, 188 "container_container12_health_status_healthy": 0, 189 "container_container12_health_status_none": 0, 190 "container_container12_health_status_not_running_unhealthy": 0, 191 "container_container12_health_status_starting": 1, 192 "container_container12_health_status_unhealthy": 0, 193 "container_container12_size_root_fs": 0, 194 "container_container12_size_rw": 0, 195 "container_container12_state_created": 0, 196 "container_container12_state_dead": 0, 197 "container_container12_state_exited": 1, 198 "container_container12_state_paused": 0, 199 "container_container12_state_removing": 0, 200 "container_container12_state_restarting": 0, 201 "container_container12_state_running": 0, 202 "container_container13_health_status_healthy": 0, 203 "container_container13_health_status_none": 0, 204 "container_container13_health_status_not_running_unhealthy": 0, 205 "container_container13_health_status_starting": 1, 206 "container_container13_health_status_unhealthy": 0, 207 "container_container13_size_root_fs": 0, 208 "container_container13_size_rw": 0, 209 "container_container13_state_created": 0, 210 "container_container13_state_dead": 0, 211 "container_container13_state_exited": 1, 212 "container_container13_state_paused": 0, 213 "container_container13_state_removing": 0, 214 "container_container13_state_restarting": 0, 215 "container_container13_state_running": 0, 216 "container_container14_health_status_healthy": 0, 217 "container_container14_health_status_none": 1, 218 "container_container14_health_status_not_running_unhealthy": 0, 219 "container_container14_health_status_starting": 0, 220 "container_container14_health_status_unhealthy": 0, 221 "container_container14_size_root_fs": 0, 222 "container_container14_size_rw": 0, 223 "container_container14_state_created": 0, 224 "container_container14_state_dead": 1, 225 "container_container14_state_exited": 0, 226 "container_container14_state_paused": 0, 227 "container_container14_state_removing": 0, 228 "container_container14_state_restarting": 0, 229 "container_container14_state_running": 0, 230 "container_container15_health_status_healthy": 0, 231 "container_container15_health_status_none": 1, 232 "container_container15_health_status_not_running_unhealthy": 0, 233 "container_container15_health_status_starting": 0, 234 "container_container15_health_status_unhealthy": 0, 235 "container_container15_size_root_fs": 0, 236 "container_container15_size_rw": 0, 237 "container_container15_state_created": 0, 238 "container_container15_state_dead": 1, 239 "container_container15_state_exited": 0, 240 "container_container15_state_paused": 0, 241 "container_container15_state_removing": 0, 242 "container_container15_state_restarting": 0, 243 "container_container15_state_running": 0, 244 "container_container16_health_status_healthy": 0, 245 "container_container16_health_status_none": 1, 246 "container_container16_health_status_not_running_unhealthy": 0, 247 "container_container16_health_status_starting": 0, 248 "container_container16_health_status_unhealthy": 0, 249 "container_container16_size_root_fs": 0, 250 "container_container16_size_rw": 0, 251 "container_container16_state_created": 0, 252 "container_container16_state_dead": 1, 253 "container_container16_state_exited": 0, 254 "container_container16_state_paused": 0, 255 "container_container16_state_removing": 0, 256 "container_container16_state_restarting": 0, 257 "container_container16_state_running": 0, 258 "container_container1_health_status_healthy": 1, 259 "container_container1_health_status_none": 0, 260 "container_container1_health_status_not_running_unhealthy": 0, 261 "container_container1_health_status_starting": 0, 262 "container_container1_health_status_unhealthy": 0, 263 "container_container1_size_root_fs": 0, 264 "container_container1_size_rw": 0, 265 "container_container1_state_created": 1, 266 "container_container1_state_dead": 0, 267 "container_container1_state_exited": 0, 268 "container_container1_state_paused": 0, 269 "container_container1_state_removing": 0, 270 "container_container1_state_restarting": 0, 271 "container_container1_state_running": 0, 272 "container_container2_health_status_healthy": 1, 273 "container_container2_health_status_none": 0, 274 "container_container2_health_status_not_running_unhealthy": 0, 275 "container_container2_health_status_starting": 0, 276 "container_container2_health_status_unhealthy": 0, 277 "container_container2_size_root_fs": 0, 278 "container_container2_size_rw": 0, 279 "container_container2_state_created": 0, 280 "container_container2_state_dead": 0, 281 "container_container2_state_exited": 0, 282 "container_container2_state_paused": 0, 283 "container_container2_state_removing": 0, 284 "container_container2_state_restarting": 0, 285 "container_container2_state_running": 1, 286 "container_container3_health_status_healthy": 1, 287 "container_container3_health_status_none": 0, 288 "container_container3_health_status_not_running_unhealthy": 0, 289 "container_container3_health_status_starting": 0, 290 "container_container3_health_status_unhealthy": 0, 291 "container_container3_size_root_fs": 0, 292 "container_container3_size_rw": 0, 293 "container_container3_state_created": 0, 294 "container_container3_state_dead": 0, 295 "container_container3_state_exited": 0, 296 "container_container3_state_paused": 0, 297 "container_container3_state_removing": 0, 298 "container_container3_state_restarting": 0, 299 "container_container3_state_running": 1, 300 "container_container4_health_status_healthy": 0, 301 "container_container4_health_status_none": 0, 302 "container_container4_health_status_not_running_unhealthy": 1, 303 "container_container4_health_status_starting": 0, 304 "container_container4_health_status_unhealthy": 0, 305 "container_container4_size_root_fs": 0, 306 "container_container4_size_rw": 0, 307 "container_container4_state_created": 1, 308 "container_container4_state_dead": 0, 309 "container_container4_state_exited": 0, 310 "container_container4_state_paused": 0, 311 "container_container4_state_removing": 0, 312 "container_container4_state_restarting": 0, 313 "container_container4_state_running": 0, 314 "container_container5_health_status_healthy": 0, 315 "container_container5_health_status_none": 0, 316 "container_container5_health_status_not_running_unhealthy": 0, 317 "container_container5_health_status_starting": 0, 318 "container_container5_health_status_unhealthy": 1, 319 "container_container5_size_root_fs": 0, 320 "container_container5_size_rw": 0, 321 "container_container5_state_created": 0, 322 "container_container5_state_dead": 0, 323 "container_container5_state_exited": 0, 324 "container_container5_state_paused": 0, 325 "container_container5_state_removing": 0, 326 "container_container5_state_restarting": 0, 327 "container_container5_state_running": 1, 328 "container_container6_health_status_healthy": 0, 329 "container_container6_health_status_none": 0, 330 "container_container6_health_status_not_running_unhealthy": 1, 331 "container_container6_health_status_starting": 0, 332 "container_container6_health_status_unhealthy": 0, 333 "container_container6_size_root_fs": 0, 334 "container_container6_size_rw": 0, 335 "container_container6_state_created": 0, 336 "container_container6_state_dead": 0, 337 "container_container6_state_exited": 0, 338 "container_container6_state_paused": 1, 339 "container_container6_state_removing": 0, 340 "container_container6_state_restarting": 0, 341 "container_container6_state_running": 0, 342 "container_container7_health_status_healthy": 0, 343 "container_container7_health_status_none": 0, 344 "container_container7_health_status_not_running_unhealthy": 1, 345 "container_container7_health_status_starting": 0, 346 "container_container7_health_status_unhealthy": 0, 347 "container_container7_size_root_fs": 0, 348 "container_container7_size_rw": 0, 349 "container_container7_state_created": 0, 350 "container_container7_state_dead": 0, 351 "container_container7_state_exited": 0, 352 "container_container7_state_paused": 0, 353 "container_container7_state_removing": 0, 354 "container_container7_state_restarting": 1, 355 "container_container7_state_running": 0, 356 "container_container8_health_status_healthy": 0, 357 "container_container8_health_status_none": 0, 358 "container_container8_health_status_not_running_unhealthy": 1, 359 "container_container8_health_status_starting": 0, 360 "container_container8_health_status_unhealthy": 0, 361 "container_container8_size_root_fs": 0, 362 "container_container8_size_rw": 0, 363 "container_container8_state_created": 0, 364 "container_container8_state_dead": 0, 365 "container_container8_state_exited": 0, 366 "container_container8_state_paused": 0, 367 "container_container8_state_removing": 1, 368 "container_container8_state_restarting": 0, 369 "container_container8_state_running": 0, 370 "container_container9_health_status_healthy": 0, 371 "container_container9_health_status_none": 0, 372 "container_container9_health_status_not_running_unhealthy": 1, 373 "container_container9_health_status_starting": 0, 374 "container_container9_health_status_unhealthy": 0, 375 "container_container9_size_root_fs": 0, 376 "container_container9_size_rw": 0, 377 "container_container9_state_created": 0, 378 "container_container9_state_dead": 0, 379 "container_container9_state_exited": 1, 380 "container_container9_state_paused": 0, 381 "container_container9_state_removing": 0, 382 "container_container9_state_restarting": 0, 383 "container_container9_state_running": 0, 384 "containers_health_status_healthy": 3, 385 "containers_health_status_none": 3, 386 "containers_health_status_not_running_unhealthy": 6, 387 "containers_health_status_starting": 3, 388 "containers_health_status_unhealthy": 1, 389 "containers_state_exited": 6, 390 "containers_state_paused": 5, 391 "containers_state_running": 4, 392 "images_active": 1, 393 "images_dangling": 1, 394 "images_size": 300, 395 }, 396 }, 397 "case success without container size": { 398 prepare: func() *Docker { 399 return prepareCaseSuccessWithoutContainerSize() 400 }, 401 expected: map[string]int64{ 402 "container_container10_health_status_healthy": 0, 403 "container_container10_health_status_none": 0, 404 "container_container10_health_status_not_running_unhealthy": 1, 405 "container_container10_health_status_starting": 0, 406 "container_container10_health_status_unhealthy": 0, 407 "container_container10_size_root_fs": 0, 408 "container_container10_size_rw": 0, 409 "container_container10_state_created": 0, 410 "container_container10_state_dead": 1, 411 "container_container10_state_exited": 0, 412 "container_container10_state_paused": 0, 413 "container_container10_state_removing": 0, 414 "container_container10_state_restarting": 0, 415 "container_container10_state_running": 0, 416 "container_container11_health_status_healthy": 0, 417 "container_container11_health_status_none": 0, 418 "container_container11_health_status_not_running_unhealthy": 0, 419 "container_container11_health_status_starting": 1, 420 "container_container11_health_status_unhealthy": 0, 421 "container_container11_size_root_fs": 0, 422 "container_container11_size_rw": 0, 423 "container_container11_state_created": 0, 424 "container_container11_state_dead": 0, 425 "container_container11_state_exited": 0, 426 "container_container11_state_paused": 0, 427 "container_container11_state_removing": 1, 428 "container_container11_state_restarting": 0, 429 "container_container11_state_running": 0, 430 "container_container12_health_status_healthy": 0, 431 "container_container12_health_status_none": 0, 432 "container_container12_health_status_not_running_unhealthy": 0, 433 "container_container12_health_status_starting": 1, 434 "container_container12_health_status_unhealthy": 0, 435 "container_container12_size_root_fs": 0, 436 "container_container12_size_rw": 0, 437 "container_container12_state_created": 0, 438 "container_container12_state_dead": 0, 439 "container_container12_state_exited": 1, 440 "container_container12_state_paused": 0, 441 "container_container12_state_removing": 0, 442 "container_container12_state_restarting": 0, 443 "container_container12_state_running": 0, 444 "container_container13_health_status_healthy": 0, 445 "container_container13_health_status_none": 0, 446 "container_container13_health_status_not_running_unhealthy": 0, 447 "container_container13_health_status_starting": 1, 448 "container_container13_health_status_unhealthy": 0, 449 "container_container13_size_root_fs": 0, 450 "container_container13_size_rw": 0, 451 "container_container13_state_created": 0, 452 "container_container13_state_dead": 0, 453 "container_container13_state_exited": 1, 454 "container_container13_state_paused": 0, 455 "container_container13_state_removing": 0, 456 "container_container13_state_restarting": 0, 457 "container_container13_state_running": 0, 458 "container_container14_health_status_healthy": 0, 459 "container_container14_health_status_none": 1, 460 "container_container14_health_status_not_running_unhealthy": 0, 461 "container_container14_health_status_starting": 0, 462 "container_container14_health_status_unhealthy": 0, 463 "container_container14_size_root_fs": 0, 464 "container_container14_size_rw": 0, 465 "container_container14_state_created": 0, 466 "container_container14_state_dead": 1, 467 "container_container14_state_exited": 0, 468 "container_container14_state_paused": 0, 469 "container_container14_state_removing": 0, 470 "container_container14_state_restarting": 0, 471 "container_container14_state_running": 0, 472 "container_container15_health_status_healthy": 0, 473 "container_container15_health_status_none": 1, 474 "container_container15_health_status_not_running_unhealthy": 0, 475 "container_container15_health_status_starting": 0, 476 "container_container15_health_status_unhealthy": 0, 477 "container_container15_size_root_fs": 0, 478 "container_container15_size_rw": 0, 479 "container_container15_state_created": 0, 480 "container_container15_state_dead": 1, 481 "container_container15_state_exited": 0, 482 "container_container15_state_paused": 0, 483 "container_container15_state_removing": 0, 484 "container_container15_state_restarting": 0, 485 "container_container15_state_running": 0, 486 "container_container16_health_status_healthy": 0, 487 "container_container16_health_status_none": 1, 488 "container_container16_health_status_not_running_unhealthy": 0, 489 "container_container16_health_status_starting": 0, 490 "container_container16_health_status_unhealthy": 0, 491 "container_container16_size_root_fs": 0, 492 "container_container16_size_rw": 0, 493 "container_container16_state_created": 0, 494 "container_container16_state_dead": 1, 495 "container_container16_state_exited": 0, 496 "container_container16_state_paused": 0, 497 "container_container16_state_removing": 0, 498 "container_container16_state_restarting": 0, 499 "container_container16_state_running": 0, 500 "container_container1_health_status_healthy": 1, 501 "container_container1_health_status_none": 0, 502 "container_container1_health_status_not_running_unhealthy": 0, 503 "container_container1_health_status_starting": 0, 504 "container_container1_health_status_unhealthy": 0, 505 "container_container1_size_root_fs": 0, 506 "container_container1_size_rw": 0, 507 "container_container1_state_created": 1, 508 "container_container1_state_dead": 0, 509 "container_container1_state_exited": 0, 510 "container_container1_state_paused": 0, 511 "container_container1_state_removing": 0, 512 "container_container1_state_restarting": 0, 513 "container_container1_state_running": 0, 514 "container_container2_health_status_healthy": 1, 515 "container_container2_health_status_none": 0, 516 "container_container2_health_status_not_running_unhealthy": 0, 517 "container_container2_health_status_starting": 0, 518 "container_container2_health_status_unhealthy": 0, 519 "container_container2_size_root_fs": 0, 520 "container_container2_size_rw": 0, 521 "container_container2_state_created": 0, 522 "container_container2_state_dead": 0, 523 "container_container2_state_exited": 0, 524 "container_container2_state_paused": 0, 525 "container_container2_state_removing": 0, 526 "container_container2_state_restarting": 0, 527 "container_container2_state_running": 1, 528 "container_container3_health_status_healthy": 1, 529 "container_container3_health_status_none": 0, 530 "container_container3_health_status_not_running_unhealthy": 0, 531 "container_container3_health_status_starting": 0, 532 "container_container3_health_status_unhealthy": 0, 533 "container_container3_size_root_fs": 0, 534 "container_container3_size_rw": 0, 535 "container_container3_state_created": 0, 536 "container_container3_state_dead": 0, 537 "container_container3_state_exited": 0, 538 "container_container3_state_paused": 0, 539 "container_container3_state_removing": 0, 540 "container_container3_state_restarting": 0, 541 "container_container3_state_running": 1, 542 "container_container4_health_status_healthy": 0, 543 "container_container4_health_status_none": 0, 544 "container_container4_health_status_not_running_unhealthy": 1, 545 "container_container4_health_status_starting": 0, 546 "container_container4_health_status_unhealthy": 0, 547 "container_container4_size_root_fs": 0, 548 "container_container4_size_rw": 0, 549 "container_container4_state_created": 1, 550 "container_container4_state_dead": 0, 551 "container_container4_state_exited": 0, 552 "container_container4_state_paused": 0, 553 "container_container4_state_removing": 0, 554 "container_container4_state_restarting": 0, 555 "container_container4_state_running": 0, 556 "container_container5_health_status_healthy": 0, 557 "container_container5_health_status_none": 0, 558 "container_container5_health_status_not_running_unhealthy": 0, 559 "container_container5_health_status_starting": 0, 560 "container_container5_health_status_unhealthy": 1, 561 "container_container5_size_root_fs": 0, 562 "container_container5_size_rw": 0, 563 "container_container5_state_created": 0, 564 "container_container5_state_dead": 0, 565 "container_container5_state_exited": 0, 566 "container_container5_state_paused": 0, 567 "container_container5_state_removing": 0, 568 "container_container5_state_restarting": 0, 569 "container_container5_state_running": 1, 570 "container_container6_health_status_healthy": 0, 571 "container_container6_health_status_none": 0, 572 "container_container6_health_status_not_running_unhealthy": 1, 573 "container_container6_health_status_starting": 0, 574 "container_container6_health_status_unhealthy": 0, 575 "container_container6_size_root_fs": 0, 576 "container_container6_size_rw": 0, 577 "container_container6_state_created": 0, 578 "container_container6_state_dead": 0, 579 "container_container6_state_exited": 0, 580 "container_container6_state_paused": 1, 581 "container_container6_state_removing": 0, 582 "container_container6_state_restarting": 0, 583 "container_container6_state_running": 0, 584 "container_container7_health_status_healthy": 0, 585 "container_container7_health_status_none": 0, 586 "container_container7_health_status_not_running_unhealthy": 1, 587 "container_container7_health_status_starting": 0, 588 "container_container7_health_status_unhealthy": 0, 589 "container_container7_size_root_fs": 0, 590 "container_container7_size_rw": 0, 591 "container_container7_state_created": 0, 592 "container_container7_state_dead": 0, 593 "container_container7_state_exited": 0, 594 "container_container7_state_paused": 0, 595 "container_container7_state_removing": 0, 596 "container_container7_state_restarting": 1, 597 "container_container7_state_running": 0, 598 "container_container8_health_status_healthy": 0, 599 "container_container8_health_status_none": 0, 600 "container_container8_health_status_not_running_unhealthy": 1, 601 "container_container8_health_status_starting": 0, 602 "container_container8_health_status_unhealthy": 0, 603 "container_container8_size_root_fs": 0, 604 "container_container8_size_rw": 0, 605 "container_container8_state_created": 0, 606 "container_container8_state_dead": 0, 607 "container_container8_state_exited": 0, 608 "container_container8_state_paused": 0, 609 "container_container8_state_removing": 1, 610 "container_container8_state_restarting": 0, 611 "container_container8_state_running": 0, 612 "container_container9_health_status_healthy": 0, 613 "container_container9_health_status_none": 0, 614 "container_container9_health_status_not_running_unhealthy": 1, 615 "container_container9_health_status_starting": 0, 616 "container_container9_health_status_unhealthy": 0, 617 "container_container9_size_root_fs": 0, 618 "container_container9_size_rw": 0, 619 "container_container9_state_created": 0, 620 "container_container9_state_dead": 0, 621 "container_container9_state_exited": 1, 622 "container_container9_state_paused": 0, 623 "container_container9_state_removing": 0, 624 "container_container9_state_restarting": 0, 625 "container_container9_state_running": 0, 626 "containers_health_status_healthy": 3, 627 "containers_health_status_none": 3, 628 "containers_health_status_not_running_unhealthy": 6, 629 "containers_health_status_starting": 3, 630 "containers_health_status_unhealthy": 1, 631 "containers_state_exited": 6, 632 "containers_state_paused": 5, 633 "containers_state_running": 4, 634 "images_active": 1, 635 "images_dangling": 1, 636 "images_size": 300, 637 }, 638 }, 639 "fail on case err on Info()": { 640 prepare: func() *Docker { 641 return prepareCaseErrOnInfo() 642 }, 643 expected: nil, 644 }, 645 "fail on case err on ImageList()": { 646 prepare: func() *Docker { 647 return prepareCaseErrOnImageList() 648 }, 649 expected: nil, 650 }, 651 "fail on case err on ContainerList()": { 652 prepare: func() *Docker { 653 return prepareCaseErrOnContainerList() 654 }, 655 expected: nil, 656 }, 657 "fail on case err on creating Docker client": { 658 prepare: func() *Docker { 659 return prepareCaseErrCreatingClient() 660 }, 661 expected: nil, 662 }, 663 } 664 665 for name, test := range tests { 666 t.Run(name, func(t *testing.T) { 667 d := test.prepare() 668 669 require.True(t, d.Init()) 670 671 mx := d.Collect() 672 673 require.Equal(t, test.expected, mx) 674 675 if d.client != nil { 676 m, ok := d.client.(*mockClient) 677 require.True(t, ok) 678 require.True(t, m.negotiateAPIVersionCalled) 679 } 680 681 }) 682 } 683 } 684 685 func prepareCaseSuccess() *Docker { 686 d := New() 687 d.CollectContainerSize = true 688 d.newClient = prepareNewClientFunc(&mockClient{}) 689 return d 690 } 691 692 func prepareCaseSuccessWithoutContainerSize() *Docker { 693 d := New() 694 d.CollectContainerSize = false 695 d.newClient = prepareNewClientFunc(&mockClient{}) 696 return d 697 } 698 699 func prepareCaseErrOnInfo() *Docker { 700 d := New() 701 d.newClient = prepareNewClientFunc(&mockClient{errOnInfo: true}) 702 return d 703 } 704 705 func prepareCaseErrOnImageList() *Docker { 706 d := New() 707 d.newClient = prepareNewClientFunc(&mockClient{errOnImageList: true}) 708 return d 709 } 710 711 func prepareCaseErrOnContainerList() *Docker { 712 d := New() 713 d.newClient = prepareNewClientFunc(&mockClient{errOnContainerList: true}) 714 return d 715 } 716 717 func prepareCaseErrCreatingClient() *Docker { 718 d := New() 719 d.newClient = prepareNewClientFunc(nil) 720 return d 721 } 722 723 func prepareNewClientFunc(m *mockClient) func(_ Config) (dockerClient, error) { 724 if m == nil { 725 return func(_ Config) (dockerClient, error) { return nil, errors.New("mock.newClient() error") } 726 } 727 return func(_ Config) (dockerClient, error) { return m, nil } 728 } 729 730 type mockClient struct { 731 errOnInfo bool 732 errOnImageList bool 733 errOnContainerList bool 734 negotiateAPIVersionCalled bool 735 closeCalled bool 736 } 737 738 func (m *mockClient) Info(_ context.Context) (types.Info, error) { 739 if m.errOnInfo { 740 return types.Info{}, errors.New("mockClient.Info() error") 741 } 742 743 return types.Info{ 744 ContainersRunning: 4, 745 ContainersPaused: 5, 746 ContainersStopped: 6, 747 }, nil 748 } 749 750 func (m *mockClient) ContainerList(_ context.Context, opts types.ContainerListOptions) ([]types.Container, error) { 751 if m.errOnContainerList { 752 return nil, errors.New("mockClient.ContainerList() error") 753 } 754 755 v := opts.Filters.Get("health") 756 757 if len(v) == 0 { 758 return nil, errors.New("mockClient.ContainerList() error (expect 'health' filter)") 759 } 760 761 var containers []types.Container 762 763 switch v[0] { 764 case types.Healthy: 765 containers = []types.Container{ 766 {Names: []string{"container1"}, State: "created", Image: "example/example:v1"}, 767 {Names: []string{"container2"}, State: "running", Image: "example/example:v1"}, 768 {Names: []string{"container3"}, State: "running", Image: "example/example:v1"}, 769 } 770 case types.Unhealthy: 771 containers = []types.Container{ 772 {Names: []string{"container4"}, State: "created", Image: "example/example:v2"}, 773 {Names: []string{"container5"}, State: "running", Image: "example/example:v2"}, 774 {Names: []string{"container6"}, State: "paused", Image: "example/example:v2"}, 775 {Names: []string{"container7"}, State: "restarting", Image: "example/example:v2"}, 776 {Names: []string{"container8"}, State: "removing", Image: "example/example:v2"}, 777 {Names: []string{"container9"}, State: "exited", Image: "example/example:v2"}, 778 {Names: []string{"container10"}, State: "dead", Image: "example/example:v2"}, 779 } 780 case types.Starting: 781 containers = []types.Container{ 782 {Names: []string{"container11"}, State: "removing", Image: "example/example:v3"}, 783 {Names: []string{"container12"}, State: "exited", Image: "example/example:v3"}, 784 {Names: []string{"container13"}, State: "exited", Image: "example/example:v3"}, 785 } 786 case types.NoHealthcheck: 787 containers = []types.Container{ 788 {Names: []string{"container14"}, State: "dead", Image: "example/example:v4"}, 789 {Names: []string{"container15"}, State: "dead", Image: "example/example:v4"}, 790 {Names: []string{"container16"}, State: "dead", Image: "example/example:v4"}, 791 } 792 } 793 794 if opts.Size { 795 for _, c := range containers { 796 c.SizeRw = 123 797 c.SizeRootFs = 321 798 } 799 } 800 801 return containers, nil 802 } 803 804 func (m *mockClient) ImageList(_ context.Context, _ types.ImageListOptions) ([]types.ImageSummary, error) { 805 if m.errOnImageList { 806 return nil, errors.New("mockClient.ImageList() error") 807 } 808 809 return []types.ImageSummary{ 810 { 811 Containers: 0, 812 Size: 100, 813 }, 814 { 815 Containers: 1, 816 Size: 200, 817 }, 818 }, nil 819 } 820 821 func (m *mockClient) NegotiateAPIVersion(_ context.Context) { 822 m.negotiateAPIVersionCalled = true 823 } 824 825 func (m *mockClient) Close() error { 826 m.closeCalled = true 827 return nil 828 }