-
Notifications
You must be signed in to change notification settings - Fork 3
/
audit.go
73 lines (65 loc) · 2.31 KB
/
audit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package audit
import (
"encoding/json"
"io/ioutil"
"os"
"strings"
"github.com/probr/probr-sdk/utils"
)
// Scenario is used by scenario states to audit progress through each step
type Scenario struct {
Name string
Result string // Passed / Failed / Given Not Met
Tags []string
Steps map[int]*step
}
type step struct {
Function string
Name string
Description string // Long-form explanation of anything happening in the step
Result string // Passed / Failed
Error string // Log the error text
Payload interface{} // Handles any values that are sent across the network
}
func (e *Probe) Write() {
if len(e.Scenarios) > 0 && utils.WriteAllowed(e.Path) {
os.Create(e.Path)
json, _ := json.MarshalIndent(e, "", " ")
data := []byte(json)
ioutil.WriteFile(e.Path, data, 0755)
}
}
// AuditScenarioStep sets description, payload, and pass/fail based on err parameter.
// This function should be deferred to catch panic behavior, otherwise the audit will not be logged on panic
func (p *Scenario) AuditScenarioStep(stepName, description string, payload interface{}, err error) {
stepFunctionName := utils.CallerName(2) // returns name if deferred and not panicking
switch stepFunctionName {
case "call":
stepFunctionName = utils.CallerName(1) // returns name if this function was not deferred in the caller
case "gopanic":
stepFunctionName = utils.CallerName(3) // returns name if caller panicked and this function was deferred
}
p.audit(stepFunctionName, stepName, description, payload, err)
}
func (p *Scenario) audit(functionName string, stepName string, description string, payload interface{}, err error) {
stepNumber := len(p.Steps) + 1
p.Steps[stepNumber] = &step{
Function: functionName,
Name: stepName,
Description: description,
Payload: payload,
}
if err == nil {
p.Steps[stepNumber].Result = "Passed"
p.Result = "Passed"
} else {
p.Steps[stepNumber].Result = "Failed"
p.Steps[stepNumber].Error = strings.Replace(err.Error(), "[ERROR] ", "", -1)
if stepNumber == 1 {
// TODO: change to handle this in AuditScenarioGiven, then here do if step.IsGiven
p.Result = "Given Not Met" // First entry is always a 'given'; failures should be ignored
} else {
p.Result = "Failed" // First 'given' was met, but a subsequent step failed
}
}
}