From 2b50e4af1ade60adaefa8a9883eefbf68d54c991 Mon Sep 17 00:00:00 2001 From: varsha teratipally Date: Thu, 19 Nov 2020 10:29:12 +0000 Subject: [PATCH] add testcases for cos and ubuntu to retrieve modules --- pkg/util/metrics/system/common.go | 2 +- pkg/util/metrics/system/module_stats.go | 42 ++++---- pkg/util/metrics/system/module_stats_test.go | 96 +++++++++++++++++-- .../metrics/system/testdata/modules_cos.txt | 4 + .../system/testdata/modules_ubuntu.txt | 4 + 5 files changed, 117 insertions(+), 31 deletions(-) create mode 100644 pkg/util/metrics/system/testdata/modules_cos.txt create mode 100644 pkg/util/metrics/system/testdata/modules_ubuntu.txt diff --git a/pkg/util/metrics/system/common.go b/pkg/util/metrics/system/common.go index a2e31dc8..77a6125d 100644 --- a/pkg/util/metrics/system/common.go +++ b/pkg/util/metrics/system/common.go @@ -19,7 +19,7 @@ import ( ) // ReadFile reads contents from a file and returns lines. -func ReadFile(filename string) ([]string, error) { +func ReadFileIntoLines(filename string) ([]string, error) { file, err := os.Open(filename) if err != nil { return nil, err diff --git a/pkg/util/metrics/system/module_stats.go b/pkg/util/metrics/system/module_stats.go index 80a114fd..5b5da12a 100644 --- a/pkg/util/metrics/system/module_stats.go +++ b/pkg/util/metrics/system/module_stats.go @@ -20,7 +20,9 @@ import ( "strings" ) -type ModuleStat struct { +var modulesFilePath = "/proc/modules" + +type Module struct { ModuleName string `json:"moduleName"` Instances uint64 `json:"instances"` Proprietary bool `json:"proprietary"` @@ -28,20 +30,19 @@ type ModuleStat struct { Unsigned bool `json:"unsigned"` } -func (d ModuleStat) String() string { +func (d Module) String() string { s, _ := json.Marshal(d) return string(s) } // Module returns all the kernel modules and their // usage. It is read from cat /proc/modules. -func Modules() ([]ModuleStat, error) { - filename := "/proc/modules" - lines, err := ReadFile(filename) +func Modules() ([]Module, error) { + lines, err := ReadFileIntoLines(modulesFilePath) if err != nil { - return nil, fmt.Errorf("Error reading the contents of %s: %s", filename, err) + return nil, fmt.Errorf("error reading the contents of %s: %s", modulesFilePath, err) } - var result = make([]ModuleStat, 0, len(lines)) + var result = make([]Module, 0, len(lines)) /* a line of /proc/modules has the following structure nf_nat 61440 2 xt_MASQUERADE,iptable_nat, Live 0x0000000000000000 (O) @@ -58,28 +59,23 @@ func Modules() ([]ModuleStat, error) { fields := strings.Fields(line) moduleName := fields[0] // name of the module numberOfInstances, err := - strconv.ParseUint((fields[1]), 10, 64) // instances of the module are currently loaded + strconv.ParseUint((fields[2]), 10, 64) // instances of the module are currently loaded if err != nil { - return nil, err + numberOfInstances = 0 } - var isProprietary = false - var isOutofTree = false - var isUnsigned = false + var module = Module{ + ModuleName: moduleName, + Instances: numberOfInstances, + } // if the len of the fields is greater than 6, then the kernel taint state is available. if len(fields) > 6 { - isProprietary = strings.Contains(fields[6], "P") - isOutofTree = strings.Contains(fields[6], "O") - isUnsigned = strings.Contains(fields[6], "E") + module.Proprietary = strings.Contains(fields[6], "P") + module.OutOfTree = strings.Contains(fields[6], "O") + module.Unsigned = strings.Contains(fields[6], "E") } - var stats = ModuleStat{ - ModuleName: moduleName, - Instances: numberOfInstances, - Proprietary: isProprietary, - OutOfTree: isOutofTree, - Unsigned: isUnsigned, - } - result = append(result, stats) + + result = append(result, module) } return result, nil } diff --git a/pkg/util/metrics/system/module_stats_test.go b/pkg/util/metrics/system/module_stats_test.go index 717c94d0..b80f0088 100644 --- a/pkg/util/metrics/system/module_stats_test.go +++ b/pkg/util/metrics/system/module_stats_test.go @@ -21,17 +21,99 @@ import ( ) func TestModules(t *testing.T) { - modules, err := Modules() - if err != nil { - t.Errorf("error %v", err) + testcases := []struct { + name string + fakeModuleFilePath string + expectedModules []Module + }{ + { + name: "default_cos", + fakeModuleFilePath: "testdata/modules_cos.txt", + expectedModules: []Module{ + { + ModuleName: "crypto_simd", + Instances: 0x1, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + { + ModuleName: "virtio_balloon", + Instances: 0x0, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + { + ModuleName: "cryptd", + Instances: 0x1, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + { + ModuleName: "loadpin_trigger", + Instances: 0x0, + Proprietary: false, + OutOfTree: true, + Unsigned: false, + }, + }, + }, + { + name: "default_ubuntu", + fakeModuleFilePath: "testdata/modules_ubuntu.txt", + expectedModules: []Module{ + { + ModuleName: "drm", + Instances: 0x0, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + { + ModuleName: "virtio_rng", + Instances: 0x0, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + { + ModuleName: "x_tables", + Instances: 0x1, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + { + ModuleName: "autofs4", + Instances: 0x2, + Proprietary: false, + OutOfTree: false, + Unsigned: false, + }, + }, + }, } - if modules == nil { - t.Error("Error retrieving modules") + for _, test := range testcases { + t.Run(test.name, func(t *testing.T) { + originalModuleFilePath := modulesFilePath + defer func() { + modulesFilePath = originalModuleFilePath + }() + + modulesFilePath = test.fakeModuleFilePath + modules, err := Modules() + if err != nil { + t.Errorf("Unexpected error retrieving modules: %v\nModulesFilePath: %s\n", err, modulesFilePath) + } + assert.Equal(t, modules, test.expectedModules, "unpected modules retrieved: %v, expected: %v", modules, test.expectedModules) + }) } } func TestModuleStat_String(t *testing.T) { - v := ModuleStat{ + v := Module{ ModuleName: "test", Instances: 2, OutOfTree: false, @@ -39,6 +121,6 @@ func TestModuleStat_String(t *testing.T) { } e := `{"moduleName":"test","instances":2,"proprietary":false,"outOfTree":false,"unsigned":false}` assert.Equal(t, - e, fmt.Sprintf("%v", v), "ModuleStat string is invalid: %v", v) + e, fmt.Sprintf("%v", v), "Module string is invalid: %v", v) } diff --git a/pkg/util/metrics/system/testdata/modules_cos.txt b/pkg/util/metrics/system/testdata/modules_cos.txt new file mode 100644 index 00000000..535ce478 --- /dev/null +++ b/pkg/util/metrics/system/testdata/modules_cos.txt @@ -0,0 +1,4 @@ +crypto_simd 16384 1 aesni_intel, Live 0x0000000000000000 +virtio_balloon 24576 0 - Live 0x0000000000000000 +cryptd 24576 1 crypto_simd, Live 0x0000000000000000 +loadpin_trigger 12288 0 [permanent], Live 0x0000000000000000 (O) \ No newline at end of file diff --git a/pkg/util/metrics/system/testdata/modules_ubuntu.txt b/pkg/util/metrics/system/testdata/modules_ubuntu.txt new file mode 100644 index 00000000..de05e3a7 --- /dev/null +++ b/pkg/util/metrics/system/testdata/modules_ubuntu.txt @@ -0,0 +1,4 @@ +drm 491520 0 - Live 0x0000000000000000 +virtio_rng 16384 0 - Live 0x0000000000000000 +x_tables 40960 1 ip_tables, Live 0x0000000000000000 +autofs4 45056 2 - Live 0x0000000000000000 \ No newline at end of file