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  }