Non systemd support with unittest (#8785)

This commit is contained in:
Niels Huylebroeck 2021-02-26 16:42:46 +01:00 committed by GitHub
parent 25aa0eeb21
commit e1a896ca12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 25 deletions

View File

@ -16,8 +16,6 @@ type diskInfoCache struct {
values map[string]string
}
var udevPath = "/run/udev/data"
func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
var err error
var stat unix.Stat_t
@ -37,9 +35,33 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
return ic.values, nil
}
var udevDataPath string
if ok && len(ic.udevDataPath) > 0 {
// We can reuse the udev data path from a "previous" entry.
// This allows us to also "poison" it during test scenarios
udevDataPath = ic.udevDataPath
} else {
major := unix.Major(uint64(stat.Rdev))
minor := unix.Minor(uint64(stat.Rdev))
udevDataPath := fmt.Sprintf("%s/b%d:%d", udevPath, major, minor)
udevDataPath = fmt.Sprintf("/run/udev/data/b%d:%d", major, minor)
_, err := os.Stat(udevDataPath)
if err != nil {
// This path failed, try the fallback .udev style (non-systemd)
udevDataPath = fmt.Sprintf("/dev/.udev/db/block:%s", devName)
_, err := os.Stat(udevDataPath)
if err != nil {
// Giving up, cannot retrieve disk info
return nil, err
}
}
}
// Final open of the confirmed (or the previously detected/used) udev file
f, err := os.Open(udevDataPath)
defer f.Close()
if err != nil {
return nil, err
}
di := map[string]string{}
@ -49,12 +71,6 @@ func (d *DiskIO) diskInfo(devName string) (map[string]string, error) {
values: di,
}
f, err := os.Open(udevDataPath)
if err != nil {
return nil, err
}
defer f.Close()
scnr := bufio.NewScanner(f)
var devlinks bytes.Buffer
for scnr.Scan() {

View File

@ -19,19 +19,31 @@ S:foo/bar/devlink1
`)
// setupNullDisk sets up fake udev info as if /dev/null were a disk.
func setupNullDisk(t *testing.T) func() error {
td, err := ioutil.TempDir("", ".telegraf.TestDiskInfo")
func setupNullDisk(t *testing.T, s *DiskIO, devName string) func() error {
td, err := ioutil.TempFile("", ".telegraf.DiskInfoTest")
require.NoError(t, err)
origUdevPath := udevPath
if s.infoCache == nil {
s.infoCache = make(map[string]diskInfoCache, 0)
}
ic, ok := s.infoCache[devName]
if !ok {
// No previous calls for the device were done, easy to poison the cache
s.infoCache[devName] = diskInfoCache{
modifiedAt: 0,
udevDataPath: td.Name(),
values: map[string]string{},
}
}
origUdevPath := ic.udevDataPath
cleanFunc := func() error {
udevPath = origUdevPath
return os.RemoveAll(td)
ic.udevDataPath = origUdevPath
return os.Remove(td.Name())
}
udevPath = td
err = ioutil.WriteFile(td+"/b1:3", nullDiskInfo, 0644) // 1:3 is the 'null' device
ic.udevDataPath = td.Name()
_, err = td.Write(nullDiskInfo)
if err != nil {
cleanFunc()
t.Fatal(err)
@ -41,10 +53,9 @@ func setupNullDisk(t *testing.T) func() error {
}
func TestDiskInfo(t *testing.T) {
clean := setupNullDisk(t)
defer clean()
s := &DiskIO{}
clean := setupNullDisk(t, s, "null")
defer clean()
di, err := s.diskInfo("null")
require.NoError(t, err)
assert.Equal(t, "myval1", di["MY_PARAM_1"])
@ -67,8 +78,6 @@ func TestDiskInfo(t *testing.T) {
// DiskIOStats.diskName isn't a linux specific function, but dependent
// functions are a no-op on non-Linux.
func TestDiskIOStats_diskName(t *testing.T) {
defer setupNullDisk(t)()
tests := []struct {
templates []string
expected string
@ -88,6 +97,7 @@ func TestDiskIOStats_diskName(t *testing.T) {
s := DiskIO{
NameTemplates: tc.templates,
}
defer setupNullDisk(t, &s, "null")()
name, _ := s.diskName("null")
assert.Equal(t, tc.expected, name, "Templates: %#v", tc.templates)
}
@ -96,11 +106,10 @@ func TestDiskIOStats_diskName(t *testing.T) {
// DiskIOStats.diskTags isn't a linux specific function, but dependent
// functions are a no-op on non-Linux.
func TestDiskIOStats_diskTags(t *testing.T) {
defer setupNullDisk(t)()
s := &DiskIO{
DeviceTags: []string{"MY_PARAM_2"},
}
defer setupNullDisk(t, s, "null")()
dt := s.diskTags("null")
assert.Equal(t, map[string]string{"MY_PARAM_2": "myval2"}, dt)
}