github.com/netdata/go.d.plugin@v0.58.1/modules/example/example_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package example
     4  
     5  import (
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestNew(t *testing.T) {
    13  	// We want to ensure that module is a reference type, nothing more.
    14  
    15  	assert.IsType(t, (*Example)(nil), New())
    16  }
    17  
    18  func TestExample_Init(t *testing.T) {
    19  	// 'Init() bool' initializes the module with an appropriate config, so to test it we need:
    20  	// - provide the config.
    21  	// - set module.Config field with the config.
    22  	// - call Init() and compare its return value with the expected value.
    23  
    24  	// 'test' map contains different test cases.
    25  	tests := map[string]struct {
    26  		config   Config
    27  		wantFail bool
    28  	}{
    29  		"success on default config": {
    30  			config: New().Config,
    31  		},
    32  		"success when only 'charts' set": {
    33  			config: Config{
    34  				Charts: ConfigCharts{
    35  					Num:  1,
    36  					Dims: 2,
    37  				},
    38  			},
    39  		},
    40  		"success when only 'hidden_charts' set": {
    41  			config: Config{
    42  				HiddenCharts: ConfigCharts{
    43  					Num:  1,
    44  					Dims: 2,
    45  				},
    46  			},
    47  		},
    48  		"success when 'charts' and 'hidden_charts' set": {
    49  			config: Config{
    50  				Charts: ConfigCharts{
    51  					Num:  1,
    52  					Dims: 2,
    53  				},
    54  				HiddenCharts: ConfigCharts{
    55  					Num:  1,
    56  					Dims: 2,
    57  				},
    58  			},
    59  		},
    60  		"fails when 'charts' and 'hidden_charts' set, but 'num' == 0": {
    61  			wantFail: true,
    62  			config: Config{
    63  				Charts: ConfigCharts{
    64  					Num:  0,
    65  					Dims: 2,
    66  				},
    67  				HiddenCharts: ConfigCharts{
    68  					Num:  0,
    69  					Dims: 2,
    70  				},
    71  			},
    72  		},
    73  		"fails when only 'charts' set, 'num' > 0, but 'dimensions' == 0": {
    74  			wantFail: true,
    75  			config: Config{
    76  				Charts: ConfigCharts{
    77  					Num:  1,
    78  					Dims: 0,
    79  				},
    80  			},
    81  		},
    82  		"fails when only 'hidden_charts' set, 'num' > 0, but 'dimensions' == 0": {
    83  			wantFail: true,
    84  			config: Config{
    85  				HiddenCharts: ConfigCharts{
    86  					Num:  1,
    87  					Dims: 0,
    88  				},
    89  			},
    90  		},
    91  	}
    92  
    93  	for name, test := range tests {
    94  		t.Run(name, func(t *testing.T) {
    95  			example := New()
    96  			example.Config = test.config
    97  
    98  			if test.wantFail {
    99  				assert.False(t, example.Init())
   100  			} else {
   101  				assert.True(t, example.Init())
   102  			}
   103  		})
   104  	}
   105  }
   106  
   107  func TestExample_Check(t *testing.T) {
   108  	// 'Check() bool' reports whether the module is able to collect any data, so to test it we need:
   109  	// - provide the module with a specific config.
   110  	// - initialize the module (call Init()).
   111  	// - call Check() and compare its return value with the expected value.
   112  
   113  	// 'test' map contains different test cases.
   114  	tests := map[string]struct {
   115  		prepare  func() *Example
   116  		wantFail bool
   117  	}{
   118  		"success on default":                            {prepare: prepareExampleDefault},
   119  		"success when only 'charts' set":                {prepare: prepareExampleOnlyCharts},
   120  		"success when only 'hidden_charts' set":         {prepare: prepareExampleOnlyHiddenCharts},
   121  		"success when 'charts' and 'hidden_charts' set": {prepare: prepareExampleChartsAndHiddenCharts},
   122  	}
   123  
   124  	for name, test := range tests {
   125  		t.Run(name, func(t *testing.T) {
   126  			example := test.prepare()
   127  			require.True(t, example.Init())
   128  
   129  			if test.wantFail {
   130  				assert.False(t, example.Check())
   131  			} else {
   132  				assert.True(t, example.Check())
   133  			}
   134  		})
   135  	}
   136  }
   137  
   138  func TestExample_Charts(t *testing.T) {
   139  	// We want to ensure that initialized module does not return 'nil'.
   140  	// If it is not 'nil' we are ok.
   141  
   142  	// 'test' map contains different test cases.
   143  	tests := map[string]struct {
   144  		prepare func(t *testing.T) *Example
   145  		wantNil bool
   146  	}{
   147  		"not initialized collector": {
   148  			wantNil: true,
   149  			prepare: func(t *testing.T) *Example {
   150  				return New()
   151  			},
   152  		},
   153  		"initialized collector": {
   154  			prepare: func(t *testing.T) *Example {
   155  				example := New()
   156  				require.True(t, example.Init())
   157  				return example
   158  			},
   159  		},
   160  	}
   161  
   162  	for name, test := range tests {
   163  		t.Run(name, func(t *testing.T) {
   164  			example := test.prepare(t)
   165  
   166  			if test.wantNil {
   167  				assert.Nil(t, example.Charts())
   168  			} else {
   169  				assert.NotNil(t, example.Charts())
   170  			}
   171  		})
   172  	}
   173  }
   174  
   175  func TestExample_Cleanup(t *testing.T) {
   176  	// Since this module has nothing to clean up,
   177  	// we want just to ensure that Cleanup() not panics.
   178  
   179  	assert.NotPanics(t, New().Cleanup)
   180  }
   181  
   182  func TestExample_Collect(t *testing.T) {
   183  	// 'Collect() map[string]int64' returns collected data, so to test it we need:
   184  	// - provide the module with a specific config.
   185  	// - initialize the module (call Init()).
   186  	// - call Collect() and compare its return value with the expected value.
   187  
   188  	// 'test' map contains different test cases.
   189  	tests := map[string]struct {
   190  		prepare       func() *Example
   191  		wantCollected map[string]int64
   192  	}{
   193  		"default config": {
   194  			prepare: prepareExampleDefault,
   195  			wantCollected: map[string]int64{
   196  				"random_0_random0": 1,
   197  				"random_0_random1": -1,
   198  				"random_0_random2": 1,
   199  				"random_0_random3": -1,
   200  			},
   201  		},
   202  		"only 'charts' set": {
   203  			prepare: prepareExampleOnlyCharts,
   204  			wantCollected: map[string]int64{
   205  				"random_0_random0": 1,
   206  				"random_0_random1": -1,
   207  				"random_0_random2": 1,
   208  				"random_0_random3": -1,
   209  				"random_0_random4": 1,
   210  				"random_1_random0": 1,
   211  				"random_1_random1": -1,
   212  				"random_1_random2": 1,
   213  				"random_1_random3": -1,
   214  				"random_1_random4": 1,
   215  			},
   216  		},
   217  		"only 'hidden_charts' set": {
   218  			prepare: prepareExampleOnlyHiddenCharts,
   219  			wantCollected: map[string]int64{
   220  				"hidden_random_0_random0": 1,
   221  				"hidden_random_0_random1": -1,
   222  				"hidden_random_0_random2": 1,
   223  				"hidden_random_0_random3": -1,
   224  				"hidden_random_0_random4": 1,
   225  				"hidden_random_1_random0": 1,
   226  				"hidden_random_1_random1": -1,
   227  				"hidden_random_1_random2": 1,
   228  				"hidden_random_1_random3": -1,
   229  				"hidden_random_1_random4": 1,
   230  			},
   231  		},
   232  		"'charts' and 'hidden_charts' set": {
   233  			prepare: prepareExampleChartsAndHiddenCharts,
   234  			wantCollected: map[string]int64{
   235  				"hidden_random_0_random0": 1,
   236  				"hidden_random_0_random1": -1,
   237  				"hidden_random_0_random2": 1,
   238  				"hidden_random_0_random3": -1,
   239  				"hidden_random_0_random4": 1,
   240  				"hidden_random_1_random0": 1,
   241  				"hidden_random_1_random1": -1,
   242  				"hidden_random_1_random2": 1,
   243  				"hidden_random_1_random3": -1,
   244  				"hidden_random_1_random4": 1,
   245  				"random_0_random0":        1,
   246  				"random_0_random1":        -1,
   247  				"random_0_random2":        1,
   248  				"random_0_random3":        -1,
   249  				"random_0_random4":        1,
   250  				"random_1_random0":        1,
   251  				"random_1_random1":        -1,
   252  				"random_1_random2":        1,
   253  				"random_1_random3":        -1,
   254  				"random_1_random4":        1,
   255  			},
   256  		},
   257  	}
   258  
   259  	for name, test := range tests {
   260  		t.Run(name, func(t *testing.T) {
   261  			example := test.prepare()
   262  			require.True(t, example.Init())
   263  
   264  			collected := example.Collect()
   265  
   266  			assert.Equal(t, test.wantCollected, collected)
   267  			ensureCollectedHasAllChartsDimsVarsIDs(t, example, collected)
   268  		})
   269  	}
   270  }
   271  
   272  func ensureCollectedHasAllChartsDimsVarsIDs(t *testing.T, e *Example, collected map[string]int64) {
   273  	for _, chart := range *e.Charts() {
   274  		if chart.Obsolete {
   275  			continue
   276  		}
   277  		for _, dim := range chart.Dims {
   278  			_, ok := collected[dim.ID]
   279  			assert.Truef(t, ok,
   280  				"collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID)
   281  		}
   282  		for _, v := range chart.Vars {
   283  			_, ok := collected[v.ID]
   284  			assert.Truef(t, ok,
   285  				"collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID)
   286  		}
   287  	}
   288  }
   289  
   290  func prepareExampleDefault() *Example {
   291  	return prepareExample(New().Config)
   292  }
   293  
   294  func prepareExampleOnlyCharts() *Example {
   295  	return prepareExample(Config{
   296  		Charts: ConfigCharts{
   297  			Num:  2,
   298  			Dims: 5,
   299  		},
   300  	})
   301  }
   302  
   303  func prepareExampleOnlyHiddenCharts() *Example {
   304  	return prepareExample(Config{
   305  		HiddenCharts: ConfigCharts{
   306  			Num:  2,
   307  			Dims: 5,
   308  		},
   309  	})
   310  }
   311  
   312  func prepareExampleChartsAndHiddenCharts() *Example {
   313  	return prepareExample(Config{
   314  		Charts: ConfigCharts{
   315  			Num:  2,
   316  			Dims: 5,
   317  		},
   318  		HiddenCharts: ConfigCharts{
   319  			Num:  2,
   320  			Dims: 5,
   321  		},
   322  	})
   323  }
   324  
   325  func prepareExample(cfg Config) *Example {
   326  	example := New()
   327  	example.Config = cfg
   328  	example.randInt = func() int64 { return 1 }
   329  	return example
   330  }