-
Notifications
You must be signed in to change notification settings - Fork 1
/
ldfi.go
113 lines (96 loc) · 2.14 KB
/
ldfi.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package lib
import (
"encoding/json"
"log"
"os"
"os/exec"
"strconv"
"strings"
"time"
)
type FailSpec struct {
EFF int // End (time) of finite failures.
Crashes int // Max amount of node (permanent) crashes.
EOT int // End of time, for the test.
LimitFaults int // Have a limit of how many faults may be generated, 0 is no limit
}
type Fault struct {
Kind string
Args FaultArgs
}
type FaultArgs interface{ FaultArgs() }
type Omission struct {
From string
To string
At int
}
func (_ Omission) FaultArgs() {}
type Crash struct {
From string
At int
}
func (_ Crash) FaultArgs() {}
type Faults = struct {
Faults []Fault `json:"faults"`
}
func (f *Fault) UnmarshalJSON(bs []byte) error {
var s map[string]interface{}
if err := json.Unmarshal(bs, &s); err != nil {
return err
}
switch strings.ToLower(s["kind"].(string)) {
case "omission":
*f = Fault{
Kind: "omission",
Args: Omission{
From: s["from"].(string),
To: s["to"].(string),
At: int(s["at"].(float64)),
},
}
case "crash":
*f = Fault{
Kind: "crash",
Args: Crash{
From: s["from"].(string),
At: int(s["at"].(float64)),
},
}
default:
log.Panicf("Unknown kind: %+v\n", s)
}
return nil
}
func Ldfi(testId TestId, failedRunIds []RunId, fail FailSpec) Faults {
start := time.Now()
args := []string{
"--endOfFiniteFailures", strconv.Itoa(fail.EFF),
"--maxCrashes", strconv.Itoa(fail.Crashes),
"--testId", strconv.Itoa(testId.TestId),
"--endOfTime", strconv.Itoa(0), // not used
}
if fail.LimitFaults > 0 {
args = append(args, "--limitNumberOfFaults")
args = append(args, strconv.Itoa(fail.LimitFaults))
}
for _, r := range failedRunIds {
args = append(args, "--failedRunId")
args = append(args, strconv.Itoa(r.RunId))
}
cmd := exec.Command("detsys-ldfi", args...)
cmd.Stderr = os.Stderr
out, err := cmd.Output()
if err != nil {
log.Panicf("%s\n%s\n", err, out)
}
var result struct {
Faults []Fault `json:"faults"`
}
err = json.Unmarshal(out, &result)
if err != nil {
log.Panic(err)
}
elapsed := time.Since(start)
log.Printf("ldfi time: %v\n", elapsed)
return Faults{result.Faults}
}