Add alert tests

This commit is contained in:
IamTheFij 2019-10-03 16:30:49 -07:00
parent 68ee048b76
commit 71574dd8a9
5 changed files with 156 additions and 25 deletions

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
"log" "log"
"os/exec" "os/exec"
"text/template" "text/template"
@ -36,7 +37,7 @@ func (alert Alert) IsValid() bool {
} }
// BuildTemplates compiles command templates for the Alert // BuildTemplates compiles command templates for the Alert
func (alert *Alert) BuildTemplates() { func (alert *Alert) BuildTemplates() error {
if alert.commandTemplate == nil && alert.Command != nil { if alert.commandTemplate == nil && alert.Command != nil {
// build template // build template
log.Println("Building template for command...") log.Println("Building template for command...")
@ -52,46 +53,50 @@ func (alert *Alert) BuildTemplates() {
alert.commandShellTemplate = template.Must( alert.commandShellTemplate = template.Must(
template.New(alert.Name).Parse(alert.CommandShell), template.New(alert.Name).Parse(alert.CommandShell),
) )
log.Printf("Template built: %v", alert.commandShellTemplate)
} else { } else {
log.Fatalf("No template provided for alert %s", alert.Name) return fmt.Errorf("No template provided for alert %s", alert.Name)
} }
return nil
} }
// Send will send an alert notice by executing the command template // Send will send an alert notice by executing the command template
func (alert Alert) Send(notice AlertNotice) { func (alert Alert) Send(notice AlertNotice) (output_str string, err error) {
var cmd *exec.Cmd var cmd *exec.Cmd
if alert.commandTemplate != nil { if alert.commandTemplate != nil {
// build template
log.Println("Send command thing...")
command := []string{} command := []string{}
for _, cmdTmp := range alert.commandTemplate { for _, cmdTmp := range alert.commandTemplate {
var commandBuffer bytes.Buffer var commandBuffer bytes.Buffer
err := cmdTmp.Execute(&commandBuffer, notice) err = cmdTmp.Execute(&commandBuffer, notice)
if err != nil { if err != nil {
panic(err) return
} }
command = append(command, commandBuffer.String()) command = append(command, commandBuffer.String())
} }
cmd = exec.Command(command[0], command[1:]...) cmd = exec.Command(command[0], command[1:]...)
} else if alert.commandShellTemplate != nil { } else if alert.commandShellTemplate != nil {
var commandBuffer bytes.Buffer var commandBuffer bytes.Buffer
err := alert.commandShellTemplate.Execute(&commandBuffer, notice) err = alert.commandShellTemplate.Execute(&commandBuffer, notice)
if err != nil { if err != nil {
panic(err) return
} }
shellCommand := commandBuffer.String() shellCommand := commandBuffer.String()
log.Printf("About to run alert command: %s", shellCommand)
cmd = ShellCommand(shellCommand) cmd = ShellCommand(shellCommand)
} else { } else {
panic("No template compiled?") err = fmt.Errorf("No templates compiled for alert %v", alert.Name)
return
} }
output, err := cmd.CombinedOutput() // Exit if we're not ready to run the command
log.Printf("Check %s\n---\n%s\n---", alert.Name, string(output)) if cmd == nil || err != nil {
if err != nil { return
panic(err)
} }
var output []byte
output, err = cmd.CombinedOutput()
output_str = string(output)
log.Printf("Check %s\n---\n%s\n---", alert.Name, output_str)
return output_str, err
} }

121
alert_test.go Normal file
View File

@ -0,0 +1,121 @@
package main
import (
"log"
"testing"
)
func TestAlertIsValid(t *testing.T) {
cases := []struct {
alert Alert
expected bool
name string
}{
{Alert{Command: []string{"echo", "test"}}, true, "Command only"},
{Alert{CommandShell: "echo test"}, true, "CommandShell only"},
{Alert{}, false, "No commands"},
{
Alert{Command: []string{"echo", "test"}, CommandShell: "echo test"},
false,
"Both commands",
},
}
for _, c := range cases {
log.Printf("Testing case %s", c.name)
actual := c.alert.IsValid()
if actual != c.expected {
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expected, actual)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----")
}
}
func TestAlertSend(t *testing.T) {
cases := []struct {
alert Alert
notice AlertNotice
expectedOutput string
expectErr bool
name string
}{
{
Alert{Command: []string{"echo", "{{.MonitorName}}"}},
AlertNotice{MonitorName: "test"},
"test\n",
false,
"Command with template",
},
{
Alert{CommandShell: "echo {{.MonitorName}}"},
AlertNotice{MonitorName: "test"},
"test\n",
false,
"Command shell with template",
},
{
Alert{Command: []string{"echo", "{{.Bad}}"}},
AlertNotice{MonitorName: "test"},
"",
true,
"Command with bad template",
},
{
Alert{CommandShell: "echo {{.Bad}}"},
AlertNotice{MonitorName: "test"},
"",
true,
"Command shell with bad template",
},
}
for _, c := range cases {
log.Printf("Testing case %s", c.name)
c.alert.BuildTemplates()
output, err := c.alert.Send(c.notice)
hasErr := (err != nil)
if output != c.expectedOutput {
t.Errorf("Send(%v output), expected=%v actual=%v", c.name, c.expectedOutput, output)
log.Printf("Case failed: %s", c.name)
}
if hasErr != c.expectErr {
t.Errorf("Send(%v err), expected=%v actual=%v", c.name, "Err", err)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----")
}
}
func TestAlertSendNoTemplates(t *testing.T) {
alert := Alert{}
notice := AlertNotice{}
output, err := alert.Send(notice)
if err == nil {
t.Errorf("Send(no template), expected=%v actual=%v", "Err", output)
}
log.Println("-----")
}
func TestAlertBuildTemplate(t *testing.T) {
cases := []struct {
alert Alert
expectErr bool
name string
}{
{Alert{Command: []string{"echo", "test"}}, false, "Command only"},
{Alert{CommandShell: "echo test"}, false, "CommandShell only"},
{Alert{}, true, "No commands"},
}
for _, c := range cases {
log.Printf("Testing case %s", c.name)
err := c.alert.BuildTemplates()
hasErr := (err != nil)
if hasErr != c.expectErr {
t.Errorf("IsValid(%v), expected=%t actual=%t", c.name, c.expectErr, err)
log.Printf("Case failed: %s", c.name)
}
log.Println("-----")
}
}

View File

@ -38,7 +38,9 @@ func (config Config) IsValid() (isValid bool) {
func (config *Config) Init() { func (config *Config) Init() {
for name, alert := range config.Alerts { for name, alert := range config.Alerts {
alert.Name = name alert.Name = name
alert.BuildTemplates() if err := alert.BuildTemplates(); err != nil {
panic(err)
}
} }
} }

View File

@ -29,7 +29,10 @@ func main() {
} }
for _, alertName := range alerts { for _, alertName := range alerts {
if alert, ok := config.Alerts[alertName]; ok { if alert, ok := config.Alerts[alertName]; ok {
alert.Send(*alertNotice) _, err := alert.Send(*alertNotice)
if err != nil {
panic(err)
}
} else { } else {
log.Printf("WARNING: Could not find alert for %s", alertName) log.Printf("WARNING: Could not find alert for %s", alertName)
} }