func (s *XLSuite) TestEncoding(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_ENCODING") } const K = 2 nodes, accs := xn.MockLocalHostCluster(K) // lazy way to get keys defer func() { for i := 0; i < K; i++ { if accs[i] != nil { accs[i].Close() } } }() peer := nodes[0].GetPeer(0) pID := peer.GetNodeID().Value() pck, err := xc.RSAPubKeyToWire(peer.GetCommsPublicKey()) c.Assert(err, IsNil) psk, err := xc.RSAPubKeyToWire(peer.GetSigPublicKey()) c.Assert(err, IsNil) cmd := XLatticeMsg_Hello one := uint64(1) msg := &XLatticeMsg{ Op: &cmd, MsgN: &one, ID: pID, CommsKey: pck, SigKey: psk, } wired, err := EncodePacket(msg) c.Assert(err, IsNil) c.Assert(wired, Not(IsNil)) backAgain, err := DecodePacket(wired) c.Assert(err, IsNil) c.Assert(backAgain, Not(IsNil)) rewired, err := EncodePacket(msg) c.Assert(err, IsNil) c.Assert(rewired, Not(IsNil)) c.Assert(len(wired), Equals, len(rewired)) for i := 0; i < len(wired); i++ { c.Assert(wired[i], Equals, rewired[i]) } // DEBUG //fmt.Printf(" len ck %d bytes\n", len(msg.GetCommsKey())) // 294 //fmt.Printf(" len sk %d bytes\n", len(msg.GetSigKey())) // 294 //fmt.Println(" end TestEncoding") // END }
func (s *XLSuite) TestHelloHandler(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_HELLO_HANDLER") } // Create a node and add a mock peer. This is a cluster of 2. nodes, accs := xn.MockLocalHostCluster(2) defer func() { for i := 0; i < 2; i++ { if accs[i] != nil { accs[i].Close() } } }() myNode, peerNode := nodes[0], nodes[1] meAsPeer := peerNode.GetPeer(0) myAcc, peerAcc := accs[0], accs[1] _ = peerAcc // never used c.Assert(myAcc, Not(IsNil)) myAccEP := myAcc.GetEndPoint() myCtor, err := xt.NewTcpConnector(myAccEP) c.Assert(err, IsNil) // myNode's server side stopCh := make(chan bool, 1) // has buffer so won't block stoppedCh := make(chan bool, 1) go func() { for { cnx, err := myAcc.Accept() if err != nil { break } // each connection handled by a separate goroutine go func() { _, _ = NewInHandler(myNode, cnx, stopCh, stoppedCh) }() } }() // -- WELL-FORMED HELLO ----------------------------------------- // Known peer sends Hello with all parameters correct. We reply // with an Ack and advance state to open. conn, err := myCtor.Connect(xt.ANY_TCP_END_POINT) c.Assert(err, IsNil) c.Assert(conn, Not(IsNil)) cnx2 := conn.(*xt.TcpConnection) defer cnx2.Close() oh := &OutHandler{ Node: peerNode, CnxHandler: CnxHandler{Cnx: cnx2, Peer: meAsPeer}} // manually create and send a hello message - // XXX HELLO_MSG IS OBSOLETE; it's done with RSA/AES handshake peerHello, err := MakeHelloMsg(peerNode) c.Assert(err, IsNil) c.Assert(peerHello, Not(IsNil)) data, err := EncodePacket(peerHello) c.Assert(err, IsNil) c.Assert(data, Not(IsNil)) count, err := cnx2.Write(data) c.Assert(err, IsNil) c.Assert(count, Equals, len(data)) oh.MsgN = ONE // end manual hello ------------------------- time.Sleep(100 * time.Millisecond) // wait for ack ack, err := oh.readMsg() c.Assert(err, IsNil) c.Assert(ack, Not(IsNil)) // verify msg returned is an ack and has the correct parameters c.Assert(ack.GetOp(), Equals, XLatticeMsg_Ack) c.Assert(ack.GetMsgN(), Equals, TWO) c.Assert(ack.GetYourMsgN(), Equals, ONE) // FOO // -- KEEPALIVE ------------------------------------------------- cmd := XLatticeMsg_KeepAlive keepAlive := &XLatticeMsg{ Op: &cmd, MsgN: &THREE, } data, err = EncodePacket(keepAlive) c.Assert(err, IsNil) c.Assert(data, Not(IsNil)) count, err = cnx2.Write(data) c.Assert(err, IsNil) c.Assert(count, Equals, len(data)) // Wait for ack. In a better world we time out if an ack is not // received in some short period rather than blocking forever. ack, err = oh.readMsg() c.Assert(err, IsNil) c.Assert(ack, Not(IsNil)) // verify msg returned is an ack and has the correct parameters c.Assert(ack.GetOp(), Equals, XLatticeMsg_Ack) c.Assert(ack.GetMsgN(), Equals, FOUR) c.Assert(ack.GetYourMsgN(), Equals, THREE) // -- BYE ------------------------------------------------------- cmd = XLatticeMsg_Bye bye := &XLatticeMsg{ Op: &cmd, MsgN: &FIVE, } data, err = EncodePacket(bye) c.Assert(err, IsNil) c.Assert(data, Not(IsNil)) count, err = cnx2.Write(data) c.Assert(err, IsNil) c.Assert(count, Equals, len(data)) // Wait for ack. In a better world we time out if an ack is not // received in some short period rather than blocking forever. ack, err = oh.readMsg() c.Assert(err, IsNil) c.Assert(ack, Not(IsNil)) // verify msg returned is an ack and has the correct parameters c.Assert(ack.GetOp(), Equals, XLatticeMsg_Ack) c.Assert(ack.GetMsgN(), Equals, SIX) c.Assert(ack.GetYourMsgN(), Equals, FIVE) // -- STOP THE SERVER ------------------------------------------- stopCh <- true select { case <-stoppedCh: case <-time.After(100 * time.Millisecond): } } // END HANDLER
func (s *XLSuite) TestSecondHello(c *C) { if VERBOSITY > 0 { fmt.Println("TEST_SECOND_HELLO") } // Create a node and add a mock peer. This is a cluster of 2. nodes, accs := xn.MockLocalHostCluster(2) defer func() { for i := 0; i < 2; i++ { if accs[i] != nil { accs[i].Close() } } }() serverNode, clientNode := nodes[0], nodes[1] serverAsPeer := clientNode.GetPeer(0) serverAcc := accs[0] c.Assert(serverAcc, Not(IsNil)) serverAccEP := serverAcc.GetEndPoint() serverCtor, err := xt.NewTcpConnector(serverAccEP) c.Assert(err, IsNil) // serverNode's server side stopCh := make(chan bool, 1) stoppedCh := make(chan bool, 1) // XXX If you comment out this goroutine, there are no mysterious // failures. go func() { for { cnx, err := serverAcc.Accept() // ADDING THIS ELIMINATES MYSTERY FAILURES if err != nil { break } // each connection handled by a separate goroutine go func() { _, _ = NewInHandler(serverNode, cnx, stopCh, stoppedCh) }() } }() // END FUNC // -- WELL-FORMED HELLO ----------------------------------------- // Known peer sends Hello with all parameters correct. Server // replies with an Ack and advance state to open. conn, err := serverCtor.Connect(xt.ANY_TCP_END_POINT) c.Assert(err, IsNil) c.Assert(conn, Not(IsNil)) cnx2 := conn.(*xt.TcpConnection) defer cnx2.Close() oh := &OutHandler{Node: clientNode, CnxHandler: CnxHandler{Cnx: cnx2, Peer: serverAsPeer}} err = oh.SendHello() c.Assert(err, IsNil) // wait for ack ack, err := oh.readMsg() c.Assert(err, IsNil) // XXX "EOF" instead c.Assert(ack, Not(IsNil)) // verify msg returned is an ack and has the correct parameters c.Assert(ack.GetOp(), Equals, XLatticeMsg_Ack) c.Assert(ack.GetMsgN(), Equals, TWO) c.Assert(ack.GetYourMsgN(), Equals, ONE) // FOO // -- SECOND WELL-FORMED HELLO ---------------------------------- // manually create and send a hello message - // XXX HELLO_MSG IS OBSOLETE; it's done with RSA/AES handshake peerHello, err := MakeHelloMsg(clientNode) c.Assert(err, IsNil) c.Assert(peerHello, Not(IsNil)) data, err := EncodePacket(peerHello) c.Assert(err, IsNil) c.Assert(data, Not(IsNil)) count, err := cnx2.Write(data) c.Assert(err, IsNil) c.Assert(count, Equals, len(data)) oh.MsgN = ONE // end manual hello ------------------------- // wait for error message reply, err := oh.readMsg() c.Assert(err, IsNil) c.Assert(reply, Not(IsNil)) // verify msg returned is an reply and has the correct parameters c.Assert(reply.GetOp(), Equals, XLatticeMsg_Error) c.Assert(reply.GetMsgN(), Equals, FOUR) // -- STOP THE SERVER ------------------------------------------- stopCh <- true select { case <-stoppedCh: case <-time.After(100 * time.Millisecond): } }