add testcases for cos and ubuntu to retrieve modules

This commit is contained in:
varsha teratipally
2020-11-19 10:29:12 +00:00
parent 944efce3a6
commit 2b50e4af1a
5 changed files with 117 additions and 31 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ import (
) )
// ReadFile reads contents from a file and returns lines. // 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) file, err := os.Open(filename)
if err != nil { if err != nil {
return nil, err return nil, err
+19 -23
View File
@@ -20,7 +20,9 @@ import (
"strings" "strings"
) )
type ModuleStat struct { var modulesFilePath = "/proc/modules"
type Module struct {
ModuleName string `json:"moduleName"` ModuleName string `json:"moduleName"`
Instances uint64 `json:"instances"` Instances uint64 `json:"instances"`
Proprietary bool `json:"proprietary"` Proprietary bool `json:"proprietary"`
@@ -28,20 +30,19 @@ type ModuleStat struct {
Unsigned bool `json:"unsigned"` Unsigned bool `json:"unsigned"`
} }
func (d ModuleStat) String() string { func (d Module) String() string {
s, _ := json.Marshal(d) s, _ := json.Marshal(d)
return string(s) return string(s)
} }
// Module returns all the kernel modules and their // Module returns all the kernel modules and their
// usage. It is read from cat /proc/modules. // usage. It is read from cat /proc/modules.
func Modules() ([]ModuleStat, error) { func Modules() ([]Module, error) {
filename := "/proc/modules" lines, err := ReadFileIntoLines(modulesFilePath)
lines, err := ReadFile(filename)
if err != nil { 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 /* a line of /proc/modules has the following structure
nf_nat 61440 2 xt_MASQUERADE,iptable_nat, Live 0x0000000000000000 (O) nf_nat 61440 2 xt_MASQUERADE,iptable_nat, Live 0x0000000000000000 (O)
@@ -58,28 +59,23 @@ func Modules() ([]ModuleStat, error) {
fields := strings.Fields(line) fields := strings.Fields(line)
moduleName := fields[0] // name of the module moduleName := fields[0] // name of the module
numberOfInstances, err := 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 { if err != nil {
return nil, err numberOfInstances = 0
} }
var isProprietary = false var module = Module{
var isOutofTree = false ModuleName: moduleName,
var isUnsigned = false Instances: numberOfInstances,
}
// if the len of the fields is greater than 6, then the kernel taint state is available. // if the len of the fields is greater than 6, then the kernel taint state is available.
if len(fields) > 6 { if len(fields) > 6 {
isProprietary = strings.Contains(fields[6], "P") module.Proprietary = strings.Contains(fields[6], "P")
isOutofTree = strings.Contains(fields[6], "O") module.OutOfTree = strings.Contains(fields[6], "O")
isUnsigned = strings.Contains(fields[6], "E") module.Unsigned = strings.Contains(fields[6], "E")
} }
var stats = ModuleStat{
ModuleName: moduleName, result = append(result, module)
Instances: numberOfInstances,
Proprietary: isProprietary,
OutOfTree: isOutofTree,
Unsigned: isUnsigned,
}
result = append(result, stats)
} }
return result, nil return result, nil
} }
+89 -7
View File
@@ -21,17 +21,99 @@ import (
) )
func TestModules(t *testing.T) { func TestModules(t *testing.T) {
modules, err := Modules() testcases := []struct {
if err != nil { name string
t.Errorf("error %v", err) 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 { for _, test := range testcases {
t.Error("Error retrieving modules") 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) { func TestModuleStat_String(t *testing.T) {
v := ModuleStat{ v := Module{
ModuleName: "test", ModuleName: "test",
Instances: 2, Instances: 2,
OutOfTree: false, OutOfTree: false,
@@ -39,6 +121,6 @@ func TestModuleStat_String(t *testing.T) {
} }
e := `{"moduleName":"test","instances":2,"proprietary":false,"outOfTree":false,"unsigned":false}` e := `{"moduleName":"test","instances":2,"proprietary":false,"outOfTree":false,"unsigned":false}`
assert.Equal(t, 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)
} }
+4
View File
@@ -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)
+4
View File
@@ -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