diff --git a/.gitignore b/.gitignore index 773e32b..6c1c4b8 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ httpmock-record.yml # Output of the go coverage tool, specifically when used with LiteIDE *.out +coverage.html \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 2d46592..468bf19 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -18,6 +18,7 @@ linters: - deadcode - structcheck - varcheck + - musttag presets: - bugs - unused diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..241ba61 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +.PHONY: test coverage lint vet + +build: + go build +lint: + go fmt $(go list ./... | grep -v /vendor/) +vet: + go vet $(go list ./... | grep -v /vendor/) +test: + go test -v -cover ./... +coverage: + go test -v -cover -coverprofile=coverage.out ./... &&\ + go tool cover -html=coverage.out -o coverage.html diff --git a/exit.go b/exit.go index db6b081..777f092 100644 --- a/exit.go +++ b/exit.go @@ -2,11 +2,11 @@ package check import ( "fmt" + "github.com/mitchellh/go-ps" "os" "runtime/debug" "strconv" - - "github.com/mitchellh/go-ps" + "strings" ) // AllowExit lets you disable the call to os.Exit() in ExitXxx() functions of this package. @@ -29,17 +29,20 @@ func Exitf(rc int, output string, args ...interface{}) { // ExitRaw prints the plugin output with the state prefixed and exits the program. // // Example: +// // OK - everything is fine func ExitRaw(rc int, output ...string) { - text := StatusText(rc) + " -" + var text strings.Builder + + text.WriteString(StatusText(rc) + " -") for _, s := range output { - text += " " + s + text.WriteString(" " + s) } - text += "\n" + text.WriteString("\n") - _, _ = os.Stdout.WriteString(text) + _, _ = os.Stdout.WriteString(text.String()) BaseExit(rc) } diff --git a/perfdata/list.go b/perfdata/list.go index 9f22e5c..de5d4f1 100644 --- a/perfdata/list.go +++ b/perfdata/list.go @@ -1,19 +1,25 @@ package perfdata +import ( + "strings" +) + // PerfdataList can store multiple perfdata and brings a simple fmt.Stringer interface type PerfdataList []*Perfdata // String returns string representations of all Perfdata -func (l PerfdataList) String() (s string) { +func (l PerfdataList) String() string { + var out strings.Builder + for _, p := range l { - if len(s) > 0 { - s += " " + if len(out.String()) > 0 { + out.WriteString(" ") } - s += p.String() + out.WriteString(p.String()) } - return + return out.String() } // Add a Perfdata to the list diff --git a/perfdata/type.go b/perfdata/type.go index 52dac34..9ce2ad0 100644 --- a/perfdata/type.go +++ b/perfdata/type.go @@ -28,30 +28,31 @@ type Perfdata struct { } // String returns the proper format for the plugin output -func (p Perfdata) String() (s string) { - s = FormatLabel(p.Label) + "=" +func (p Perfdata) String() string { + var sb strings.Builder - s += FormatNumeric(p.Value) - s += p.Uom + sb.WriteString(FormatLabel(p.Label) + "=") + + sb.WriteString(FormatNumeric(p.Value)) + sb.WriteString(p.Uom) // Thresholds for _, value := range []*check.Threshold{p.Warn, p.Crit} { - s += ";" + sb.WriteString(";") + if value != nil { - s += value.String() + sb.WriteString(value.String()) } } // Limits for _, value := range []interface{}{p.Min, p.Max} { - s += ";" + sb.WriteString(";") + if value != nil { - s += FormatNumeric(value) + sb.WriteString(FormatNumeric(value)) } } - // Remove trailing semicolons - s = strings.TrimRight(s, ";") - - return + return strings.TrimRight(sb.String(), ";") } diff --git a/result/overall.go b/result/overall.go index f697eb4..87ca639 100644 --- a/result/overall.go +++ b/result/overall.go @@ -98,89 +98,102 @@ func (o *Overall) GetStatus() int { } } +// nolint: funlen func (o *Overall) GetSummary() string { - if o.Summary == "" { - if o.Criticals > 0 { - o.Summary += fmt.Sprintf("critical=%d ", o.Criticals) - } + if o.Summary != "" { + return o.Summary + } - if o.Unknowns > 0 { - o.Summary += fmt.Sprintf("unknown=%d ", o.Unknowns) - } + if o.Criticals > 0 { + o.Summary += fmt.Sprintf("critical=%d ", o.Criticals) + } - if o.Warnings > 0 { - o.Summary += fmt.Sprintf("warning=%d ", o.Warnings) - } + if o.Unknowns > 0 { + o.Summary += fmt.Sprintf("unknown=%d ", o.Unknowns) + } - if o.OKs > 0 { - o.Summary += fmt.Sprintf("ok=%d ", o.OKs) - } + if o.Warnings > 0 { + o.Summary += fmt.Sprintf("warning=%d ", o.Warnings) + } - if o.Summary == "" && len(o.partialResults) == 0 { - o.Summary = "No status information" - } else { - criticals := 0 - warnings := 0 - oks := 0 - unknowns := 0 - for _, sc := range o.partialResults { - if sc.State == check.Critical { - criticals++ - } else if sc.State == check.Warning { - warnings++ - } else if sc.State == check.Unknown { - unknowns++ - } else if sc.State == check.OK { - oks++ - } - } - - if criticals > 0 { - o.Summary += fmt.Sprintf("critical=%d ", criticals) - } - if unknowns > 0 { - o.Summary += fmt.Sprintf("unknowns=%d ", unknowns) - } - if warnings > 0 { - o.Summary += fmt.Sprintf("warning=%d ", warnings) - } - if oks > 0 { - o.Summary += fmt.Sprintf("ok=%d ", oks) - } - o.Summary = "states: " + strings.TrimSpace(o.Summary) + if o.OKs > 0 { + o.Summary += fmt.Sprintf("ok=%d ", o.OKs) + } + + if o.Summary == "" && len(o.partialResults) == 0 { + o.Summary = "No status information" + return o.Summary + } + + var ( + criticals int + warnings int + oks int + unknowns int + ) + + for _, sc := range o.partialResults { + if sc.State == check.Critical { + criticals++ + } else if sc.State == check.Warning { + warnings++ + } else if sc.State == check.Unknown { + unknowns++ + } else if sc.State == check.OK { + oks++ } } + if criticals > 0 { + o.Summary += fmt.Sprintf("critical=%d ", criticals) + } + + if unknowns > 0 { + o.Summary += fmt.Sprintf("unknowns=%d ", unknowns) + } + + if warnings > 0 { + o.Summary += fmt.Sprintf("warning=%d ", warnings) + } + + if oks > 0 { + o.Summary += fmt.Sprintf("ok=%d ", oks) + } + + o.Summary = "states: " + strings.TrimSpace(o.Summary) + return o.Summary } func (o *Overall) GetOutput() string { - output := o.GetSummary() + "\n" + var output strings.Builder + + output.WriteString(o.GetSummary() + "\n") for _, extra := range o.Outputs { - output += extra + "\n" + output.WriteString(extra + "\n") } if o.partialResults != nil { for i := range o.partialResults { - output += o.partialResults[i].getOutput(0) + output.WriteString(o.partialResults[i].getOutput(0)) } } - return output + return output.String() } func (s *PartialResult) getOutput(indent_level int) string { - var output string + var output strings.Builder prefix := strings.Repeat(" ", indent_level) - output += prefix + "\\_ " + s.String() + "\n" + output.WriteString(prefix + "\\_ " + s.String() + "\n") if s.partialResults != nil { for _, ss := range s.partialResults { - output += ss.getOutput(indent_level + 2) + output.WriteString(ss.getOutput(indent_level + 2)) } } - return output + return output.String() } diff --git a/result/overall_test.go b/result/overall_test.go index f5c414c..19004dc 100644 --- a/result/overall_test.go +++ b/result/overall_test.go @@ -63,6 +63,9 @@ func TestOverall_GetStatus_GetSummary(t *testing.T) { overall = Overall{OKs: 1, Warnings: 2} assert.Equal(t, 1, overall.GetStatus()) assert.Equal(t, "states: warning=2 ok=1", overall.GetSummary()) + + overall = Overall{Summary: "foobar"} + assert.Equal(t, "foobar", overall.GetSummary()) } func TestOverall_GetOutput(t *testing.T) { diff --git a/result/worst_test.go b/result/worst_test.go index a88bb6a..51cb746 100644 --- a/result/worst_test.go +++ b/result/worst_test.go @@ -1,31 +1,22 @@ -package result_test +package result import ( - "fmt" - "github.com/NETWAYS/go-check" - "github.com/NETWAYS/go-check/result" "github.com/stretchr/testify/assert" "testing" ) func TestWorstState(t *testing.T) { - assert.Equal(t, 3, result.WorstState(3)) - assert.Equal(t, 2, result.WorstState(2)) - assert.Equal(t, 1, result.WorstState(1)) - assert.Equal(t, 0, result.WorstState(0)) - assert.Equal(t, 2, result.WorstState(0, 1, 2, 3)) - assert.Equal(t, 3, result.WorstState(0, 1, 3)) - assert.Equal(t, 1, result.WorstState(1, 0, 0)) - assert.Equal(t, 0, result.WorstState(0, 0, 0)) + assert.Equal(t, 3, WorstState(3)) + assert.Equal(t, 2, WorstState(2)) + assert.Equal(t, 1, WorstState(1)) + assert.Equal(t, 0, WorstState(0)) - assert.Equal(t, 3, result.WorstState(-1)) - assert.Equal(t, 3, result.WorstState(4)) -} + assert.Equal(t, 2, WorstState(0, 1, 2, 3)) + assert.Equal(t, 3, WorstState(0, 1, 3)) + assert.Equal(t, 1, WorstState(1, 0, 0)) + assert.Equal(t, 0, WorstState(0, 0, 0)) -func ExampleWorstState() { - state := result.WorstState(check.Unknown, check.Critical, check.OK) - fmt.Println(state) - // Output: - // 2 + assert.Equal(t, 3, WorstState(-1)) + assert.Equal(t, 3, WorstState(4)) }