github.com/susy-go/susy-graviton@v0.0.0-20190614130430-36cddae42305/swarm/network/protocol_test.go (about) 1 // Copyleft 2016 The susy-graviton Authors 2 // This file is part of the susy-graviton library. 3 // 4 // The susy-graviton library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The susy-graviton library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MSRCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the susy-graviton library. If not, see <http://www.gnu.org/licenses/>. 16 17 package network 18 19 import ( 20 "flag" 21 "fmt" 22 "os" 23 "testing" 24 "time" 25 26 "github.com/susy-go/susy-graviton/log" 27 "github.com/susy-go/susy-graviton/p2p" 28 "github.com/susy-go/susy-graviton/p2p/enode" 29 "github.com/susy-go/susy-graviton/p2p/protocols" 30 p2ptest "github.com/susy-go/susy-graviton/p2p/testing" 31 ) 32 33 const ( 34 TestProtocolVersion = 8 35 TestProtocolNetworkID = 3 36 ) 37 38 var ( 39 loglevel = flag.Int("loglevel", 2, "verbosity of logs") 40 ) 41 42 func init() { 43 flag.Parse() 44 log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) 45 } 46 47 func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id enode.ID) []p2ptest.Exchange { 48 return []p2ptest.Exchange{ 49 { 50 Expects: []p2ptest.Expect{ 51 { 52 Code: 0, 53 Msg: lhs, 54 Peer: id, 55 }, 56 }, 57 }, 58 { 59 Triggers: []p2ptest.Trigger{ 60 { 61 Code: 0, 62 Msg: rhs, 63 Peer: id, 64 }, 65 }, 66 }, 67 } 68 } 69 70 func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester { 71 cs := make(map[string]chan bool) 72 73 srv := func(p *BzzPeer) error { 74 defer func() { 75 if cs[p.ID().String()] != nil { 76 close(cs[p.ID().String()]) 77 } 78 }() 79 return run(p) 80 } 81 82 protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error { 83 return srv(&BzzPeer{Peer: protocols.NewPeer(p, rw, spec), BzzAddr: NewAddr(p.Node())}) 84 } 85 86 s := p2ptest.NewProtocolTester(addr.ID(), n, protocol) 87 88 for _, node := range s.Nodes { 89 cs[node.ID().String()] = make(chan bool) 90 } 91 92 return &bzzTester{ 93 addr: addr, 94 ProtocolTester: s, 95 cs: cs, 96 } 97 } 98 99 type bzzTester struct { 100 *p2ptest.ProtocolTester 101 addr *BzzAddr 102 cs map[string]chan bool 103 bzz *Bzz 104 } 105 106 func newBzz(addr *BzzAddr, lightNode bool) *Bzz { 107 config := &BzzConfig{ 108 OverlayAddr: addr.Over(), 109 UnderlayAddr: addr.Under(), 110 HiveParams: NewHiveParams(), 111 NetworkID: DefaultNetworkID, 112 LightNode: lightNode, 113 } 114 kad := NewKademlia(addr.OAddr, NewKadParams()) 115 bzz := NewBzz(config, kad, nil, nil, nil) 116 return bzz 117 } 118 119 func newBzzHandshakeTester(n int, addr *BzzAddr, lightNode bool) *bzzTester { 120 bzz := newBzz(addr, lightNode) 121 pt := p2ptest.NewProtocolTester(addr.ID(), n, bzz.runBzz) 122 123 return &bzzTester{ 124 addr: addr, 125 ProtocolTester: pt, 126 bzz: bzz, 127 } 128 } 129 130 // should test handshakes in one exchange? parallelisation 131 func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error { 132 if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, rhs.Addr.ID())...); err != nil { 133 return err 134 } 135 136 if len(disconnects) > 0 { 137 return s.TestDisconnected(disconnects...) 138 } 139 140 // If we don't expect disconnect, ensure peers remain connected 141 err := s.TestDisconnected(&p2ptest.Disconnect{ 142 Peer: s.Nodes[0].ID(), 143 Error: nil, 144 }) 145 146 if err == nil { 147 return fmt.Errorf("Unexpected peer disconnect") 148 } 149 150 if err.Error() != "timed out waiting for peers to disconnect" { 151 return err 152 } 153 154 return nil 155 } 156 157 func correctBzzHandshake(addr *BzzAddr, lightNode bool) *HandshakeMsg { 158 return &HandshakeMsg{ 159 Version: TestProtocolVersion, 160 NetworkID: TestProtocolNetworkID, 161 Addr: addr, 162 LightNode: lightNode, 163 } 164 } 165 166 func TestBzzHandshakeNetworkIDMismatch(t *testing.T) { 167 lightNode := false 168 addr := RandomAddr() 169 s := newBzzHandshakeTester(1, addr, lightNode) 170 node := s.Nodes[0] 171 172 err := s.testHandshake( 173 correctBzzHandshake(addr, lightNode), 174 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: 321, Addr: NewAddr(node)}, 175 &p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")}, 176 ) 177 178 if err != nil { 179 t.Fatal(err) 180 } 181 } 182 183 func TestBzzHandshakeVersionMismatch(t *testing.T) { 184 lightNode := false 185 addr := RandomAddr() 186 s := newBzzHandshakeTester(1, addr, lightNode) 187 node := s.Nodes[0] 188 189 err := s.testHandshake( 190 correctBzzHandshake(addr, lightNode), 191 &HandshakeMsg{Version: 0, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)}, 192 &p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= %d)", TestProtocolVersion)}, 193 ) 194 195 if err != nil { 196 t.Fatal(err) 197 } 198 } 199 200 func TestBzzHandshakeSuccess(t *testing.T) { 201 lightNode := false 202 addr := RandomAddr() 203 s := newBzzHandshakeTester(1, addr, lightNode) 204 node := s.Nodes[0] 205 206 err := s.testHandshake( 207 correctBzzHandshake(addr, lightNode), 208 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)}, 209 ) 210 211 if err != nil { 212 t.Fatal(err) 213 } 214 } 215 216 func TestBzzHandshakeLightNode(t *testing.T) { 217 var lightNodeTests = []struct { 218 name string 219 lightNode bool 220 }{ 221 {"on", true}, 222 {"off", false}, 223 } 224 225 for _, test := range lightNodeTests { 226 t.Run(test.name, func(t *testing.T) { 227 randomAddr := RandomAddr() 228 pt := newBzzHandshakeTester(1, randomAddr, false) 229 230 node := pt.Nodes[0] 231 addr := NewAddr(node) 232 233 err := pt.testHandshake( 234 correctBzzHandshake(randomAddr, false), 235 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: addr, LightNode: test.lightNode}, 236 ) 237 238 if err != nil { 239 t.Fatal(err) 240 } 241 242 select { 243 244 case <-pt.bzz.handshakes[node.ID()].done: 245 if pt.bzz.handshakes[node.ID()].LightNode != test.lightNode { 246 t.Fatalf("peer LightNode flag is %v, should be %v", pt.bzz.handshakes[node.ID()].LightNode, test.lightNode) 247 } 248 case <-time.After(10 * time.Second): 249 t.Fatal("test timeout") 250 } 251 }) 252 } 253 }