Improve test structures using subtests
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
IamTheFij 2024-11-14 11:35:26 -08:00
parent 3f6c8f5a22
commit 32745c816c
5 changed files with 182 additions and 163 deletions

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"log"
"testing" "testing"
) )
@ -17,15 +16,16 @@ func TestAlertIsValid(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
actual := c.alert.IsValid() t.Run(c.name, func(t *testing.T) {
if actual != c.expected { t.Parallel()
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expected, actual)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") actual := c.alert.IsValid()
if actual != c.expected {
t.Errorf("expected=%t actual=%t", c.expected, actual)
}
})
} }
} }
@ -91,27 +91,27 @@ func TestAlertSend(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
err := c.alert.BuildTemplates() t.Run(c.name, func(t *testing.T) {
if err != nil { t.Parallel()
t.Errorf("Send(%v output), error building templates: %v", c.name, err)
}
output, err := c.alert.Send(c.notice) err := c.alert.BuildTemplates()
hasErr := (err != nil) if err != nil {
t.Errorf("Send(%v output), error building templates: %v", c.name, err)
}
if output != c.expectedOutput { output, err := c.alert.Send(c.notice)
t.Errorf("Send(%v output), expected=%v actual=%v", c.name, c.expectedOutput, output) hasErr := (err != nil)
log.Printf("Case failed: %s", c.name)
}
if hasErr != c.expectErr { if output != c.expectedOutput {
t.Errorf("Send(%v err), expected=%v actual=%v", c.name, "Err", err) t.Errorf("Send(%v output), expected=%v actual=%v", c.name, c.expectedOutput, output)
log.Printf("Case failed: %s", c.name) }
}
log.Println("-----") if hasErr != c.expectErr {
t.Errorf("Send(%v err), expected=%v actual=%v", c.name, "Err", err)
}
})
} }
} }
@ -123,8 +123,6 @@ func TestAlertSendNoTemplates(t *testing.T) {
if err == nil { if err == nil {
t.Errorf("Send(no template), expected=%v actual=%v", "Err", output) t.Errorf("Send(no template), expected=%v actual=%v", "Err", output)
} }
log.Println("-----")
} }
func TestAlertBuildTemplate(t *testing.T) { func TestAlertBuildTemplate(t *testing.T) {
@ -139,15 +137,18 @@ func TestAlertBuildTemplate(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
err := c.alert.BuildTemplates()
hasErr := (err != nil)
if hasErr != c.expectErr { t.Run(c.name, func(t *testing.T) {
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expectErr, err) t.Parallel()
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") err := c.alert.BuildTemplates()
hasErr := (err != nil)
if hasErr != c.expectErr {
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expectErr, err)
}
})
} }
} }

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"log"
"testing" "testing"
"time" "time"
) )
@ -23,19 +22,23 @@ func TestLoadConfig(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
_, err := LoadConfig(c.configPath)
hasErr := (err != nil)
if hasErr != c.expectErr { t.Run(c.name, func(t *testing.T) {
t.Errorf("LoadConfig(%v), expected_error=%v actual=%v", c.name, c.expectErr, err) t.Parallel()
log.Printf("Case failed: %s", c.name)
} _, err := LoadConfig(c.configPath)
hasErr := (err != nil)
if hasErr != c.expectErr {
t.Errorf("LoadConfig(%v), expected_error=%v actual=%v", c.name, c.expectErr, err)
}
})
} }
} }
func TestIntervalParsing(t *testing.T) { func TestIntervalParsing(t *testing.T) {
log.Printf("Testing case TestIntervalParsing") t.Parallel()
config, err := LoadConfig("./test/valid-config.yml") config, err := LoadConfig("./test/valid-config.yml")
if err != nil { if err != nil {
@ -58,23 +61,18 @@ func TestIntervalParsing(t *testing.T) {
if config.Monitors[1].CheckInterval != oneMinute { if config.Monitors[1].CheckInterval != oneMinute {
t.Errorf("Incorrectly parsed seconds duration. expected=%v actual=%v", oneSecond, config.CheckInterval) t.Errorf("Incorrectly parsed seconds duration. expected=%v actual=%v", oneSecond, config.CheckInterval)
} }
log.Println("-----")
} }
// TestMultiLineConfig is a more complicated test stepping through the parsing // TestMultiLineConfig is a more complicated test stepping through the parsing
// and execution of mutli-line strings presented in YAML // and execution of mutli-line strings presented in YAML
func TestMultiLineConfig(t *testing.T) { func TestMultiLineConfig(t *testing.T) {
log.Println("Testing multi-line string config") t.Parallel()
config, err := LoadConfig("./test/valid-verify-multi-line.yml") config, err := LoadConfig("./test/valid-verify-multi-line.yml")
if err != nil { if err != nil {
t.Fatalf("TestMultiLineConfig(load), expected=no_error actual=%v", err) t.Fatalf("TestMultiLineConfig(load), expected=no_error actual=%v", err)
} }
log.Println("-----")
log.Println("TestMultiLineConfig(parse > string)")
expected := "echo 'Some string with stuff'; echo \"<angle brackets>\"; exit 1\n" expected := "echo 'Some string with stuff'; echo \"<angle brackets>\"; exit 1\n"
actual := config.Monitors[0].Command.ShellCommand actual := config.Monitors[0].Command.ShellCommand
@ -86,9 +84,6 @@ func TestMultiLineConfig(t *testing.T) {
t.Logf("bytes actual =%v", []byte(actual)) t.Logf("bytes actual =%v", []byte(actual))
} }
log.Println("-----")
log.Println("TestMultiLineConfig(execute > string)")
_, notice := config.Monitors[0].Check() _, notice := config.Monitors[0].Check()
if notice == nil { if notice == nil {
t.Fatalf("Did not receive an alert notice") t.Fatalf("Did not receive an alert notice")
@ -105,9 +100,6 @@ func TestMultiLineConfig(t *testing.T) {
t.Logf("bytes actual =%v", []byte(actual)) t.Logf("bytes actual =%v", []byte(actual))
} }
log.Println("-----")
log.Println("TestMultiLineConfig(parse | string)")
expected = "echo 'Some string with stuff'\necho '<angle brackets>'\n" expected = "echo 'Some string with stuff'\necho '<angle brackets>'\n"
actual = config.Alerts["log_shell"].Command.ShellCommand actual = config.Alerts["log_shell"].Command.ShellCommand
@ -119,9 +111,6 @@ func TestMultiLineConfig(t *testing.T) {
t.Logf("bytes actual =%v", []byte(actual)) t.Logf("bytes actual =%v", []byte(actual))
} }
log.Println("-----")
log.Println("TestMultiLineConfig(execute | string)")
actual, err = config.Alerts["log_shell"].Send(AlertNotice{}) actual, err = config.Alerts["log_shell"].Send(AlertNotice{})
if err != nil { if err != nil {
t.Errorf("Execution of alert failed") t.Errorf("Execution of alert failed")

View File

@ -121,17 +121,23 @@ func TestCheckMonitors(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
err := c.config.Init() c := c
if err != nil {
t.Errorf("checkMonitors(%s): unexpected error reading config: %v", c.name, err)
}
err = checkMonitors(&c.config) t.Run(c.name, func(t *testing.T) {
if err == nil && c.expectErr { t.Parallel()
t.Errorf("checkMonitors(%s): Expected panic, the code did not panic", c.name)
} else if err != nil && !c.expectErr { err := c.config.Init()
t.Errorf("checkMonitors(%s): Did not expect an error, but we got one anyway: %v", c.name, err) if err != nil {
} t.Errorf("checkMonitors(%s): unexpected error reading config: %v", c.name, err)
}
err = checkMonitors(&c.config)
if err == nil && c.expectErr {
t.Errorf("checkMonitors(%s): Expected panic, the code did not panic", c.name)
} else if err != nil && !c.expectErr {
t.Errorf("checkMonitors(%s): Did not expect an error, but we got one anyway: %v", c.name, err)
}
})
} }
} }
@ -182,16 +188,22 @@ func TestFirstRunAlerts(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
err := c.config.Init() c := c
if err != nil {
t.Errorf("sendFirstRunAlerts(%s): unexpected error reading config: %v", c.name, err)
}
err = sendStartupAlerts(&c.config, c.startupAlerts) t.Run(c.name, func(t *testing.T) {
if err == nil && c.expectErr { t.Parallel()
t.Errorf("sendFirstRunAlerts(%s): Expected error, the code did not error", c.name)
} else if err != nil && !c.expectErr { err := c.config.Init()
t.Errorf("sendFirstRunAlerts(%s): Did not expect an error, but we got one anyway: %v", c.name, err) if err != nil {
} t.Errorf("sendFirstRunAlerts(%s): unexpected error reading config: %v", c.name, err)
}
err = sendStartupAlerts(&c.config, c.startupAlerts)
if err == nil && c.expectErr {
t.Errorf("sendFirstRunAlerts(%s): Expected error, the code did not error", c.name)
} else if err != nil && !c.expectErr {
t.Errorf("sendFirstRunAlerts(%s): Did not expect an error, but we got one anyway: %v", c.name, err)
}
})
} }
} }

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"log"
"testing" "testing"
"time" "time"
) )
@ -21,15 +20,16 @@ func TestMonitorIsValid(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
actual := c.monitor.IsValid() t.Run(c.name, func(t *testing.T) {
if actual != c.expected { t.Parallel()
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expected, actual)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") actual := c.monitor.IsValid()
if actual != c.expected {
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expected, actual)
}
})
} }
} }
@ -51,10 +51,16 @@ func TestMonitorShouldCheck(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
actual := c.monitor.ShouldCheck() c := c
if actual != c.expected {
t.Errorf("ShouldCheck(%v), expected=%t actual=%t", c.name, c.expected, actual) t.Run(c.name, func(t *testing.T) {
} t.Parallel()
actual := c.monitor.ShouldCheck()
if actual != c.expected {
t.Errorf("ShouldCheck(%v), expected=%t actual=%t", c.name, c.expected, actual)
}
})
} }
} }
@ -72,15 +78,16 @@ func TestMonitorIsUp(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
actual := c.monitor.IsUp() t.Run(c.name, func(t *testing.T) {
if actual != c.expected { t.Parallel()
t.Errorf("IsUp(%v), expected=%t actual=%t", c.name, c.expected, actual)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") actual := c.monitor.IsUp()
if actual != c.expected {
t.Errorf("IsUp(%v), expected=%t actual=%t", c.name, c.expected, actual)
}
})
} }
} }
@ -99,15 +106,16 @@ func TestMonitorGetAlertNames(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
actual := c.monitor.GetAlertNames(c.up) t.Run(c.name, func(t *testing.T) {
if !EqualSliceString(actual, c.expected) { t.Parallel()
t.Errorf("GetAlertNames(%v), expected=%v actual=%v", c.name, c.expected, actual)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") actual := c.monitor.GetAlertNames(c.up)
if !EqualSliceString(actual, c.expected) {
t.Errorf("GetAlertNames(%v), expected=%v actual=%v", c.name, c.expected, actual)
}
})
} }
} }
@ -124,17 +132,18 @@ func TestMonitorSuccess(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
notice := c.monitor.success() t.Run(c.name, func(t *testing.T) {
hasNotice := (notice != nil) t.Parallel()
if hasNotice != c.expectNotice { notice := c.monitor.success()
t.Errorf("success(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice) hasNotice := (notice != nil)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") if hasNotice != c.expectNotice {
t.Errorf("success(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice)
}
})
} }
} }
@ -157,17 +166,18 @@ func TestMonitorFailureAlertAfter(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
notice := c.monitor.failure() t.Run(c.name, func(t *testing.T) {
hasNotice := (notice != nil) t.Parallel()
if hasNotice != c.expectNotice { notice := c.monitor.failure()
t.Errorf("failure(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice) hasNotice := (notice != nil)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") if hasNotice != c.expectNotice {
t.Errorf("failure(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice)
}
})
} }
} }
@ -210,17 +220,18 @@ func TestMonitorFailureAlertEvery(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
notice := c.monitor.failure() t.Run(c.name, func(t *testing.T) {
hasNotice := (notice != nil) t.Parallel()
if hasNotice != c.expectNotice { notice := c.monitor.failure()
t.Errorf("failure(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice) hasNotice := (notice != nil)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----") if hasNotice != c.expectNotice {
t.Errorf("failure(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice)
}
})
} }
} }
@ -248,17 +259,15 @@ func TestMonitorFailureExponential(t *testing.T) {
monitor := Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEveryExp} monitor := Monitor{failureCount: 0, AlertAfter: 1, AlertEvery: &alertEveryExp}
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) t.Run(c.name, func(t *testing.T) {
// NOTE: These tests are not parallel because they rely on the state of the Monitor
notice := monitor.failure()
hasNotice := (notice != nil)
notice := monitor.failure() if hasNotice != c.expectNotice {
hasNotice := (notice != nil) t.Errorf("failure(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice)
}
if hasNotice != c.expectNotice { })
t.Errorf("failure(%v), expected=%t actual=%t", c.name, c.expectNotice, hasNotice)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----")
} }
} }
@ -298,26 +307,25 @@ func TestMonitorCheck(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
log.Printf("Testing case %s", c.name) c := c
isSuccess, notice := c.monitor.Check() t.Run(c.name, func(t *testing.T) {
if isSuccess != c.expect.isSuccess { t.Parallel()
t.Errorf("Check(%v) (success), expected=%t actual=%t", c.name, c.expect.isSuccess, isSuccess)
log.Printf("Case failed: %s", c.name)
}
hasNotice := (notice != nil) isSuccess, notice := c.monitor.Check()
if hasNotice != c.expect.hasNotice { if isSuccess != c.expect.isSuccess {
t.Errorf("Check(%v) (notice), expected=%t actual=%t", c.name, c.expect.hasNotice, hasNotice) t.Errorf("Check(%v) (success), expected=%t actual=%t", c.name, c.expect.isSuccess, isSuccess)
log.Printf("Case failed: %s", c.name) }
}
lastOutput := c.monitor.lastOutput hasNotice := (notice != nil)
if lastOutput != c.expect.lastOutput { if hasNotice != c.expect.hasNotice {
t.Errorf("Check(%v) (output), expected=%v actual=%v", c.name, c.expect.lastOutput, lastOutput) t.Errorf("Check(%v) (notice), expected=%t actual=%t", c.name, c.expect.hasNotice, hasNotice)
log.Printf("Case failed: %s", c.name) }
}
log.Println("-----") lastOutput := c.monitor.lastOutput
if lastOutput != c.expect.lastOutput {
t.Errorf("Check(%v) (output), expected=%v actual=%v", c.name, c.expect.lastOutput, lastOutput)
}
})
} }
} }

View File

@ -1,6 +1,9 @@
package main package main
import "testing" import (
"fmt"
"testing"
)
func TestUtilEqualSliceString(t *testing.T) { func TestUtilEqualSliceString(t *testing.T) {
cases := []struct { cases := []struct {
@ -21,12 +24,18 @@ func TestUtilEqualSliceString(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
actual := EqualSliceString(c.a, c.b) c := c
if actual != c.expected {
t.Errorf( t.Run(fmt.Sprintf("%v %v", c.a, c.b), func(t *testing.T) {
"EqualSliceString(%v, %v), expected=%v actual=%v", t.Parallel()
c.a, c.b, c.expected, actual,
) actual := EqualSliceString(c.a, c.b)
} if actual != c.expected {
t.Errorf(
"EqualSliceString(%v, %v), expected=%v actual=%v",
c.a, c.b, c.expected, actual,
)
}
})
} }
} }