github.com/netdata/go.d.plugin@v0.58.1/agent/discovery/dyncfg/dyncfg_test.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package dyncfg
     4  
     5  import (
     6  	"context"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/netdata/go.d.plugin/agent/confgroup"
    12  	"github.com/netdata/go.d.plugin/agent/functions"
    13  	"github.com/netdata/go.d.plugin/agent/module"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestNewDiscovery(t *testing.T) {
    20  
    21  }
    22  
    23  func TestDiscovery_Register(t *testing.T) {
    24  	tests := map[string]struct {
    25  		regConfigs   []confgroup.Config
    26  		wantApiStats *mockApi
    27  		wantConfigs  int
    28  	}{
    29  		"register jobs created by Dyncfg and other providers": {
    30  			regConfigs: []confgroup.Config{
    31  				prepareConfig(
    32  					"__provider__", dynCfg,
    33  					"module", "test",
    34  					"name", "first",
    35  				),
    36  				prepareConfig(
    37  					"__provider__", "test",
    38  					"module", "test",
    39  					"name", "second",
    40  				),
    41  			},
    42  			wantConfigs: 2,
    43  			wantApiStats: &mockApi{
    44  				callsDynCfgRegisterJob: 1,
    45  			},
    46  		},
    47  	}
    48  
    49  	for name, test := range tests {
    50  		t.Run(name, func(t *testing.T) {
    51  			var mock mockApi
    52  			d := &Discovery{
    53  				API:     &mock,
    54  				mux:     &sync.Mutex{},
    55  				configs: make(map[string]confgroup.Config),
    56  			}
    57  
    58  			for _, v := range test.regConfigs {
    59  				d.Register(v)
    60  			}
    61  
    62  			assert.Equal(t, test.wantApiStats, &mock)
    63  			assert.Equal(t, test.wantConfigs, len(d.configs))
    64  		})
    65  	}
    66  }
    67  
    68  func TestDiscovery_Unregister(t *testing.T) {
    69  	tests := map[string]struct {
    70  		regConfigs   []confgroup.Config
    71  		unregConfigs []confgroup.Config
    72  		wantApiStats *mockApi
    73  		wantConfigs  int
    74  	}{
    75  		"register/unregister jobs created by Dyncfg and other providers": {
    76  			wantConfigs: 0,
    77  			wantApiStats: &mockApi{
    78  				callsDynCfgRegisterJob: 1,
    79  			},
    80  			regConfigs: []confgroup.Config{
    81  				prepareConfig(
    82  					"__provider__", dynCfg,
    83  					"module", "test",
    84  					"name", "first",
    85  				),
    86  				prepareConfig(
    87  					"__provider__", "test",
    88  					"module", "test",
    89  					"name", "second",
    90  				),
    91  			},
    92  			unregConfigs: []confgroup.Config{
    93  				prepareConfig(
    94  					"__provider__", dynCfg,
    95  					"module", "test",
    96  					"name", "first",
    97  				),
    98  				prepareConfig(
    99  					"__provider__", "test",
   100  					"module", "test",
   101  					"name", "second",
   102  				),
   103  			},
   104  		},
   105  	}
   106  
   107  	for name, test := range tests {
   108  		t.Run(name, func(t *testing.T) {
   109  			var mock mockApi
   110  			d := &Discovery{
   111  				API:     &mock,
   112  				mux:     &sync.Mutex{},
   113  				configs: make(map[string]confgroup.Config),
   114  			}
   115  
   116  			for _, v := range test.regConfigs {
   117  				d.Register(v)
   118  			}
   119  			for _, v := range test.unregConfigs {
   120  				d.Unregister(v)
   121  			}
   122  
   123  			assert.Equal(t, test.wantApiStats, &mock)
   124  			assert.Equal(t, test.wantConfigs, len(d.configs))
   125  		})
   126  	}
   127  }
   128  
   129  func TestDiscovery_UpdateStatus(t *testing.T) {
   130  
   131  }
   132  
   133  func TestDiscovery_Run(t *testing.T) {
   134  	tests := map[string]struct {
   135  		wantApiStats *mockApi
   136  	}{
   137  		"default run": {
   138  			wantApiStats: &mockApi{
   139  				callsDynCfgEnable:          1,
   140  				callsDyncCfgRegisterModule: 2,
   141  				callsRegister:              10,
   142  			},
   143  		},
   144  	}
   145  
   146  	for name, test := range tests {
   147  		t.Run(name, func(t *testing.T) {
   148  			var mock mockApi
   149  			d, err := NewDiscovery(Config{
   150  				Plugin:    "test",
   151  				API:       &mock,
   152  				Functions: &mock,
   153  				Modules: module.Registry{
   154  					"module1": module.Creator{},
   155  					"module2": module.Creator{},
   156  				},
   157  				ModuleConfigDefaults: nil,
   158  			})
   159  			require.Nil(t, err)
   160  
   161  			testTime := time.Second * 3
   162  			ctx, cancel := context.WithTimeout(context.Background(), testTime)
   163  			defer cancel()
   164  
   165  			in := make(chan<- []*confgroup.Group)
   166  			done := make(chan struct{})
   167  
   168  			go func() { defer close(done); d.Run(ctx, in) }()
   169  
   170  			timeout := testTime + time.Second*2
   171  			tk := time.NewTimer(timeout)
   172  			defer tk.Stop()
   173  
   174  			select {
   175  			case <-done:
   176  				assert.Equal(t, test.wantApiStats, &mock)
   177  			case <-tk.C:
   178  				t.Errorf("timed out after %s", timeout)
   179  			}
   180  		})
   181  	}
   182  }
   183  
   184  type mockApi struct {
   185  	callsDynCfgEnable          int
   186  	callsDyncCfgRegisterModule int
   187  	callsDynCfgRegisterJob     int
   188  	callsDynCfgReportJobStatus int
   189  	callsFunctionResultSuccess int
   190  	callsFunctionResultReject  int
   191  
   192  	callsRegister int
   193  }
   194  
   195  func (m *mockApi) Register(string, func(functions.Function)) {
   196  	m.callsRegister++
   197  }
   198  
   199  func (m *mockApi) DynCfgEnable(string) error {
   200  	m.callsDynCfgEnable++
   201  	return nil
   202  }
   203  
   204  func (m *mockApi) DynCfgReset() error {
   205  	return nil
   206  }
   207  
   208  func (m *mockApi) DyncCfgRegisterModule(string) error {
   209  	m.callsDyncCfgRegisterModule++
   210  	return nil
   211  }
   212  
   213  func (m *mockApi) DynCfgRegisterJob(_, _, _ string) error {
   214  	m.callsDynCfgRegisterJob++
   215  	return nil
   216  }
   217  
   218  func (m *mockApi) DynCfgReportJobStatus(_, _, _, _ string) error {
   219  	m.callsDynCfgReportJobStatus++
   220  	return nil
   221  }
   222  
   223  func (m *mockApi) FunctionResultSuccess(_, _, _ string) error {
   224  	m.callsFunctionResultSuccess++
   225  	return nil
   226  }
   227  
   228  func (m *mockApi) FunctionResultReject(_, _, _ string) error {
   229  	m.callsFunctionResultReject++
   230  	return nil
   231  }
   232  
   233  func prepareConfig(values ...string) confgroup.Config {
   234  	cfg := confgroup.Config{}
   235  	for i := 1; i < len(values); i += 2 {
   236  		cfg[values[i-1]] = values[i]
   237  	}
   238  	return cfg
   239  }