Skip to content

Commit

Permalink
Merge pull request #20 from mackerelio/support-as-status
Browse files Browse the repository at this point in the history
overwrite status.
  • Loading branch information
yseto authored Oct 3, 2023
2 parents 505df3f + 72e28ed commit 1fd6e2d
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 4 deletions.
63 changes: 63 additions & 0 deletions asstatusparse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package checkers

import "strings"

type invalidStatusMapError string

func (err invalidStatusMapError) Error() string {
return "invalid status map: " + string(err)
}

type duplicateStatusMapError Status

func (err duplicateStatusMapError) Error() string {
return "duplicate status in map: " + Status(err).String()
}

func parseStatusPrefix(src string) (Status, string, bool) {
switch {
case strings.HasPrefix(src, "OK"):
return OK, src[len("OK"):], true
case strings.HasPrefix(src, "WARNING"):
return WARNING, src[len("WARNING"):], true
case strings.HasPrefix(src, "CRITICAL"):
return CRITICAL, src[len("CRITICAL"):], true
case strings.HasPrefix(src, "UNKNOWN"):
return UNKNOWN, src[len("UNKNOWN"):], true
default:
return OK, src, false
}
}

// Parse parses a string of the form <status>=<status>. <status> is one of:
//
// - ok
// - warning
// - critical
// - unknown
//
// You can specify multiple key-value pairs separated by commas.
func Parse(src string) (map[Status]Status, error) {
orig, stm := src, map[Status]Status{}
for src = strings.ToUpper(src); src != ""; {
var from, to Status
var ok bool
if from, src, ok = parseStatusPrefix(src); !ok {
return nil, invalidStatusMapError(orig)
}
if src, ok = strings.CutPrefix(src, "="); !ok {
return nil, invalidStatusMapError(orig)
}
if to, src, ok = parseStatusPrefix(src); !ok {
return nil, invalidStatusMapError(orig)
}
if src, ok = strings.CutPrefix(src, ","); ok == (src == "") {
return nil, invalidStatusMapError(orig)
}
if _, ok = stm[from]; ok {
return nil, duplicateStatusMapError(from)
}
stm[from] = to
}
return stm, nil
}
85 changes: 85 additions & 0 deletions asstatusparse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package checkers

import (
"reflect"
"testing"
)

func TestParse(t *testing.T) {
tests := []struct {
name string
source string
expected map[Status]Status
wantErr bool
}{
{
name: "normal",
source: "unknown=critical",
expected: map[Status]Status{
UNKNOWN: CRITICAL,
},
},
{
name: "uppercase",
source: "UNKNOWN=CRITICAL",
expected: map[Status]Status{
UNKNOWN: CRITICAL,
},
},
{
name: "multi",
source: "unknown=ok,warning=critical",
expected: map[Status]Status{
UNKNOWN: OK,
WARNING: CRITICAL,
},
},
{
name: "from error",
source: "invalid=critical",
wantErr: true,
},
{
name: "= error",
source: "unknown critical",
wantErr: true,
},
{
name: "to error",
source: "critical=invalid",
wantErr: true,
},
{
name: "argument error",
source: "unknown=critical=invalid",
wantErr: true,
},
{
name: "missing comma error",
source: "unknown=criticalwarning=critical",
wantErr: true,
},
{
name: "trailing comma error",
source: "unknown=ok,",
wantErr: true,
},
{
name: "duplicate error",
source: "critical=unknown,critical=warning",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual, err := Parse(tt.source)
if (err != nil) != tt.wantErr {
t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(tt.expected, actual) {
t.Errorf("Parse() should be %+v but got: %+v", tt.expected, actual)
}
})
}
}
15 changes: 12 additions & 3 deletions checkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ const (

func (st Status) String() string {
switch st {
case 0:
case OK:
return "OK"
case 1:
case WARNING:
return "WARNING"
case 2:
case CRITICAL:
return "CRITICAL"
default:
return "UNKNOWN"
Expand Down Expand Up @@ -53,6 +53,15 @@ func (ckr *Checker) Exit() {
exit(int(ckr.Status))
}

func (ckr *Checker) ExitStatusAs(maps map[Status]Status) {
if _, ok := maps[ckr.Status]; ok {
ckr.Status = maps[ckr.Status]
}

fmt.Println(ckr.String())
exit(int(ckr.Status))
}

func (ckr *Checker) String() string {
return fmt.Sprintf("%s %s: %s", ckr.Name, ckr.Status, ckr.Message)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/mackerelio/checkers

go 1.18
go 1.20
Empty file removed go.sum
Empty file.

0 comments on commit 1fd6e2d

Please sign in to comment.