func TestPeerOnGossip(t *testing.T) { for _, testcase := range []struct { initial map[mesh.PeerName]int msg map[mesh.PeerName]int want map[mesh.PeerName]int }{ { map[mesh.PeerName]int{}, map[mesh.PeerName]int{123: 1, 456: 2}, map[mesh.PeerName]int{123: 1, 456: 2}, }, { map[mesh.PeerName]int{123: 1}, map[mesh.PeerName]int{123: 0, 456: 2}, map[mesh.PeerName]int{456: 2}, }, { map[mesh.PeerName]int{123: 9}, map[mesh.PeerName]int{123: 8}, nil, }, } { p := newPeer(mesh.PeerName(999), log.New(ioutil.Discard, "", 0)) p.st.mergeComplete(testcase.initial) var buf bytes.Buffer if err := gob.NewEncoder(&buf).Encode(testcase.msg); err != nil { t.Fatal(err) } delta, err := p.OnGossip(buf.Bytes()) if err != nil { t.Errorf("%v OnGossip %v: %v", testcase.initial, testcase.msg, err) continue } if want := testcase.want; want == nil { if delta != nil { t.Errorf("%v OnGossip %v: want nil, have non-nil", testcase.initial, testcase.msg) } } else { if have := delta.(*state).set; !reflect.DeepEqual(want, have) { t.Errorf("%v OnGossip %v: want %v, have %v", testcase.initial, testcase.msg, want, have) } } } }
// Restart a node func (m *Model) restart(node *TestNode) { node.Node = NewNode(mesh.PeerName(m.nextID), mesh.PeerUID(m.r.Int63()), m.quorum) m.nextID++ node.Propose() // The node is now ignorant, so we need to mark the links into // the node as ready. for _, l := range node.links { if !l.to.isolated { m.readyLink(l.converse) } } // If a consensus was just accepted due to this node accepting // it, without other nodes hearing of it, and we then restart // this node, then a different consensus can occur later on. // If a tree falls with no one to hear it, does it make a // sound? node.firstConsensus = AcceptedValue{} }
// Make a network of nodes with random topology func makeRandomModel(params *TestParams, r *rand.Rand, t *testing.T) *Model { m := Model{ t: t, r: r, quorum: params.nodeCount/2 + 1, nodes: make([]TestNode, params.nodeCount), readyLinks: []*Link{}, nextID: params.nodeCount + 1, } for i := range m.nodes { m.nodes[i].Node = NewNode(mesh.PeerName(i/2+1), mesh.PeerUID(r.Int63()), m.quorum) m.nodes[i].Propose() } for i := 1; i < len(m.nodes); i++ { // was node i connected to the other nodes yet? connected := false for j := 0; j < i; j++ { if r.Float32() < params.connectedProb { connected = true m.addLink(&m.nodes[i], &m.nodes[j]) } } if !connected { // node i must be connected into the graph // somewhere. So if we didn't connect it // already, this is a last resort. m.addLink(&m.nodes[i], &m.nodes[r.Intn(i)]) } } return &m }
func checkSuccess(t *testing.T, nameStr string, expected uint64) { actual, err := mesh.PeerNameFromString(nameStr) require.NoError(t, err) require.Equal(t, mesh.PeerName(expected), actual) }