From 806a74bdff6cf2f014bb93d01d84611c9ef26e04 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 1 Feb 2022 13:49:24 -0500 Subject: internal/feed: add severity, severity tests --- internal/feed/feed.go | 32 +--------------- internal/feed/severity.go | 47 +++++++++++++++++++++++ internal/feed/severity_string.go | 27 +++++++++++++ internal/feed/severity_test.go | 83 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 31 deletions(-) create mode 100644 internal/feed/severity.go create mode 100644 internal/feed/severity_string.go create mode 100644 internal/feed/severity_test.go diff --git a/internal/feed/feed.go b/internal/feed/feed.go index b8a3849..40e385d 100644 --- a/internal/feed/feed.go +++ b/internal/feed/feed.go @@ -21,36 +21,6 @@ const ( // TODO: parse cpe -// CVSS severity -type Severity int - -// Unmarshal CVSS severity from JSON. -func (me *Severity) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "LOW": - *me = Low - case "MEDIUM": - *me = Medium - case "HIGH": - *me = High - case "CRITICAL": - *me = Critical - default: - // return error - return fmt.Errorf("unknown severity: %s", s) - } - - // return success - return nil -} - type V2AccessVector byte const ( @@ -372,7 +342,7 @@ type CvssV2 struct { // CVSS V2 base metrics type BaseMetricV2 struct { CvssV2 CvssV2 `json:"cvssV2"` - severity Severity `json:"severity"` + Severity Severity `json:"severity"` ExploitabilityScore Score `json:"impactScore"` ImpactScore Score `json:"impactScore"` InsufficientInfo bool `json:"acInsufInfo"` diff --git a/internal/feed/severity.go b/internal/feed/severity.go new file mode 100644 index 0000000..50969ed --- /dev/null +++ b/internal/feed/severity.go @@ -0,0 +1,47 @@ +package feed + +//go:generate stringer -linecomment -type=Severity + +import ( + "encoding/json" + "fmt" +) + +type Severity byte + +const ( + SeverityNone Severity = iota // NONE + SeverityLow // LOW + SeverityMedium // MEDIUM + SeverityHigh // HIGH + SeverityCritical // CRITICAL +) + +// Unmarshal CVSS severity from JSON. +func (me *Severity) UnmarshalJSON(b []byte) error { + // decode string, check for error + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + + // check value + switch s { + case "NONE": + *me = SeverityNone + case "LOW": + *me = SeverityLow + case "MEDIUM": + *me = SeverityMedium + case "HIGH": + *me = SeverityHigh + case "CRITICAL": + *me = SeverityCritical + default: + // return error + return fmt.Errorf("unknown severity: %s", s) + } + + // return success + return nil +} diff --git a/internal/feed/severity_string.go b/internal/feed/severity_string.go new file mode 100644 index 0000000..28e1e91 --- /dev/null +++ b/internal/feed/severity_string.go @@ -0,0 +1,27 @@ +// Code generated by "stringer -linecomment -type=Severity"; DO NOT EDIT. + +package feed + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[SeverityNone-0] + _ = x[SeverityLow-1] + _ = x[SeverityMedium-2] + _ = x[SeverityHigh-3] + _ = x[SeverityCritical-4] +} + +const _Severity_name = "NONELOWMEDIUMHIGHCRITICAL" + +var _Severity_index = [...]uint8{0, 4, 7, 13, 17, 25} + +func (i Severity) String() string { + if i >= Severity(len(_Severity_index)-1) { + return "Severity(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Severity_name[_Severity_index[i]:_Severity_index[i+1]] +} diff --git a/internal/feed/severity_test.go b/internal/feed/severity_test.go new file mode 100644 index 0000000..75aec72 --- /dev/null +++ b/internal/feed/severity_test.go @@ -0,0 +1,83 @@ +package feed + +import ( + "encoding/json" + "testing" +) + +func TestSeverityUnmarshalInvalidData(t *testing.T) { + test := []byte(`{}`) + var val Severity + + if err := json.Unmarshal(test, &val); err == nil { + t.Errorf("got \"%s\", exp error", val) + } +} + +func TestSeverityUnmarshalUnknown(t *testing.T) { + test := []byte(`"foo"`) + exp := "unknown severity: foo" + var val Severity + + err := json.Unmarshal(test, &val) + if err == nil { + t.Errorf("got \"%s\", exp error", val) + return + } + + if err.Error() != exp { + t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) + } +} + +func TestSeverityUnmarshalValid(t *testing.T) { + tests := []struct { + val string + exp Severity + } { + { "\"NONE\"", SeverityNone }, + { "\"LOW\"", SeverityLow }, + { "\"MEDIUM\"", SeverityMedium }, + { "\"HIGH\"", SeverityHigh }, + { "\"CRITICAL\"", SeverityCritical }, + } + + for _, test := range(tests) { + t.Run(test.val, func(t *testing.T) { + var got Severity + if err := json.Unmarshal([]byte(test.val), &got); err != nil { + t.Error(err) + return + } + + if got != test.exp { + t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) + } + }) + } +} + +func TestSeverityString(t *testing.T) { + tests := []struct { + val Severity + exp string + } { + { SeverityNone, "NONE" }, + { SeverityLow, "LOW" }, + { SeverityMedium, "MEDIUM" }, + { SeverityHigh, "HIGH" }, + { SeverityCritical, "CRITICAL" }, + + { Severity(255), "Severity(255)" }, + } + + for _, test := range(tests) { + t.Run(test.exp, func(t *testing.T) { + got := test.val.String() + + if got != test.exp { + t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) + } + }) + } +} -- cgit v1.2.3