mirror of
https://github.com/kubernetes/node-problem-detector.git
synced 2026-08-19 04:06:24 +00:00
add testcases for cos and ubuntu to retrieve modules
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user