From 4bdc8ff7b0dd532ec2f645e3dbfe737cd6b6d613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Wed, 22 Jan 2020 23:44:35 +0000 Subject: [PATCH] feat(tests): add basic testscript tests --- cmd/karma/main.go | 74 ++++++++++++------- cmd/karma/main_test.go | 5 +- cmd/karma/script_test.go | 43 +++++++++++ cmd/karma/testdata/check-config.txt | 5 ++ .../testdata/duplicated_alertmanager_name.txt | 12 +++ .../testdata/duplicated_alertmanager_uri.txt | 12 +++ cmd/karma/testdata/invalid_log_format.txt | 4 + cmd/karma/testdata/invalid_log_level.txt | 4 + cmd/karma/testdata/invalid_tls_config.txt | 15 ++++ cmd/karma/testdata/invalid_ttl.txt | 4 + cmd/karma/testdata/invalid_uri.txt | 4 + .../testdata/linkDetect_invalid_regex.txt | 16 ++++ cmd/karma/testdata/linkDetect_no_regex.txt | 15 ++++ cmd/karma/testdata/linkDetect_no_uri.txt | 15 ++++ .../testdata/linkDetect_valid_config.txt | 17 +++++ cmd/karma/testdata/log_format_json.txt | 4 + cmd/karma/testdata/no_args.txt | 4 + cmd/karma/testdata/version.txt | 4 + cmd/karma/views_test.go | 5 +- go.mod | 1 + go.sum | 2 + 21 files changed, 237 insertions(+), 28 deletions(-) create mode 100644 cmd/karma/script_test.go create mode 100644 cmd/karma/testdata/check-config.txt create mode 100644 cmd/karma/testdata/duplicated_alertmanager_name.txt create mode 100644 cmd/karma/testdata/duplicated_alertmanager_uri.txt create mode 100644 cmd/karma/testdata/invalid_log_format.txt create mode 100644 cmd/karma/testdata/invalid_log_level.txt create mode 100644 cmd/karma/testdata/invalid_tls_config.txt create mode 100644 cmd/karma/testdata/invalid_ttl.txt create mode 100644 cmd/karma/testdata/invalid_uri.txt create mode 100644 cmd/karma/testdata/linkDetect_invalid_regex.txt create mode 100644 cmd/karma/testdata/linkDetect_no_regex.txt create mode 100644 cmd/karma/testdata/linkDetect_no_uri.txt create mode 100644 cmd/karma/testdata/linkDetect_valid_config.txt create mode 100644 cmd/karma/testdata/log_format_json.txt create mode 100644 cmd/karma/testdata/no_args.txt create mode 100644 cmd/karma/testdata/version.txt diff --git a/cmd/karma/main.go b/cmd/karma/main.go index 5de3251b2..2dad1a294 100644 --- a/cmd/karma/main.go +++ b/cmd/karma/main.go @@ -117,7 +117,7 @@ func setupMetrics(router *gin.Engine) { router.GET(getViewURL("/metrics"), promHandler(promhttp.Handler())) } -func setupUpstreams() { +func setupUpstreams() error { for _, s := range config.Config.Alertmanager.Servers { var httpTransport http.RoundTripper @@ -126,7 +126,7 @@ func setupUpstreams() { if s.TLS.CA != "" || s.TLS.Cert != "" || s.TLS.InsecureSkipVerify { httpTransport, err = alertmanager.NewHTTPTransport(s.TLS.CA, s.TLS.Cert, s.TLS.Key, s.TLS.InsecureSkipVerify) if err != nil { - log.Fatalf("Failed to create HTTP transport for Alertmanager '%s' with URI '%s': %s", s.Name, uri.SanitizeURI(s.URI), err) + return fmt.Errorf("Failed to create HTTP transport for Alertmanager '%s' with URI '%s': %s", s.Name, uri.SanitizeURI(s.URI), err) } } @@ -140,16 +140,18 @@ func setupUpstreams() { alertmanager.WithHTTPHeaders(s.Headers), ) if err != nil { - log.Fatalf("Failed to create Alertmanager '%s' with URI '%s': %s", s.Name, uri.SanitizeURI(s.URI), err) + return fmt.Errorf("Failed to create Alertmanager '%s' with URI '%s': %s", s.Name, uri.SanitizeURI(s.URI), err) } err = alertmanager.RegisterAlertmanager(am) if err != nil { - log.Fatalf("Failed to register Alertmanager '%s' with URI '%s': %s", s.Name, uri.SanitizeURI(s.URI), err) + return fmt.Errorf("Failed to register Alertmanager '%s' with URI '%s': %s", s.Name, uri.SanitizeURI(s.URI), err) } } + + return nil } -func setupLogger() { +func setupLogger() error { switch config.Config.Log.Level { case "debug": log.SetLevel(log.DebugLevel) @@ -164,7 +166,7 @@ func setupLogger() { case "panic": log.SetLevel(log.PanicLevel) default: - log.Fatalf("Unknown log level '%s'", config.Config.Log.Level) + return fmt.Errorf("Unknown log level '%s'", config.Config.Log.Level) } switch config.Config.Log.Format { @@ -173,26 +175,31 @@ func setupLogger() { case "json": log.SetFormatter(&log.JSONFormatter{}) default: - log.Fatalf("Unknown log format '%s'", config.Config.Log.Format) + return fmt.Errorf("Unknown log format '%s'", config.Config.Log.Format) } + + return nil } -func main() { +func mainSetup() (*gin.Engine, error) { printVersion := pflag.Bool("version", false, "Print version and exit") validateConfig := pflag.Bool("check-config", false, "Validate configuration and exit") pflag.Parse() if *printVersion { fmt.Println(version) - return + return nil, nil } config.Config.Read() - setupLogger() + err := setupLogger() + if err != nil { + return nil, err + } // timer duration cannot be zero second or a negative one if config.Config.Alertmanager.Interval <= time.Second*0 { - log.Fatalf("Invalid AlertmanagerTTL value '%v'", config.Config.Alertmanager.Interval) + return nil, fmt.Errorf("Invalid AlertmanagerTTL value '%v'", config.Config.Alertmanager.Interval) } log.Infof("Version: %s", version) @@ -203,11 +210,11 @@ func main() { linkDetectRules := []models.LinkDetectRule{} for _, rule := range config.Config.Silences.Comments.LinkDetect.Rules { if rule.Regex == "" || rule.URITemplate == "" { - log.Fatalf("Invalid link detect rule, regex '%s' uriTemplate '%s'", rule.Regex, rule.URITemplate) + return nil, fmt.Errorf("Invalid link detect rule, regex '%s' uriTemplate '%s'", rule.Regex, rule.URITemplate) } re, err := regexp.Compile(rule.Regex) if err != nil { - log.Fatalf("Invalid link detect rule '%s': %s", rule.Regex, err) + return nil, fmt.Errorf("Invalid link detect rule '%s': %s", rule.Regex, err) } linkDetectRules = append(linkDetectRules, models.LinkDetectRule{Regex: re, URITemplate: rule.URITemplate}) } @@ -215,26 +222,20 @@ func main() { apiCache = cache.New(cache.NoExpiration, 10*time.Second) - setupUpstreams() + err = setupUpstreams() + if err != nil { + return nil, err + } if len(alertmanager.GetAlertmanagers()) == 0 { - log.Fatal("No valid Alertmanager URIs defined") + return nil, fmt.Errorf("No valid Alertmanager URIs defined") } if *validateConfig { log.Info("Configuration is valid") - return + return nil, nil } - // before we start try to fetch data from Alertmanager - log.Info("Initial Alertmanager query") - pullFromAlertmanager() - log.Info("Done, starting HTTP server") - - // background loop that will fetch updates from Alertmanager - ticker = time.NewTicker(config.Config.Alertmanager.Interval) - go Tick() - switch config.Config.Debug { case true: gin.SetMode(gin.DebugMode) @@ -263,10 +264,31 @@ func main() { for _, am := range alertmanager.GetAlertmanagers() { err := setupRouterProxyHandlers(router, am) if err != nil { - log.Fatalf("Failed to setup proxy handlers for Alertmanager '%s': %s", am.Name, err) + return nil, fmt.Errorf("Failed to setup proxy handlers for Alertmanager '%s': %s", am.Name, err) } } + return router, nil +} + +func main() { + router, err := mainSetup() + if err != nil { + log.Fatal(err) + } + if router == nil { + return + } + + // before we start try to fetch data from Alertmanager + log.Info("Initial Alertmanager query") + pullFromAlertmanager() + log.Info("Done, starting HTTP server") + + // background loop that will fetch updates from Alertmanager + ticker = time.NewTicker(config.Config.Alertmanager.Interval) + go Tick() + listen := fmt.Sprintf("%s:%d", config.Config.Listen.Address, config.Config.Listen.Port) httpServer := &http.Server{ Addr: listen, diff --git a/cmd/karma/main_test.go b/cmd/karma/main_test.go index d4a7e4266..d73954846 100644 --- a/cmd/karma/main_test.go +++ b/cmd/karma/main_test.go @@ -23,7 +23,10 @@ func TestLogConfig(t *testing.T) { for val, level := range logLevels { config.Config.Log.Level = val - setupLogger() + err := setupLogger() + if err != nil { + t.Error(err) + } if log.GetLevel() != level { t.Errorf("Config.Log.Level=%s resulted in invalid log level %s", val, log.GetLevel()) } diff --git a/cmd/karma/script_test.go b/cmd/karma/script_test.go new file mode 100644 index 000000000..7918eacb4 --- /dev/null +++ b/cmd/karma/script_test.go @@ -0,0 +1,43 @@ +package main + +import ( + "os" + "testing" + + "github.com/rogpeppe/go-internal/testscript" + + log "github.com/sirupsen/logrus" +) + +func mainShoulFail() int { + _, err := mainSetup() + if err != nil { + log.Error(err) + } else { + log.Error("No error logged") + return 100 + } + return 0 +} + +func mainShouldWork() int { + _, err := mainSetup() + if err != nil { + log.Error(err) + return 100 + } + return 0 +} + +func TestMain(m *testing.M) { + os.Exit(testscript.RunMain(m, map[string]func() int{ + "karma.bin-should-fail": mainShoulFail, + "karma.bin-should-work": mainShouldWork, + })) +} + +func TestScripts(t *testing.T) { + testscript.Run(t, testscript.Params{ + Dir: "testdata", + }) +} diff --git a/cmd/karma/testdata/check-config.txt b/cmd/karma/testdata/check-config.txt new file mode 100644 index 000000000..167b79b24 --- /dev/null +++ b/cmd/karma/testdata/check-config.txt @@ -0,0 +1,5 @@ +# Validates config when --check-config is passed +karma.bin-should-work --log.format=text --log.config=false --check-config --alertmanager.uri=http://localhost +! stdout . +stderr 'msg="Configuration is valid"' +! stderr 'level=error' diff --git a/cmd/karma/testdata/duplicated_alertmanager_name.txt b/cmd/karma/testdata/duplicated_alertmanager_name.txt new file mode 100644 index 000000000..8fad482a4 --- /dev/null +++ b/cmd/karma/testdata/duplicated_alertmanager_name.txt @@ -0,0 +1,12 @@ +# Raises an error if we have 2 instances with the same name +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --config.file=karma.yaml +! stdout . +stderr 'msg="Failed to register Alertmanager ''am1'' with URI ''https://localhost:9094'': alertmanager upstream ''am1'' already exist"' + +-- karma.yaml -- +alertmanager: + servers: + - name: am1 + uri: https://localhost:9093 + - name: am1 + uri: https://localhost:9094 diff --git a/cmd/karma/testdata/duplicated_alertmanager_uri.txt b/cmd/karma/testdata/duplicated_alertmanager_uri.txt new file mode 100644 index 000000000..7fb7e84f4 --- /dev/null +++ b/cmd/karma/testdata/duplicated_alertmanager_uri.txt @@ -0,0 +1,12 @@ +# Raises an error if we have 2 instances with the same URI +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --config.file karma.yaml +! stdout . +stderr 'msg="Failed to register Alertmanager ''am2'' with URI ''https://localhost:9093'': alertmanager upstream ''am1'' already collects from ''https://localhost:9093''"' + +-- karma.yaml -- +alertmanager: + servers: + - name: am1 + uri: https://localhost:9093 + - name: am2 + uri: https://localhost:9093 diff --git a/cmd/karma/testdata/invalid_log_format.txt b/cmd/karma/testdata/invalid_log_format.txt new file mode 100644 index 000000000..34fe3f9b7 --- /dev/null +++ b/cmd/karma/testdata/invalid_log_format.txt @@ -0,0 +1,4 @@ +# Raises an error if invalid log format is passed +karma.bin-should-fail --log.format=text --log.config=false --log.format=xml +! stdout . +stderr 'msg="Unknown log format ''xml''"' diff --git a/cmd/karma/testdata/invalid_log_level.txt b/cmd/karma/testdata/invalid_log_level.txt new file mode 100644 index 000000000..84a9bed92 --- /dev/null +++ b/cmd/karma/testdata/invalid_log_level.txt @@ -0,0 +1,4 @@ +# Raises an error if invalid log level is passed +karma.bin-should-fail --log.format=text --log.config=false --log.level=foobar +! stdout . +stderr 'msg="Unknown log level ''foobar''"' diff --git a/cmd/karma/testdata/invalid_tls_config.txt b/cmd/karma/testdata/invalid_tls_config.txt new file mode 100644 index 000000000..1942eb82b --- /dev/null +++ b/cmd/karma/testdata/invalid_tls_config.txt @@ -0,0 +1,15 @@ +# Raises an error if tls config is invalid +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --config.file=karma.yaml +! stdout . +stderr 'msg="Failed to create HTTP transport for Alertmanager ''client-auth'' with URI ''https://localhost:9093'': open /xxx/xxx-ca-bundle.crt: no such file or directory"' + +-- karma.yaml -- +alertmanager: + servers: + - name: client-auth + uri: https://localhost:9093 + timeout: 10s + tls: + ca: /xxx/xxx-ca-bundle.crt + cert: /xxx/karma/client.pem + key: /xxx/karma/client.key diff --git a/cmd/karma/testdata/invalid_ttl.txt b/cmd/karma/testdata/invalid_ttl.txt new file mode 100644 index 000000000..ccdfb8ca7 --- /dev/null +++ b/cmd/karma/testdata/invalid_ttl.txt @@ -0,0 +1,4 @@ +# Raises an error if negative refresh interval is passed +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --alertmanager.interval=-4s +! stdout . +stderr 'msg="Invalid AlertmanagerTTL value ''-4s''"' diff --git a/cmd/karma/testdata/invalid_uri.txt b/cmd/karma/testdata/invalid_uri.txt new file mode 100644 index 000000000..02078358d --- /dev/null +++ b/cmd/karma/testdata/invalid_uri.txt @@ -0,0 +1,4 @@ +# Raises an error if alertmanager URI is invalid +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --alertmanager.uri httpz://username:secret@localhost +! stdout . +stderr 'msg="Failed to create Alertmanager ''default'' with URI ''httpz://username:xxx@localhost'': unsupported URI scheme ''httpz'' in ''httpz://username:xxx@localhost''"' diff --git a/cmd/karma/testdata/linkDetect_invalid_regex.txt b/cmd/karma/testdata/linkDetect_invalid_regex.txt new file mode 100644 index 000000000..709d7bcd4 --- /dev/null +++ b/cmd/karma/testdata/linkDetect_invalid_regex.txt @@ -0,0 +1,16 @@ +# Raises an error if linkDetect config is missing regex rule +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --config.file=karma.yaml +! stdout . +stderr 'msg="Invalid link detect rule ''foo\+\+\+\+\+\+'': error parsing regexp: invalid nested repetition operator: `\+\+`"' + +-- karma.yaml -- +alertmanager: + servers: + - name: default + uri: https://localhost:9093 +silences: + comments: + linkDetect: + rules: + - regex: "foo++++++" + uriTemplate: https://jira.example.com/ diff --git a/cmd/karma/testdata/linkDetect_no_regex.txt b/cmd/karma/testdata/linkDetect_no_regex.txt new file mode 100644 index 000000000..87623af5b --- /dev/null +++ b/cmd/karma/testdata/linkDetect_no_regex.txt @@ -0,0 +1,15 @@ +# Raises an error if linkDetect config is missing regex rule +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --config.file=karma.yaml +! stdout . +stderr 'msg="Invalid link detect rule, regex '''' uriTemplate ''https://jira.example.com/''"' + +-- karma.yaml -- +alertmanager: + servers: + - name: default + uri: https://localhost:9093 +silences: + comments: + linkDetect: + rules: + - uriTemplate: https://jira.example.com/ diff --git a/cmd/karma/testdata/linkDetect_no_uri.txt b/cmd/karma/testdata/linkDetect_no_uri.txt new file mode 100644 index 000000000..51a45a186 --- /dev/null +++ b/cmd/karma/testdata/linkDetect_no_uri.txt @@ -0,0 +1,15 @@ +# Raises an error if linkDetect config is missing uriTemplate +karma.bin-should-fail --log.format=text --log.config=false --log.level=error --config.file=karma.yaml +! stdout . +stderr 'msg="Invalid link detect rule, regex ''DEVOPS-\[0-9\]\+'' uriTemplate ''''"' + +-- karma.yaml -- +alertmanager: + servers: + - name: default + uri: https://localhost:9093 +silences: + comments: + linkDetect: + rules: + - regex: "DEVOPS-[0-9]+" diff --git a/cmd/karma/testdata/linkDetect_valid_config.txt b/cmd/karma/testdata/linkDetect_valid_config.txt new file mode 100644 index 000000000..90b1cc6cb --- /dev/null +++ b/cmd/karma/testdata/linkDetect_valid_config.txt @@ -0,0 +1,17 @@ +# Config is valid with correct linkDetect rules +karma.bin-should-work --log.format=text --log.config=false --config.file=karma.yaml --check-config +! stdout . +stderr 'msg="Configuration is valid"' +! stderr 'level=error' + +-- karma.yaml -- +alertmanager: + servers: + - name: default + uri: https://localhost:9093 +silences: + comments: + linkDetect: + rules: + - regex: "(DEVOPS-[0-9]+)" + uriTemplate: https://jira.example.com/browse/$1 diff --git a/cmd/karma/testdata/log_format_json.txt b/cmd/karma/testdata/log_format_json.txt new file mode 100644 index 000000000..4eb21a8eb --- /dev/null +++ b/cmd/karma/testdata/log_format_json.txt @@ -0,0 +1,4 @@ +# Logs messages as JSON when log.format=json is passed +karma.bin-should-fail --log.format=json --log.level=error +! stdout . +stderr '^{"level":"error","msg":"No valid Alertmanager URIs defined"' diff --git a/cmd/karma/testdata/no_args.txt b/cmd/karma/testdata/no_args.txt new file mode 100644 index 000000000..d0fdac647 --- /dev/null +++ b/cmd/karma/testdata/no_args.txt @@ -0,0 +1,4 @@ +# Raises an error if no alertmanager uri is set +karma.bin-should-fail --log.format=text --log.config=false --log.level=error +! stdout . +stderr 'msg="No valid Alertmanager URIs defined"' diff --git a/cmd/karma/testdata/version.txt b/cmd/karma/testdata/version.txt new file mode 100644 index 000000000..0a7b24ba5 --- /dev/null +++ b/cmd/karma/testdata/version.txt @@ -0,0 +1,4 @@ +# Prints version when --version is passed +karma.bin-should-work --version +stdout 'dev\n' +! stderr . diff --git a/cmd/karma/views_test.go b/cmd/karma/views_test.go index a22385365..5a64d5cdc 100644 --- a/cmd/karma/views_test.go +++ b/cmd/karma/views_test.go @@ -33,7 +33,10 @@ func mockConfig() { config.Config.Read() if !upstreamSetup { upstreamSetup = true - setupUpstreams() + err := setupUpstreams() + if err != nil { + log.Fatal(err) + } } } diff --git a/go.mod b/go.mod index c4c26e2de..ab3bd5635 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.3.0 github.com/prometheus/common v0.9.1 + github.com/rogpeppe/go-internal v1.3.0 github.com/sirupsen/logrus v1.4.2 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.6.2 diff --git a/go.sum b/go.sum index 08c27a2c9..6568402c5 100644 --- a/go.sum +++ b/go.sum @@ -376,6 +376,7 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83 h1:AtnWoOvTioyDXFvu96MWEeE8qj4COSQnJogzLy/u41A= @@ -555,6 +556,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=