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

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package file
     4  
     5  import (
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/netdata/go.d.plugin/agent/confgroup"
    10  	"github.com/netdata/go.d.plugin/agent/module"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestWatcher_String(t *testing.T) {
    16  	assert.NotEmpty(t, NewWatcher(confgroup.Registry{}, nil))
    17  }
    18  
    19  func TestNewWatcher(t *testing.T) {
    20  	tests := map[string]struct {
    21  		reg   confgroup.Registry
    22  		paths []string
    23  	}{
    24  		"empty inputs": {
    25  			reg:   confgroup.Registry{},
    26  			paths: []string{},
    27  		},
    28  	}
    29  
    30  	for name, test := range tests {
    31  		t.Run(name, func(t *testing.T) { assert.NotNil(t, NewWatcher(test.reg, test.paths)) })
    32  	}
    33  }
    34  
    35  func TestWatcher_Run(t *testing.T) {
    36  	tests := map[string]func(tmp *tmpDir) discoverySim{
    37  		"file exists before start": func(tmp *tmpDir) discoverySim {
    38  			reg := confgroup.Registry{
    39  				"module": {},
    40  			}
    41  			cfg := sdConfig{
    42  				{
    43  					"name":   "name",
    44  					"module": "module",
    45  				},
    46  			}
    47  			filename := tmp.join("module.conf")
    48  			discovery := prepareDiscovery(t, Config{
    49  				Registry: reg,
    50  				Watch:    []string{tmp.join("*.conf")},
    51  			})
    52  			expected := []*confgroup.Group{
    53  				{
    54  					Source: filename,
    55  					Configs: []confgroup.Config{
    56  						{
    57  							"name":                "name",
    58  							"module":              "module",
    59  							"update_every":        module.UpdateEvery,
    60  							"autodetection_retry": module.AutoDetectionRetry,
    61  							"priority":            module.Priority,
    62  							"__source__":          filename,
    63  							"__provider__":        "file watcher",
    64  						},
    65  					},
    66  				},
    67  			}
    68  
    69  			sim := discoverySim{
    70  				discovery: discovery,
    71  				beforeRun: func() {
    72  					tmp.writeYAML(filename, cfg)
    73  				},
    74  				expectedGroups: expected,
    75  			}
    76  			return sim
    77  		},
    78  		"empty file": func(tmp *tmpDir) discoverySim {
    79  			reg := confgroup.Registry{
    80  				"module": {},
    81  			}
    82  			filename := tmp.join("module.conf")
    83  			discovery := prepareDiscovery(t, Config{
    84  				Registry: reg,
    85  				Watch:    []string{tmp.join("*.conf")},
    86  			})
    87  			expected := []*confgroup.Group{
    88  				{
    89  					Source: filename,
    90  				},
    91  			}
    92  
    93  			sim := discoverySim{
    94  				discovery: discovery,
    95  				beforeRun: func() {
    96  					tmp.writeString(filename, "")
    97  				},
    98  				expectedGroups: expected,
    99  			}
   100  			return sim
   101  		},
   102  		"only comments, no data": func(tmp *tmpDir) discoverySim {
   103  			reg := confgroup.Registry{
   104  				"module": {},
   105  			}
   106  			filename := tmp.join("module.conf")
   107  			discovery := prepareDiscovery(t, Config{
   108  				Registry: reg,
   109  				Watch:    []string{tmp.join("*.conf")},
   110  			})
   111  			expected := []*confgroup.Group{
   112  				{
   113  					Source: filename,
   114  				},
   115  			}
   116  
   117  			sim := discoverySim{
   118  				discovery: discovery,
   119  				beforeRun: func() {
   120  					tmp.writeString(filename, "# a comment")
   121  				},
   122  				expectedGroups: expected,
   123  			}
   124  			return sim
   125  		},
   126  		"add file": func(tmp *tmpDir) discoverySim {
   127  			reg := confgroup.Registry{
   128  				"module": {},
   129  			}
   130  			cfg := sdConfig{
   131  				{
   132  					"name":   "name",
   133  					"module": "module",
   134  				},
   135  			}
   136  			filename := tmp.join("module.conf")
   137  			discovery := prepareDiscovery(t, Config{
   138  				Registry: reg,
   139  				Watch:    []string{tmp.join("*.conf")},
   140  			})
   141  			expected := []*confgroup.Group{
   142  				{
   143  					Source: filename,
   144  					Configs: []confgroup.Config{
   145  						{
   146  							"name":                "name",
   147  							"module":              "module",
   148  							"update_every":        module.UpdateEvery,
   149  							"autodetection_retry": module.AutoDetectionRetry,
   150  							"priority":            module.Priority,
   151  							"__source__":          filename,
   152  							"__provider__":        "file watcher",
   153  						},
   154  					},
   155  				},
   156  			}
   157  
   158  			sim := discoverySim{
   159  				discovery: discovery,
   160  				afterRun: func() {
   161  					tmp.writeYAML(filename, cfg)
   162  				},
   163  				expectedGroups: expected,
   164  			}
   165  			return sim
   166  		},
   167  		"remove file": func(tmp *tmpDir) discoverySim {
   168  			reg := confgroup.Registry{
   169  				"module": {},
   170  			}
   171  			cfg := sdConfig{
   172  				{
   173  					"name":   "name",
   174  					"module": "module",
   175  				},
   176  			}
   177  			filename := tmp.join("module.conf")
   178  			discovery := prepareDiscovery(t, Config{
   179  				Registry: reg,
   180  				Watch:    []string{tmp.join("*.conf")},
   181  			})
   182  			expected := []*confgroup.Group{
   183  				{
   184  					Source: filename,
   185  					Configs: []confgroup.Config{
   186  						{
   187  							"name":                "name",
   188  							"module":              "module",
   189  							"update_every":        module.UpdateEvery,
   190  							"autodetection_retry": module.AutoDetectionRetry,
   191  							"priority":            module.Priority,
   192  							"__source__":          filename,
   193  							"__provider__":        "file watcher",
   194  						},
   195  					},
   196  				},
   197  				{
   198  					Source:  filename,
   199  					Configs: nil,
   200  				},
   201  			}
   202  
   203  			sim := discoverySim{
   204  				discovery: discovery,
   205  				beforeRun: func() {
   206  					tmp.writeYAML(filename, cfg)
   207  				},
   208  				afterRun: func() {
   209  					tmp.removeFile(filename)
   210  				},
   211  				expectedGroups: expected,
   212  			}
   213  			return sim
   214  		},
   215  		"change file": func(tmp *tmpDir) discoverySim {
   216  			reg := confgroup.Registry{
   217  				"module": {},
   218  			}
   219  			cfgOrig := sdConfig{
   220  				{
   221  					"name":   "name",
   222  					"module": "module",
   223  				},
   224  			}
   225  			cfgChanged := sdConfig{
   226  				{
   227  					"name":   "name_changed",
   228  					"module": "module",
   229  				},
   230  			}
   231  			filename := tmp.join("module.conf")
   232  			discovery := prepareDiscovery(t, Config{
   233  				Registry: reg,
   234  				Watch:    []string{tmp.join("*.conf")},
   235  			})
   236  			expected := []*confgroup.Group{
   237  				{
   238  					Source: filename,
   239  					Configs: []confgroup.Config{
   240  						{
   241  							"name":                "name",
   242  							"module":              "module",
   243  							"update_every":        module.UpdateEvery,
   244  							"autodetection_retry": module.AutoDetectionRetry,
   245  							"priority":            module.Priority,
   246  							"__source__":          filename,
   247  							"__provider__":        "file watcher",
   248  						},
   249  					},
   250  				},
   251  				{
   252  					Source: filename,
   253  					Configs: []confgroup.Config{
   254  						{
   255  							"name":                "name_changed",
   256  							"module":              "module",
   257  							"update_every":        module.UpdateEvery,
   258  							"autodetection_retry": module.AutoDetectionRetry,
   259  							"priority":            module.Priority,
   260  							"__source__":          filename,
   261  							"__provider__":        "file watcher",
   262  						},
   263  					},
   264  				},
   265  			}
   266  
   267  			sim := discoverySim{
   268  				discovery: discovery,
   269  				beforeRun: func() {
   270  					tmp.writeYAML(filename, cfgOrig)
   271  				},
   272  				afterRun: func() {
   273  					tmp.writeYAML(filename, cfgChanged)
   274  					time.Sleep(time.Millisecond * 500)
   275  				},
   276  				expectedGroups: expected,
   277  			}
   278  			return sim
   279  		},
   280  		"vim 'backupcopy=no' (writing to a file and backup)": func(tmp *tmpDir) discoverySim {
   281  			reg := confgroup.Registry{
   282  				"module": {},
   283  			}
   284  			cfg := sdConfig{
   285  				{
   286  					"name":   "name",
   287  					"module": "module",
   288  				},
   289  			}
   290  			filename := tmp.join("module.conf")
   291  			discovery := prepareDiscovery(t, Config{
   292  				Registry: reg,
   293  				Watch:    []string{tmp.join("*.conf")},
   294  			})
   295  			expected := []*confgroup.Group{
   296  				{
   297  					Source: filename,
   298  					Configs: []confgroup.Config{
   299  						{
   300  							"name":                "name",
   301  							"module":              "module",
   302  							"update_every":        module.UpdateEvery,
   303  							"autodetection_retry": module.AutoDetectionRetry,
   304  							"priority":            module.Priority,
   305  							"__source__":          filename,
   306  							"__provider__":        "file watcher",
   307  						},
   308  					},
   309  				},
   310  				{
   311  					Source: filename,
   312  					Configs: []confgroup.Config{
   313  						{
   314  							"name":                "name",
   315  							"module":              "module",
   316  							"update_every":        module.UpdateEvery,
   317  							"autodetection_retry": module.AutoDetectionRetry,
   318  							"priority":            module.Priority,
   319  							"__source__":          filename,
   320  							"__provider__":        "file watcher",
   321  						},
   322  					},
   323  				},
   324  			}
   325  
   326  			sim := discoverySim{
   327  				discovery: discovery,
   328  				beforeRun: func() {
   329  					tmp.writeYAML(filename, cfg)
   330  				},
   331  				afterRun: func() {
   332  					newFilename := filename + ".swp"
   333  					tmp.renameFile(filename, newFilename)
   334  					tmp.writeYAML(filename, cfg)
   335  					tmp.removeFile(newFilename)
   336  					time.Sleep(time.Millisecond * 500)
   337  				},
   338  				expectedGroups: expected,
   339  			}
   340  			return sim
   341  		},
   342  	}
   343  
   344  	for name, createSim := range tests {
   345  		t.Run(name, func(t *testing.T) {
   346  			tmp := newTmpDir(t, "watch-run-*")
   347  			defer tmp.cleanup()
   348  
   349  			createSim(tmp).run(t)
   350  		})
   351  	}
   352  }