github.com/Ethersocial/go-esn@v0.3.7/swarm/network/protocol_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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 go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY 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 go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package network 18 19 import ( 20 "flag" 21 "fmt" 22 "os" 23 "sync" 24 "testing" 25 26 "github.com/ethersocial/go-esn/log" 27 "github.com/ethersocial/go-esn/p2p" 28 "github.com/ethersocial/go-esn/p2p/enode" 29 "github.com/ethersocial/go-esn/p2p/protocols" 30 p2ptest "github.com/ethersocial/go-esn/p2p/testing" 31 ) 32 33 const ( 34 TestProtocolVersion = 7 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 type testStore struct { 48 sync.Mutex 49 50 values map[string][]byte 51 } 52 53 func newTestStore() *testStore { 54 return &testStore{values: make(map[string][]byte)} 55 } 56 57 func (t *testStore) Load(key string) ([]byte, error) { 58 t.Lock() 59 defer t.Unlock() 60 v, ok := t.values[key] 61 if !ok { 62 return nil, fmt.Errorf("key not found: %s", key) 63 } 64 return v, nil 65 } 66 67 func (t *testStore) Save(key string, v []byte) error { 68 t.Lock() 69 defer t.Unlock() 70 t.values[key] = v 71 return nil 72 } 73 74 func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id enode.ID) []p2ptest.Exchange { 75 76 return []p2ptest.Exchange{ 77 { 78 Expects: []p2ptest.Expect{ 79 { 80 Code: 0, 81 Msg: lhs, 82 Peer: id, 83 }, 84 }, 85 }, 86 { 87 Triggers: []p2ptest.Trigger{ 88 { 89 Code: 0, 90 Msg: rhs, 91 Peer: id, 92 }, 93 }, 94 }, 95 } 96 } 97 98 func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester { 99 cs := make(map[string]chan bool) 100 101 srv := func(p *BzzPeer) error { 102 defer func() { 103 if cs[p.ID().String()] != nil { 104 close(cs[p.ID().String()]) 105 } 106 }() 107 return run(p) 108 } 109 110 protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error { 111 return srv(&BzzPeer{Peer: protocols.NewPeer(p, rw, spec), BzzAddr: NewAddr(p.Node())}) 112 } 113 114 s := p2ptest.NewProtocolTester(t, addr.ID(), n, protocol) 115 116 for _, node := range s.Nodes { 117 cs[node.ID().String()] = make(chan bool) 118 } 119 120 return &bzzTester{ 121 addr: addr, 122 ProtocolTester: s, 123 cs: cs, 124 } 125 } 126 127 type bzzTester struct { 128 *p2ptest.ProtocolTester 129 addr *BzzAddr 130 cs map[string]chan bool 131 bzz *Bzz 132 } 133 134 func newBzz(addr *BzzAddr, lightNode bool) *Bzz { 135 config := &BzzConfig{ 136 OverlayAddr: addr.Over(), 137 UnderlayAddr: addr.Under(), 138 HiveParams: NewHiveParams(), 139 NetworkID: DefaultNetworkID, 140 LightNode: lightNode, 141 } 142 kad := NewKademlia(addr.OAddr, NewKadParams()) 143 bzz := NewBzz(config, kad, nil, nil, nil) 144 return bzz 145 } 146 147 func newBzzHandshakeTester(t *testing.T, n int, addr *BzzAddr, lightNode bool) *bzzTester { 148 bzz := newBzz(addr, lightNode) 149 pt := p2ptest.NewProtocolTester(t, addr.ID(), n, bzz.runBzz) 150 151 return &bzzTester{ 152 addr: addr, 153 ProtocolTester: pt, 154 bzz: bzz, 155 } 156 } 157 158 // should test handshakes in one exchange? parallelisation 159 func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error { 160 var peers []enode.ID 161 id := rhs.Addr.ID() 162 if len(disconnects) > 0 { 163 for _, d := range disconnects { 164 peers = append(peers, d.Peer) 165 } 166 } else { 167 peers = []enode.ID{id} 168 } 169 170 if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, id)...); err != nil { 171 return err 172 } 173 174 if len(disconnects) > 0 { 175 return s.TestDisconnected(disconnects...) 176 } 177 178 // If we don't expect disconnect, ensure peers remain connected 179 err := s.TestDisconnected(&p2ptest.Disconnect{ 180 Peer: s.Nodes[0].ID(), 181 Error: nil, 182 }) 183 184 if err == nil { 185 return fmt.Errorf("Unexpected peer disconnect") 186 } 187 188 if err.Error() != "timed out waiting for peers to disconnect" { 189 return err 190 } 191 192 return nil 193 } 194 195 func correctBzzHandshake(addr *BzzAddr, lightNode bool) *HandshakeMsg { 196 return &HandshakeMsg{ 197 Version: TestProtocolVersion, 198 NetworkID: TestProtocolNetworkID, 199 Addr: addr, 200 LightNode: lightNode, 201 } 202 } 203 204 func TestBzzHandshakeNetworkIDMismatch(t *testing.T) { 205 lightNode := false 206 addr := RandomAddr() 207 s := newBzzHandshakeTester(t, 1, addr, lightNode) 208 node := s.Nodes[0] 209 210 err := s.testHandshake( 211 correctBzzHandshake(addr, lightNode), 212 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: 321, Addr: NewAddr(node)}, 213 &p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")}, 214 ) 215 216 if err != nil { 217 t.Fatal(err) 218 } 219 } 220 221 func TestBzzHandshakeVersionMismatch(t *testing.T) { 222 lightNode := false 223 addr := RandomAddr() 224 s := newBzzHandshakeTester(t, 1, addr, lightNode) 225 node := s.Nodes[0] 226 227 err := s.testHandshake( 228 correctBzzHandshake(addr, lightNode), 229 &HandshakeMsg{Version: 0, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)}, 230 &p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= %d)", TestProtocolVersion)}, 231 ) 232 233 if err != nil { 234 t.Fatal(err) 235 } 236 } 237 238 func TestBzzHandshakeSuccess(t *testing.T) { 239 lightNode := false 240 addr := RandomAddr() 241 s := newBzzHandshakeTester(t, 1, addr, lightNode) 242 node := s.Nodes[0] 243 244 err := s.testHandshake( 245 correctBzzHandshake(addr, lightNode), 246 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)}, 247 ) 248 249 if err != nil { 250 t.Fatal(err) 251 } 252 } 253 254 func TestBzzHandshakeLightNode(t *testing.T) { 255 var lightNodeTests = []struct { 256 name string 257 lightNode bool 258 }{ 259 {"on", true}, 260 {"off", false}, 261 } 262 263 for _, test := range lightNodeTests { 264 t.Run(test.name, func(t *testing.T) { 265 randomAddr := RandomAddr() 266 pt := newBzzHandshakeTester(t, 1, randomAddr, false) 267 node := pt.Nodes[0] 268 addr := NewAddr(node) 269 270 err := pt.testHandshake( 271 correctBzzHandshake(randomAddr, false), 272 &HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: addr, LightNode: test.lightNode}, 273 ) 274 275 if err != nil { 276 t.Fatal(err) 277 } 278 279 if pt.bzz.handshakes[node.ID()].LightNode != test.lightNode { 280 t.Fatalf("peer LightNode flag is %v, should be %v", pt.bzz.handshakes[node.ID()].LightNode, test.lightNode) 281 } 282 }) 283 } 284 }