-
Notifications
You must be signed in to change notification settings - Fork 2
/
instances_test.go
88 lines (84 loc) · 2.84 KB
/
instances_test.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
package main
import (
"bytes"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"
)
func TestInstances(t *testing.T) {
if _, err := os.Stat(testerPath); err != nil {
t.Fatalf("can't find tester binary: %v", err)
}
type testcase struct {
name string
inputs []string
expectedOutputs []string // only used if len(expectedFails) == 0
expectedFails []int // if empty, we expect success; otherwise we expect failure from one of the numerated instances
expectedDeadlock bool
}
testcases := []*testcase{
{"no comm", []string{"", "", "", ""}, []string{"0 4\n", "1 4\n", "2 4\n", "3 4\n"}, nil, false},
{"fail", []string{"", "Q 1", "Q 2"}, nil, []int{1, 2}, false},
{"send with no recv", []string{"", "Safoo\n"}, []string{"0 2\n", "1 2\n"}, nil, false},
{"send with recv", []string{"Rb\n", "Safoo\n"}, []string{"0 2\n1 3 foo\n", "1 2\n"}, nil, false},
{"send with recvany", []string{"R*\n", "Safoo\n"}, []string{"0 2\n1 3 foo\n", "1 2\n"}, nil, false},
{"deadlock", []string{"Scfoo\nR*\n", "R*\n", ""}, nil, nil, true},
{"fail and hang", []string{"H\n", "Q 1\n"}, nil, []int{1}, false},
{"fail and hanging recv", []string{"R*\n", "Q 1\n"}, nil, []int{1}, false},
}
for _, tc := range testcases {
outputs := make([]bytes.Buffer, len(tc.inputs))
cmds := make([]*exec.Cmd, len(tc.inputs))
for i, input := range tc.inputs {
cmds[i] = exec.Command(testerPath)
cmds[i].Stdin = strings.NewReader(input)
cmds[i].Stdout = &outputs[i]
}
_, err := RunInstances(cmds, ioutil.Discard)
if _, ok := err.(ErrRemainingMessages); ok {
err = nil
}
if err != nil {
switch err := err.(type) {
case InstanceError:
ok := false
for _, i := range tc.expectedFails {
if err.ID == i {
ok = true
}
}
if !ok {
t.Errorf("test %s: unexpected error from RunInstances: %v", tc.name, err)
}
case ErrDeadlock:
if !tc.expectedDeadlock {
t.Errorf("test %s: unexpected deadlock", tc.name)
}
default:
t.Errorf("test %s: unexpected error from RunInstances: %v", tc.name, err)
}
continue
}
if len(tc.expectedFails) != 0 || tc.expectedDeadlock {
t.Errorf("test %s: unexpected success of RunInstances", tc.name)
continue
}
for i, want := range tc.expectedOutputs {
got := strings.Replace(outputs[i].String(), "\r\n", "\n", -1)
if got != want {
t.Errorf("test %s: wrong output from instance %d: got=%q, want=%q", tc.name, i, got, want)
}
}
}
}
func TestInstancesStartError(t *testing.T) {
cmds := []*exec.Cmd{exec.Command("/does/not/exist")}
_, err := RunInstances(cmds, ioutil.Discard)
if err == nil {
t.Errorf("expected an error when trying to run a nonexistent binary")
}
}
// TODO: check what happens when we send/recv message to/from an instance that doesn't exist
// TODO: check what happens when an instance claims that its CPU time goes backward