go.dedis.ch/onet/v4@v4.0.0-pre1/network/local_test.go (about) 1 package network 2 3 import ( 4 "strconv" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 "golang.org/x/xerrors" 11 ) 12 13 func TestLocalRouter(t *testing.T) { 14 addr := &ServerIdentity{Address: NewLocalAddress("127.0.0.1:2000")} 15 wrongAddr1 := &ServerIdentity{Address: NewTCPAddress(addr.Address.NetworkAddress())} 16 _, err := NewLocalRouter(wrongAddr1, tSuite) 17 if err == nil { 18 t.Error("Should have returned something..") 19 } 20 _, err = NewLocalRouter(addr, tSuite) 21 if err != nil { 22 t.Error("Should not have returned something") 23 } 24 25 } 26 27 func TestLocalListener(t *testing.T) { 28 addr := NewLocalAddress("127.0.0.1:2000") 29 wrongAddr1 := NewTCPAddress(addr.NetworkAddress()) 30 listener, err := NewLocalListener(wrongAddr1, tSuite) 31 if err == nil { 32 t.Error("Create listener with wrong address should fail") 33 } 34 defaultLocalManager.setListening(addr, func(c Conn) {}) 35 listener, err = NewLocalListener(addr, tSuite) 36 if err == nil { 37 t.Error("Create listener with already binded address should fail") 38 } 39 LocalReset() 40 41 listener, err = NewLocalListener(addr, tSuite) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 var ready = make(chan bool) 47 go func() { 48 ready <- true 49 err := listener.Listen(func(c Conn) {}) 50 if err != nil { 51 t.Error("Should not have had error while listening") 52 } 53 ready <- true 54 }() 55 56 <-ready 57 // give it some time 58 time.Sleep(20 * time.Millisecond) 59 if err := listener.Listen(func(c Conn) {}); err == nil { 60 t.Error("listener should have returned an error when Listen twice") 61 } 62 assert.Nil(t, listener.Stop()) 63 if err := listener.Stop(); err != nil { 64 t.Error("listener.Stop() twice should not returns an error") 65 } 66 <-ready 67 } 68 69 // Test whether a call to a conn.Close() will stop the remote Receive() call 70 func TestLocalConnCloseReceive(t *testing.T) { 71 addr := NewLocalAddress("127.0.0.1:2000") 72 listener, err := NewLocalListener(addr, tSuite) 73 if err != nil { 74 t.Fatal("Could not listen", err) 75 } 76 77 var ready = make(chan bool) 78 go func() { 79 ready <- true 80 listener.Listen(func(c Conn) { 81 ready <- true 82 assert.Nil(t, c.Close()) 83 ready <- true 84 }) 85 }() 86 <-ready 87 88 outgoing, err := NewLocalConnWithManager(defaultLocalManager, addr, addr, tSuite) 89 if err != nil { 90 t.Fatal("erro NewLocalConn:", err) 91 } 92 if outgoing.Type() != Local { 93 t.Error("Wrong type for Conn?") 94 } 95 if outgoing.Local() != addr { 96 t.Error("Wrong local addr for Conn!?") 97 } 98 <-ready 99 <-ready 100 _, err = outgoing.Receive() 101 assert.True(t, xerrors.Is(err, ErrClosed)) 102 assert.True(t, xerrors.Is(outgoing.Close(), ErrClosed)) 103 assert.Nil(t, listener.Stop()) 104 } 105 106 // Test if we can run two parallel local network using two different contexts 107 func TestLocalContext(t *testing.T) { 108 ctx1 := NewLocalManager() 109 ctx2 := NewLocalManager() 110 111 addrListener := NewLocalAddress("127.0.0.1:2000") 112 addrConn := NewLocalAddress("127.0.0.1:2001") 113 siListener := NewTestServerIdentity(addrListener) 114 siConn := NewTestServerIdentity(addrConn) 115 116 done1 := make(chan error) 117 done2 := make(chan error) 118 119 go testConnListener(ctx1, done1, siListener, siConn, 1) 120 go testConnListener(ctx2, done2, siListener, siConn, 2) 121 122 var confirmed int 123 for confirmed != 2 { 124 var err error 125 select { 126 case err = <-done1: 127 case err = <-done2: 128 } 129 130 if err != nil { 131 t.Fatal(err) 132 } 133 confirmed++ 134 } 135 } 136 137 // launch a listener, then a Conn and communicate their own address + individual 138 // val 139 func testConnListener(ctx *LocalManager, done chan error, listenA, connA *ServerIdentity, secret int) { 140 listener, err := NewLocalListenerWithManager(ctx, listenA.Address, tSuite) 141 if err != nil { 142 done <- err 143 return 144 } 145 146 var ok = make(chan error) 147 148 // make the listener send and receive a struct that only they can know (this 149 // listener + conn 150 handshake := func(c Conn, sending, receiving Address) error { 151 sentLen, err := c.Send(&AddressTest{sending, int64(secret)}) 152 if err != nil { 153 return xerrors.Errorf("sending: %v", err) 154 } 155 if sentLen == 0 { 156 return xerrors.Errorf("sentLen is zero") 157 } 158 159 p, err := c.Receive() 160 if err != nil { 161 return err 162 } 163 164 at := p.Msg.(*AddressTest) 165 if at.Addr != receiving { 166 return xerrors.New("Receiveid wrong address") 167 } 168 if at.Val != int64(secret) { 169 return xerrors.New("Received wrong secret") 170 } 171 return nil 172 } 173 174 go func() { 175 ok <- nil 176 listener.Listen(func(c Conn) { 177 ok <- nil 178 err := handshake(c, listenA.Address, connA.Address) 179 ok <- err 180 }) 181 ok <- nil 182 }() 183 // wait go routine to start 184 <-ok 185 186 // trick to use host because it already tries multiple times to connect if 187 // the listening routine is not up yet. 188 h, err := NewLocalHostWithManager(ctx, connA.Address, tSuite) 189 if err != nil { 190 done <- err 191 return 192 } 193 c, err := h.Connect(listenA) 194 if err != nil { 195 done <- err 196 return 197 } 198 199 // wait listening function to start for the incoming conn 200 <-ok 201 err = handshake(c, connA.Address, listenA.Address) 202 if err != nil { 203 done <- err 204 return 205 } 206 // wait for any err of the handshake from the listening PoV 207 err = <-ok 208 if err != nil { 209 done <- err 210 return 211 } 212 if err := c.Close(); err != nil { 213 done <- err 214 return 215 } 216 listener.Stop() 217 <-ok 218 done <- nil 219 } 220 221 func TestLocalConnDiffAddress(t *testing.T) { 222 testLocalConn(t, NewLocalAddress("127.0.0.1:2000"), NewLocalAddress("127.0.0.1:2001")) 223 } 224 225 func TestLocalConnSameAddress(t *testing.T) { 226 testLocalConn(t, NewLocalAddress("127.0.0.1:2000"), NewLocalAddress("127.0.0.1:2000")) 227 } 228 229 func testLocalConn(t *testing.T, a1, a2 Address) { 230 addr1 := a1 231 addr2 := a2 232 233 listener, err := NewLocalListener(addr1, tSuite) 234 if err != nil { 235 t.Fatal("Could not listen", err) 236 } 237 238 var ready = make(chan bool) 239 var incomingConn = make(chan bool) 240 var outgoingConn = make(chan bool) 241 go func() { 242 ready <- true 243 listener.Listen(func(c Conn) { 244 incomingConn <- true 245 nm, err := c.Receive() 246 assert.Nil(t, err) 247 assert.Equal(t, int64(3), nm.Msg.(*SimpleMessage).I) 248 // acknoledge the message 249 incomingConn <- true 250 sentLen, err := c.Send(&SimpleMessage{3}) 251 assert.Nil(t, err) 252 assert.NotZero(t, sentLen) 253 //wait ack 254 <-outgoingConn 255 assert.Equal(t, 2, listener.manager.count()) 256 // close connection 257 assert.Nil(t, c.Close()) 258 incomingConn <- true 259 260 }) 261 ready <- true 262 }() 263 <-ready 264 265 outgoing, err := NewLocalConnWithManager(defaultLocalManager, addr2, addr1, tSuite) 266 if err != nil { 267 t.Fatal("erro NewLocalConn:", err) 268 } 269 270 // check if connection is opened on the listener 271 <-incomingConn 272 // send stg and wait for ack 273 sentLen, err := outgoing.Send(&SimpleMessage{3}) 274 assert.Nil(t, err) 275 assert.NotZero(t, sentLen) 276 <-incomingConn 277 278 // receive stg and send ack 279 nm, err := outgoing.Receive() 280 assert.Nil(t, err) 281 assert.Equal(t, int64(3), nm.Msg.(*SimpleMessage).I) 282 outgoingConn <- true 283 284 <-incomingConn 285 // close the incoming conn, so Receive here should return an error 286 nm, err = outgoing.Receive() 287 if !xerrors.Is(err, ErrClosed) { 288 t.Error("Receive should have returned an error") 289 } 290 assert.True(t, xerrors.Is(outgoing.Close(), ErrClosed)) 291 // close the listener 292 assert.Nil(t, listener.Stop()) 293 <-ready 294 } 295 296 func TestLocalManyConn(t *testing.T) { 297 nbrConn := 3 298 addr := NewLocalAddress("127.0.0.1:2000") 299 listener, err := NewLocalListener(addr, tSuite) 300 if err != nil { 301 t.Fatal("Could not setup listener:", err) 302 } 303 var wg sync.WaitGroup 304 go func() { 305 listener.Listen(func(c Conn) { 306 _, err := c.Receive() 307 assert.Nil(t, err) 308 sentLen, err := c.Send(&SimpleMessage{3}) 309 assert.Nil(t, err) 310 assert.NotZero(t, sentLen) 311 }) 312 }() 313 314 if !waitListeningUp(addr) { 315 t.Fatal("Can't get listener up") 316 } 317 wg.Add(nbrConn) 318 for i := 1; i <= nbrConn; i++ { 319 go func(j int) { 320 a := NewLocalAddress("127.0.0.1:" + strconv.Itoa(2000+j)) 321 c, err := NewLocalConnWithManager(defaultLocalManager, a, addr, tSuite) 322 if err != nil { 323 t.Fatal(err) 324 } 325 sentLen, err := c.Send(&SimpleMessage{3}) 326 assert.Nil(t, err) 327 assert.NotZero(t, sentLen) 328 nm, err := c.Receive() 329 assert.Nil(t, err) 330 assert.Equal(t, int64(3), nm.Msg.(*SimpleMessage).I) 331 assert.Nil(t, c.Close()) 332 wg.Done() 333 }(i) 334 } 335 336 wg.Wait() 337 listener.Stop() 338 } 339 340 func TestDefaultLocalManager(t *testing.T) { 341 defaultLocalManager.setListening(NewLocalAddress("127.0.0.1"), func(c Conn) {}) 342 assert.Equal(t, 1, len(defaultLocalManager.listening)) 343 LocalReset() 344 assert.Equal(t, 0, len(defaultLocalManager.listening)) 345 } 346 347 func waitListeningUp(addr Address) bool { 348 for i := 0; i < 5; i++ { 349 if defaultLocalManager.isListening(addr) { 350 return true 351 } 352 time.Sleep(50 * time.Millisecond) 353 } 354 return false 355 } 356 357 func NewTestLocalHost(port int) (*LocalHost, error) { 358 addr := NewLocalAddress("127.0.0.1:" + strconv.Itoa(port)) 359 return NewLocalHost(addr, tSuite) 360 } 361 362 type AddressTest struct { 363 Addr Address 364 Val int64 365 } 366 367 var AddressTestType = RegisterMessage(&AddressTest{})