From 1b7a8a7899f8133b1f916632e601f78619204e6c Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 2 Mar 2023 16:19:12 -0500 Subject: [PATCH 1/3] Fix segfault in disk space check --- CHANGELOG.md | 6 ++++++ pkg/checks/disk/space.go | 30 +++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f92f62..1fa8a06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Added a progress indicator for the running checks. [conjurinc/conjur-preflight#24](https://github.com/conjurinc/conjur-preflight/pull/24) +### Fixed +- Previously, if the user running `conjur-preflight` has insufficient permission + to access a partition mountpoint, then the check would result in a segfault. + Now, this logs a warning and skips the mountpoint in the report. + [conjurinc/conjur-preflight#28](https://github.com/conjurinc/conjur-preflight/pull/28) + ## [0.2.0] - 2023-01-20 ### Added diff --git a/pkg/checks/disk/space.go b/pkg/checks/disk/space.go index aa2f7eb..66238f1 100644 --- a/pkg/checks/disk/space.go +++ b/pkg/checks/disk/space.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/conjurinc/conjur-preflight/pkg/log" "github.com/dustin/go-humanize" "github.com/shirou/gopsutil/v3/disk" ) @@ -19,15 +20,38 @@ func (*SpaceCheck) Describe() string { } // Run executes the disk checks and returns their results -func (*SpaceCheck) Run() <-chan []framework.CheckResult { +func (spaceCheck *SpaceCheck) Run() <-chan []framework.CheckResult { future := make(chan []framework.CheckResult) go func() { - partitions, _ := disk.Partitions(true) + partitions, err := disk.Partitions(true) + // If we can't list the partitions, we exit early with the failure message + if err != nil { + log.Debug("Unable to list disk partitions: %s", err) + future <- []framework.CheckResult{ + { + Title: "Error", + Status: framework.STATUS_ERROR, + Value: fmt.Sprintf("%s", err), + }, + } + + return + } + results := []framework.CheckResult{} for _, partition := range partitions { - usage, _ := disk.Usage(partition.Mountpoint) + usage, err := disk.Usage(partition.Mountpoint) + if err != nil { + log.Debug( + "Unable to collect disk usage for '%s': %s", + partition.Mountpoint, + err, + ) + continue + } + if usage.Total == 0 { continue } From 94bfabb9f5d0d99d91d8b0559e58d82ea2274dd5 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 6 Mar 2023 14:04:46 -0500 Subject: [PATCH 2/3] Add tests for space check failure scenarios --- pkg/checks/disk/space.go | 13 +++++++++-- pkg/checks/disk/space_test.go | 41 ++++++++++++++++++++++++++++++++--- pkg/report/default.go | 2 +- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/pkg/checks/disk/space.go b/pkg/checks/disk/space.go index 66238f1..e6e46a7 100644 --- a/pkg/checks/disk/space.go +++ b/pkg/checks/disk/space.go @@ -12,6 +12,15 @@ import ( // SpaceCheck reports on the available partitions and devices on the current // machine, as well as their available disk space. type SpaceCheck struct { + partitionsFunc func(all bool) ([]disk.PartitionStat, error) + usageFunc func(path string) (*disk.UsageStat, error) +} + +func NewSpaceCheck() *SpaceCheck { + return &SpaceCheck{ + partitionsFunc: disk.Partitions, + usageFunc: disk.Usage, + } } // Describe provides a textual description of what this check gathers info on @@ -24,7 +33,7 @@ func (spaceCheck *SpaceCheck) Run() <-chan []framework.CheckResult { future := make(chan []framework.CheckResult) go func() { - partitions, err := disk.Partitions(true) + partitions, err := spaceCheck.partitionsFunc(true) // If we can't list the partitions, we exit early with the failure message if err != nil { log.Debug("Unable to list disk partitions: %s", err) @@ -42,7 +51,7 @@ func (spaceCheck *SpaceCheck) Run() <-chan []framework.CheckResult { results := []framework.CheckResult{} for _, partition := range partitions { - usage, err := disk.Usage(partition.Mountpoint) + usage, err := spaceCheck.usageFunc(partition.Mountpoint) if err != nil { log.Debug( "Unable to collect disk usage for '%s': %s", diff --git a/pkg/checks/disk/space_test.go b/pkg/checks/disk/space_test.go index 8ddc35e..9649f12 100644 --- a/pkg/checks/disk/space_test.go +++ b/pkg/checks/disk/space_test.go @@ -1,16 +1,17 @@ -package disk_test +package disk import ( + "errors" "regexp" "testing" - "github.com/conjurinc/conjur-preflight/pkg/checks/disk" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/shirou/gopsutil/v3/disk" "github.com/stretchr/testify/assert" ) func TestSpaceCheck(t *testing.T) { - testCheck := &disk.SpaceCheck{} + testCheck := NewSpaceCheck() resultChan := testCheck.Run() results := <-resultChan @@ -32,3 +33,37 @@ func TestSpaceCheck(t *testing.T) { ) } } + +func TestPartitionListError(t *testing.T) { + testCheck := &SpaceCheck{ + partitionsFunc: failedPartitionsFunc, + usageFunc: disk.Usage, + } + resultChan := testCheck.Run() + results := <-resultChan + + assert.Len(t, results, 1) + + errResult := results[0] + assert.Equal(t, "Error", errResult.Title) + assert.Equal(t, "test partitions failure", errResult.Value) +} + +func TestDiskUsageError(t *testing.T) { + testCheck := &SpaceCheck{ + partitionsFunc: disk.Partitions, + usageFunc: failedUsageFunc, + } + resultChan := testCheck.Run() + results := <-resultChan + + assert.Empty(t, results) +} + +func failedPartitionsFunc(all bool) ([]disk.PartitionStat, error) { + return nil, errors.New("test partitions failure") +} + +func failedUsageFunc(path string) (*disk.UsageStat, error) { + return nil, errors.New("test usage failure") +} diff --git a/pkg/report/default.go b/pkg/report/default.go index c87f2e7..7ca88e6 100644 --- a/pkg/report/default.go +++ b/pkg/report/default.go @@ -21,7 +21,7 @@ func NewDefaultReport(debug bool) *Report { { Title: "Disk", Checks: []framework.Check{ - &disk.SpaceCheck{}, + disk.NewSpaceCheck(), disk.NewIopsCheck(debug), disk.NewLatencyCheck(debug), }, From de9c006d4a2b44ce6f06134f2aff461c888d9f3c Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 6 Mar 2023 14:03:03 -0500 Subject: [PATCH 3/3] Fix other unhandled error cases --- pkg/checks/cpu.go | 5 ++- pkg/checks/cpu_test.go | 5 ++- pkg/checks/disk/iops.go | 14 ++++++-- pkg/checks/disk/iops_test.go | 26 +++++++++++++++ pkg/checks/disk/latency.go | 20 +++++++++--- pkg/checks/disk/latency_test.go | 26 +++++++++++++++ pkg/checks/disk/space.go | 21 +++++------- pkg/checks/disk/space_test.go | 26 ++++++++++----- pkg/checks/follower_test.go | 5 ++- pkg/checks/host.go | 27 ++++++++++++--- pkg/checks/host_test.go | 58 +++++++++++++++++++++++++++++++-- pkg/checks/memory.go | 22 +++++++++++-- pkg/checks/memory_test.go | 30 +++++++++++++++-- pkg/report/default.go | 2 +- 14 files changed, 237 insertions(+), 50 deletions(-) diff --git a/pkg/checks/cpu.go b/pkg/checks/cpu.go index 492ac60..c4a4eb2 100644 --- a/pkg/checks/cpu.go +++ b/pkg/checks/cpu.go @@ -7,14 +7,17 @@ import ( "github.com/conjurinc/conjur-preflight/pkg/framework" ) +// Cpu collects inspection information on the host machines CPU cores and +// architecture type Cpu struct { } -// Describe provides a textual description of what this check gathers info on +// Describe provides a textual description of the info this check gathers func (*Cpu) Describe() string { return "CPU" } +// Run executes the CPU inspection checks func (cpu *Cpu) Run() <-chan []framework.CheckResult { future := make(chan []framework.CheckResult) diff --git a/pkg/checks/cpu_test.go b/pkg/checks/cpu_test.go index e5f9386..9d65bfa 100644 --- a/pkg/checks/cpu_test.go +++ b/pkg/checks/cpu_test.go @@ -1,16 +1,15 @@ -package checks_test +package checks import ( "regexp" "testing" - "github.com/conjurinc/conjur-preflight/pkg/checks" "github.com/conjurinc/conjur-preflight/pkg/framework" "github.com/stretchr/testify/assert" ) func TestCpuRun(t *testing.T) { - testCheck := &checks.Cpu{} + testCheck := &Cpu{} resultChan := testCheck.Run() results := <-resultChan diff --git a/pkg/checks/disk/iops.go b/pkg/checks/disk/iops.go index 52a7fde..612b566 100644 --- a/pkg/checks/disk/iops.go +++ b/pkg/checks/disk/iops.go @@ -23,6 +23,8 @@ type IopsCheck struct { fioNewJob func(string, []string) fio.Executable } +var getWorkingDirectory func() (string, error) = os.Getwd + // NewIopsCheck instantiates an Iops check with the default dependencies func NewIopsCheck(debug bool) *IopsCheck { return &IopsCheck{ @@ -91,7 +93,11 @@ func fioReadIopsResult(job *fio.JobResult) framework.CheckResult { } // Format title - path, _ := os.Getwd() + path, err := getWorkingDirectory() + if err != nil { + log.Debug("Unable to get working directory: %s", err) + path = "working directory" + } titleStr := fmt.Sprintf("FIO - Read IOPs (%s)", path) // Format value @@ -119,7 +125,11 @@ func fioWriteIopsResult(job *fio.JobResult) framework.CheckResult { } // Format title - path, _ := os.Getwd() + path, err := getWorkingDirectory() + if err != nil { + log.Debug("Unable to get working directory: %s", err) + path = "working directory" + } titleStr := fmt.Sprintf("FIO - Write IOPs (%s)", path) // Format value diff --git a/pkg/checks/disk/iops_test.go b/pkg/checks/disk/iops_test.go index 3ddbd7c..e0ca99f 100644 --- a/pkg/checks/disk/iops_test.go +++ b/pkg/checks/disk/iops_test.go @@ -94,6 +94,32 @@ func TestIopsWithNoJobs(t *testing.T) { assert.Equal(t, "No job results returned by 'fio'", results[0].Message) } +func TestIopsWithWorkingDirectoryError(t *testing.T) { + // Double the working directory function to simulate it failing with an error + originalWorkingDirectoryFunc := getWorkingDirectory + getWorkingDirectory = failedWorkingDir + defer func() { + getWorkingDirectory = originalWorkingDirectoryFunc + }() + + testCheck := &IopsCheck{ + debug: true, + fioNewJob: newSuccessfulIopsFioJob, + } + resultChan := testCheck.Run() + results := <-resultChan + + assert.Equal( + t, + 2, + len(results), + "There are read and write IOPs results present", + ) + + assertReadIopsResult(t, results[0], framework.STATUS_INFO) + assertWriteIopsResult(t, results[1], framework.STATUS_INFO) +} + func assertReadIopsResult( t *testing.T, result framework.CheckResult, diff --git a/pkg/checks/disk/latency.go b/pkg/checks/disk/latency.go index f08ece6..aad7cc9 100644 --- a/pkg/checks/disk/latency.go +++ b/pkg/checks/disk/latency.go @@ -2,10 +2,10 @@ package disk import ( "fmt" - "os" "github.com/conjurinc/conjur-preflight/pkg/checks/disk/fio" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/conjurinc/conjur-preflight/pkg/log" ) // LatencyCheck is a pre-flight check to report the read, write, and sync @@ -90,7 +90,11 @@ func fioReadLatencyResult(jobResult *fio.JobResult) framework.CheckResult { status = framework.STATUS_WARN } - path, _ := os.Getwd() + path, err := getWorkingDirectory() + if err != nil { + log.Debug("Unable to get working directory: %s", err) + path = "working directory" + } return framework.CheckResult{ Title: fmt.Sprintf("FIO - Read Latency (99%%, %s)", path), @@ -110,7 +114,11 @@ func fioWriteLatencyResult(jobResult *fio.JobResult) framework.CheckResult { status = framework.STATUS_WARN } - path, _ := os.Getwd() + path, err := getWorkingDirectory() + if err != nil { + log.Debug("Unable to get working directory: %s", err) + path = "working directory" + } return framework.CheckResult{ Title: fmt.Sprintf("FIO - Write Latency (99%%, %s)", path), @@ -130,7 +138,11 @@ func fioSyncLatencyResult(jobResult *fio.JobResult) framework.CheckResult { status = framework.STATUS_WARN } - path, _ := os.Getwd() + path, err := getWorkingDirectory() + if err != nil { + log.Debug("Unable to get working directory: %s", err) + path = "working directory" + } return framework.CheckResult{ Title: fmt.Sprintf("FIO - Sync Latency (99%%, %s)", path), diff --git a/pkg/checks/disk/latency_test.go b/pkg/checks/disk/latency_test.go index d6a3b48..6ae0937 100644 --- a/pkg/checks/disk/latency_test.go +++ b/pkg/checks/disk/latency_test.go @@ -3,6 +3,7 @@ package disk import ( + "errors" "regexp" "testing" @@ -71,6 +72,27 @@ func TestLatencyWithNoJobs(t *testing.T) { assert.Equal(t, "No job results returned by 'fio'", results[0].Message) } +func TestLatencyWithWorkingDirectoryError(t *testing.T) { + // Double the working directory function to simulate it failing with an error + originalWorkingDirectoryFunc := getWorkingDirectory + getWorkingDirectory = failedWorkingDir + defer func() { + getWorkingDirectory = originalWorkingDirectoryFunc + }() + + testCheck := &LatencyCheck{ + fioNewJob: newSuccessfulLatencyFioJob, + } + resultChan := testCheck.Run() + results := <-resultChan + + assert.Equal(t, 3, len(results), "There are disk latency results present") + + assertReadLatencyResult(t, results[0], framework.STATUS_INFO) + assertWriteLatencyResult(t, results[1], framework.STATUS_INFO) + assertSyncLatencyResult(t, results[2], framework.STATUS_INFO) +} + func assertReadLatencyResult( t *testing.T, result framework.CheckResult, @@ -187,3 +209,7 @@ func newPoorLatencyPerformanceFioJob( }, } } + +func failedWorkingDir() (string, error) { + return "", errors.New("working directory error") +} diff --git a/pkg/checks/disk/space.go b/pkg/checks/disk/space.go index e6e46a7..3f8cd4e 100644 --- a/pkg/checks/disk/space.go +++ b/pkg/checks/disk/space.go @@ -9,19 +9,14 @@ import ( "github.com/shirou/gopsutil/v3/disk" ) +// Aliasing our external dependencies like this allows to swap them out for +// testing +var getPartitions func(all bool) ([]disk.PartitionStat, error) = disk.Partitions +var getUsage func(path string) (*disk.UsageStat, error) = disk.Usage + // SpaceCheck reports on the available partitions and devices on the current // machine, as well as their available disk space. -type SpaceCheck struct { - partitionsFunc func(all bool) ([]disk.PartitionStat, error) - usageFunc func(path string) (*disk.UsageStat, error) -} - -func NewSpaceCheck() *SpaceCheck { - return &SpaceCheck{ - partitionsFunc: disk.Partitions, - usageFunc: disk.Usage, - } -} +type SpaceCheck struct{} // Describe provides a textual description of what this check gathers info on func (*SpaceCheck) Describe() string { @@ -33,7 +28,7 @@ func (spaceCheck *SpaceCheck) Run() <-chan []framework.CheckResult { future := make(chan []framework.CheckResult) go func() { - partitions, err := spaceCheck.partitionsFunc(true) + partitions, err := getPartitions(true) // If we can't list the partitions, we exit early with the failure message if err != nil { log.Debug("Unable to list disk partitions: %s", err) @@ -51,7 +46,7 @@ func (spaceCheck *SpaceCheck) Run() <-chan []framework.CheckResult { results := []framework.CheckResult{} for _, partition := range partitions { - usage, err := spaceCheck.usageFunc(partition.Mountpoint) + usage, err := getUsage(partition.Mountpoint) if err != nil { log.Debug( "Unable to collect disk usage for '%s': %s", diff --git a/pkg/checks/disk/space_test.go b/pkg/checks/disk/space_test.go index 9649f12..8fc90af 100644 --- a/pkg/checks/disk/space_test.go +++ b/pkg/checks/disk/space_test.go @@ -11,7 +11,7 @@ import ( ) func TestSpaceCheck(t *testing.T) { - testCheck := NewSpaceCheck() + testCheck := &SpaceCheck{} resultChan := testCheck.Run() results := <-resultChan @@ -35,10 +35,14 @@ func TestSpaceCheck(t *testing.T) { } func TestPartitionListError(t *testing.T) { - testCheck := &SpaceCheck{ - partitionsFunc: failedPartitionsFunc, - usageFunc: disk.Usage, - } + // Double the usage function to simulate an error + originalPartitionsFunc := getPartitions + getPartitions = failedPartitionsFunc + defer func() { + getPartitions = originalPartitionsFunc + }() + + testCheck := &SpaceCheck{} resultChan := testCheck.Run() results := <-resultChan @@ -50,10 +54,14 @@ func TestPartitionListError(t *testing.T) { } func TestDiskUsageError(t *testing.T) { - testCheck := &SpaceCheck{ - partitionsFunc: disk.Partitions, - usageFunc: failedUsageFunc, - } + // Double the usage function to simulate an error + originalUsageFunc := getUsage + getUsage = failedUsageFunc + defer func() { + getUsage = originalUsageFunc + }() + + testCheck := &SpaceCheck{} resultChan := testCheck.Run() results := <-resultChan diff --git a/pkg/checks/follower_test.go b/pkg/checks/follower_test.go index 63e26fb..41081ee 100644 --- a/pkg/checks/follower_test.go +++ b/pkg/checks/follower_test.go @@ -1,15 +1,14 @@ -package checks_test +package checks import ( "testing" - "github.com/conjurinc/conjur-preflight/pkg/checks" "github.com/stretchr/testify/assert" ) func TestFollowerRun(t *testing.T) { t.Setenv("MASTER_HOSTNAME", "http://example.com") - testCheck := &checks.Follower{} + testCheck := &Follower{} resultChan := testCheck.Run() results := <-resultChan diff --git a/pkg/checks/host.go b/pkg/checks/host.go index 33aa16d..c06cb5e 100644 --- a/pkg/checks/host.go +++ b/pkg/checks/host.go @@ -5,23 +5,40 @@ import ( "time" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/conjurinc/conjur-preflight/pkg/log" "github.com/hako/durafmt" "github.com/shirou/gopsutil/v3/host" ) -type Host struct { -} +var getHostInfo func() (*host.InfoStat, error) = host.Info + +// Host collects inspection information on the host machine's metadata, such +// as the operating system +type Host struct{} -// Describe provides a textual description of what this check gathers info on +// Describe provides a textual description of what this check gathers func (*Host) Describe() string { return "operating system" } -func (*Host) Run() <-chan []framework.CheckResult { +// Run executes the Host inspection checks +func (host *Host) Run() <-chan []framework.CheckResult { future := make(chan []framework.CheckResult) go func() { - hostInfo, _ := host.Info() + hostInfo, err := getHostInfo() + if err != nil { + log.Debug("Unable to inspect host info: %s", err) + future <- []framework.CheckResult{ + { + Title: "Error", + Status: framework.STATUS_ERROR, + Value: fmt.Sprintf("%s", err), + }, + } + + return + } future <- []framework.CheckResult{ hostnameResult(hostInfo), diff --git a/pkg/checks/host_test.go b/pkg/checks/host_test.go index ce470b7..5041de9 100644 --- a/pkg/checks/host_test.go +++ b/pkg/checks/host_test.go @@ -1,16 +1,17 @@ -package checks_test +package checks import ( + "errors" "testing" - "github.com/conjurinc/conjur-preflight/pkg/checks" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/shirou/gopsutil/v3/host" "github.com/stretchr/testify/assert" "golang.org/x/exp/slices" ) func TestHostRun(t *testing.T) { - testCheck := &checks.Host{} + testCheck := &Host{} resultChan := testCheck.Run() results := <-resultChan @@ -35,6 +36,57 @@ func TestHostRun(t *testing.T) { assert.NotEmpty(t, virtualization.Value) } +func TestHostRunError(t *testing.T) { + // Double the host info function to simulate an error + originalHostInfo := getHostInfo + getHostInfo = failedHostInfoFunc + defer func() { + getHostInfo = originalHostInfo + }() + + testCheck := &Host{} + resultChan := testCheck.Run() + results := <-resultChan + + errResult := results[0] + assert.Equal(t, "Error", errResult.Title) + assert.Equal(t, "test host failure", errResult.Value) +} + +func TestHostRunNoVirtualization(t *testing.T) { + // Double the host info function to simulate no virtualization + originalHostInfo := getHostInfo + getHostInfo = noVirtualizationHostInfoFunc + defer func() { + getHostInfo = originalHostInfo + }() + + testCheck := &Host{} + resultChan := testCheck.Run() + results := <-resultChan + + virtualization := GetResultByTitle(results, "Virtualization") + assert.NotNil(t, virtualization) + assert.Equal(t, framework.STATUS_INFO, virtualization.Status) + assert.NotEmpty(t, "None") +} + +func failedHostInfoFunc() (*host.InfoStat, error) { + return nil, errors.New("test host failure") +} + +func noVirtualizationHostInfoFunc() (*host.InfoStat, error) { + original, err := host.Info() + // We assume this will work on a test host. If not, abort the test run. + if err != nil { + panic(err) + } + + original.VirtualizationSystem = "" + + return original, nil +} + func GetResultByTitle( results []framework.CheckResult, title string, diff --git a/pkg/checks/memory.go b/pkg/checks/memory.go index 92118b6..1b31a79 100644 --- a/pkg/checks/memory.go +++ b/pkg/checks/memory.go @@ -4,24 +4,40 @@ import ( "fmt" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/conjurinc/conjur-preflight/pkg/log" "github.com/dustin/go-humanize" "github.com/shirou/gopsutil/v3/mem" ) -type Memory struct { -} +var getVirtualMemory func() (*mem.VirtualMemoryStat, error) = mem.VirtualMemory + +// Memory collects inspection information on the host machine's memory +// availability and usage +type Memory struct{} // Describe provides a textual description of what this check gathers info on func (*Memory) Describe() string { return "memory" } +// Run executes the Memory inspection checks func (memory *Memory) Run() <-chan []framework.CheckResult { future := make(chan []framework.CheckResult) go func() { + v, err := getVirtualMemory() + if err != nil { + log.Debug("Unable to inspect memory: %s", err) + future <- []framework.CheckResult{ + { + Title: "Error", + Status: framework.STATUS_ERROR, + Value: fmt.Sprintf("%s", err), + }, + } - v, _ := mem.VirtualMemory() + return + } future <- []framework.CheckResult{ { diff --git a/pkg/checks/memory_test.go b/pkg/checks/memory_test.go index 813d821..9c22824 100644 --- a/pkg/checks/memory_test.go +++ b/pkg/checks/memory_test.go @@ -1,15 +1,16 @@ -package checks_test +package checks import ( + "errors" "testing" - "github.com/conjurinc/conjur-preflight/pkg/checks" "github.com/conjurinc/conjur-preflight/pkg/framework" + "github.com/shirou/gopsutil/v3/mem" "github.com/stretchr/testify/assert" ) func TestMemoryRun(t *testing.T) { - testCheck := &checks.Memory{} + testCheck := &Memory{} resultChan := testCheck.Run() results := <-resultChan @@ -28,3 +29,26 @@ func TestMemoryRun(t *testing.T) { assert.Equal(t, framework.STATUS_INFO, memoryUsed.Status) assert.NotEmpty(t, memoryUsed.Value) } + +func TestMemoryRunError(t *testing.T) { + // Double the virtual memory function to simulate an error + originalVirtualMemory := getVirtualMemory + getVirtualMemory = failedVirtualMemoryFunc + defer func() { + getVirtualMemory = originalVirtualMemory + }() + + testCheck := &Memory{} + resultChan := testCheck.Run() + results := <-resultChan + + assert.Len(t, results, 1) + + errResult := results[0] + assert.Equal(t, "Error", errResult.Title) + assert.Equal(t, "test virtual memory failure", errResult.Value) +} + +func failedVirtualMemoryFunc() (*mem.VirtualMemoryStat, error) { + return nil, errors.New("test virtual memory failure") +} diff --git a/pkg/report/default.go b/pkg/report/default.go index 7ca88e6..c87f2e7 100644 --- a/pkg/report/default.go +++ b/pkg/report/default.go @@ -21,7 +21,7 @@ func NewDefaultReport(debug bool) *Report { { Title: "Disk", Checks: []framework.Check{ - disk.NewSpaceCheck(), + &disk.SpaceCheck{}, disk.NewIopsCheck(debug), disk.NewLatencyCheck(debug), },