-
Notifications
You must be signed in to change notification settings - Fork 22
/
acs_test.go
138 lines (124 loc) · 2.85 KB
/
acs_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
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package hbbft
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// Test ACS with 4 good nodes. The result should be that at least the output
// of (N - f) nodes has been provided.
func TestACSGoodNodes(t *testing.T) {
inputs := map[int][]byte{
0: []byte("AAAAAA"),
1: []byte("BBBBBB"),
2: []byte("CCCCCC"),
3: []byte("DDDDDD"),
}
testCommonSubset(t, inputs)
}
func testCommonSubset(t *testing.T, inputs map[int][]byte) {
type acsResult struct {
nodeID uint64
results map[uint64][]byte
}
var (
resultCh = make(chan acsResult, 4)
nodes = makeACSNetwork(4)
messages = make(chan testMsg)
)
go func() {
for {
select {
case msg := <-messages:
acs := nodes[msg.msg.To]
err := acs.HandleMessage(msg.from, msg.msg.Payload.(*ACSMessage))
if err != nil {
t.Fatal(err)
}
for _, msg := range acs.messageQue.messages() {
go func(msg MessageTuple) {
messages <- testMsg{acs.ID, msg}
}(msg)
}
if output := acs.Output(); output != nil {
resultCh <- acsResult{acs.ID, output}
}
}
}
}()
for nodeID, value := range inputs {
assert.Nil(t, nodes[nodeID].InputValue(value))
for _, msg := range nodes[nodeID].messageQue.messages() {
messages <- testMsg{uint64(nodeID), msg}
time.Sleep(1 * time.Millisecond)
}
}
count := 0
for res := range resultCh {
assert.True(t, len(res.results) >= len(nodes)-1)
for id, result := range res.results {
assert.Equal(t, inputs[int(id)], result)
}
count++
if count == 4 {
break
}
}
}
func TestNewACS(t *testing.T) {
var (
id = uint64(0)
nodes = []uint64{0, 1, 2, 3}
acs = NewACS(Config{
N: len(nodes),
ID: id,
Nodes: nodes,
})
)
assert.Equal(t, len(nodes), len(acs.bbaInstances))
assert.Equal(t, len(nodes), len(acs.rbcInstances))
for i := range acs.rbcInstances {
_, ok := acs.bbaInstances[i]
assert.True(t, ok)
}
for i := range acs.bbaInstances {
_, ok := acs.bbaInstances[i]
assert.True(t, ok)
}
assert.Equal(t, id, acs.ID)
}
func TestACSOutputIsNilAfterConsuming(t *testing.T) {
acs := NewACS(Config{N: 4})
output := map[uint64][]byte{
1: []byte("this is it"),
}
acs.output = output
assert.Equal(t, output, acs.Output())
assert.Nil(t, acs.Output())
}
type testMsg struct {
from uint64
msg MessageTuple
}
func makeACSNetwork(n int) []*ACS {
network := make([]*ACS, n)
for i := 0; i < n; i++ {
network[i] = NewACS(Config{N: n, ID: uint64(i), Nodes: makeids(n)})
go network[i].run()
}
return network
}
func makeids(n int) []uint64 {
ids := make([]uint64, n)
for i := 0; i < n; i++ {
ids[i] = uint64(i)
}
return ids
}
// makeTransports is a test helper function for making n number of transports.
func makeTransports(n int) []Transport {
transports := make([]Transport, n)
for i := 0; i < n; i++ {
transports[i] = NewLocalTransport(uint64(i))
}
return transports
}