go.dedis.ch/onet/v4@v4.0.0-pre1/network/router_test.go (about)

     1  package network
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/require"
     9  	"go.dedis.ch/onet/v4/log"
    10  	"golang.org/x/xerrors"
    11  )
    12  
    13  func NewTestRouterTCP(port int) (*Router, error) {
    14  	h, err := NewTestTCPHost(port)
    15  	if err != nil {
    16  		return nil, xerrors.Errorf("tcp host: %v", err)
    17  	}
    18  	h.sid.Address = h.TCPListener.Address()
    19  	r := NewRouter(h.sid, h)
    20  	r.UnauthOk = true
    21  	return r, nil
    22  }
    23  
    24  func NewTestRouterLocal(port int) (*Router, error) {
    25  	h, err := NewTestLocalHost(port)
    26  	if err != nil {
    27  		return nil, xerrors.Errorf("local host: %v", err)
    28  	}
    29  	id := NewTestServerIdentity(h.addr)
    30  	return NewRouter(id, h), nil
    31  }
    32  
    33  type routerFactory func(port int) (*Router, error)
    34  
    35  // Test if router fits the interface such as calling Run(), then Stop(),
    36  // should return
    37  func TestRouterTCP(t *testing.T) {
    38  	testRouter(t, NewTestRouterTCP)
    39  }
    40  func TestRouterLocal(t *testing.T) {
    41  	testRouter(t, NewTestRouterLocal)
    42  }
    43  
    44  func testRouter(t *testing.T, fac routerFactory) {
    45  	h, err := fac(2004)
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	var stop = make(chan bool)
    50  	go func() {
    51  		stop <- true
    52  		h.Start()
    53  		stop <- true
    54  	}()
    55  	<-stop
    56  	// Time needed so the listener is up. Equivalent to "connecting ourself" as
    57  	// we had before.
    58  	time.Sleep(250 * time.Millisecond)
    59  	h.Stop()
    60  	select {
    61  	case <-stop:
    62  		return
    63  	case <-time.After(500 * time.Millisecond):
    64  		t.Fatal("TcpHost should have returned from Run() by now")
    65  	}
    66  }
    67  
    68  // Test connection of multiple Hosts and sending messages back and forth
    69  // also tests for the counterIO interface that it works well
    70  func TestRouterErrorHandling(t *testing.T) {
    71  	h1, err1 := NewTestRouterTCP(2109)
    72  	h2, err2 := NewTestRouterTCP(2110)
    73  	if err1 != nil || err2 != nil {
    74  		t.Fatal("Could not setup hosts")
    75  	}
    76  
    77  	go h1.Start()
    78  	go h2.Start()
    79  
    80  	defer func() {
    81  		h1.Stop()
    82  	}()
    83  
    84  	// tests the setting error handler
    85  	require.NotNil(t, h1.connectionErrorHandlers)
    86  	if len(h1.connectionErrorHandlers) != 0 {
    87  		t.Error("errorHandlers should start empty")
    88  	}
    89  	errHandlerCalled := make(chan bool, 1)
    90  	errHandler := func(remote *ServerIdentity) {
    91  		errHandlerCalled <- true
    92  	}
    93  	h1.AddErrorHandler(errHandler)
    94  	if len(h1.connectionErrorHandlers) != 1 {
    95  		t.Error("errorHandlers should now hold one function")
    96  	}
    97  
    98  	//register handlers
    99  	proc := &simpleMessageProc{t, make(chan SimpleMessage)}
   100  	h1.RegisterProcessor(proc, SimpleMessageType)
   101  	h2.RegisterProcessor(proc, SimpleMessageType)
   102  
   103  	msgSimple := &SimpleMessage{3}
   104  	sentLen, err := h1.Send(h2.ServerIdentity, msgSimple)
   105  	require.Nil(t, err)
   106  	require.NotZero(t, sentLen)
   107  	decoded := <-proc.relay
   108  	require.Equal(t, int64(3), decoded.I)
   109  	sentLen, err = h2.Send(h1.ServerIdentity, msgSimple)
   110  	require.Nil(t, err)
   111  	require.NotZero(t, sentLen)
   112  	decoded = <-proc.relay
   113  
   114  	//stop node 2
   115  	h2.Stop()
   116  
   117  	// test if the error handler was called
   118  	select {
   119  	case <-errHandlerCalled:
   120  		// all good
   121  	case <-time.After(250 * time.Millisecond):
   122  		t.Error("Error handler should have been called after a disconnection")
   123  	}
   124  }
   125  
   126  func TestRouterSendToSelf(t *testing.T) {
   127  	r, err := NewTestRouterTCP(0)
   128  	require.Nil(t, err)
   129  
   130  	go r.Start()
   131  
   132  	defer func() {
   133  		r.Stop()
   134  	}()
   135  
   136  	// Need the "1" because sending message through channel in the same
   137  	// goroutine, will deadlock otherwise
   138  	proc := &simpleMessageProc{t, make(chan SimpleMessage, 1)}
   139  	r.RegisterProcessor(proc, SimpleMessageType)
   140  
   141  	simpleMsg := &SimpleMessage{3}
   142  	sentLen, err := r.Send(r.ServerIdentity, simpleMsg)
   143  	require.Nil(t, err)
   144  	require.NotZero(t, sentLen)
   145  	decoded := <-proc.relay
   146  	require.Equal(t, int64(3), decoded.I)
   147  
   148  	// Ensure no connections were open (since sending to ourself)
   149  	r.Lock()
   150  	require.Equal(t, 0, len(r.connections))
   151  	r.Unlock()
   152  }
   153  
   154  func testRouterRemoveConnection(t *testing.T) {
   155  	r1, err := NewTestRouterTCP(2008)
   156  	require.Nil(t, err)
   157  	r2, err := NewTestRouterTCP(2009)
   158  	require.Nil(t, err)
   159  
   160  	defer r1.Stop()
   161  
   162  	go r1.Start()
   163  	go r2.Start()
   164  
   165  	sentLen, err := r1.Send(r2.ServerIdentity, nil)
   166  	require.NotNil(t, err)
   167  	require.Zero(t, sentLen)
   168  
   169  	r1.Lock()
   170  	require.Equal(t, 1, len(r1.connections[r2.ServerIdentity.ID]))
   171  	r1.Unlock()
   172  
   173  	require.Nil(t, r2.Stop())
   174  
   175  	r1.Lock()
   176  	require.Equal(t, 0, len(r1.connections[r2.ServerIdentity.ID]))
   177  	r1.Unlock()
   178  }
   179  
   180  // Test the automatic connection upon request
   181  func TestRouterAutoConnectionTCP(t *testing.T) {
   182  	testRouterAutoConnection(t, NewTestRouterTCP)
   183  }
   184  func TestRouterAutoConnectionLocal(t *testing.T) {
   185  	testRouterAutoConnection(t, NewTestRouterLocal)
   186  }
   187  
   188  func testRouterAutoConnection(t *testing.T, fac routerFactory) {
   189  	h1, err := fac(2007)
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  	_, err = h1.Send(&ServerIdentity{Address: NewLocalAddress("127.1.2.3:2890")}, &SimpleMessage{12})
   194  	require.NotNil(t, err, "Should not be able to send")
   195  
   196  	h2, err := fac(2008)
   197  	if err != nil {
   198  		t.Fatal(err)
   199  	}
   200  
   201  	_, err = h1.Send(h2.ServerIdentity, nil)
   202  	require.NotNil(t, err)
   203  
   204  	go h2.Start()
   205  	for !h2.Listening() {
   206  		time.Sleep(10 * time.Millisecond)
   207  	}
   208  
   209  	clean := func() {
   210  		require.Nil(t, h1.Stop())
   211  		require.Nil(t, h2.Stop())
   212  	}
   213  	defer clean()
   214  
   215  	proc := newSimpleMessageProc(t)
   216  	h2.RegisterProcessor(proc, SimpleMessageType)
   217  	h1.RegisterProcessor(proc, SimpleMessageType)
   218  
   219  	sentLen, err := h1.Send(h2.ServerIdentity, &SimpleMessage{12})
   220  	require.Nil(t, err)
   221  	require.NotZero(t, sentLen)
   222  
   223  	// Receive the message
   224  	msg := <-proc.relay
   225  	if msg.I != 12 {
   226  		t.Fatal("Simple message got distorted")
   227  	}
   228  
   229  	h12 := h1.connection(h2.ServerIdentity.ID)
   230  	h21 := h2.connection(h1.ServerIdentity.ID)
   231  	require.NotNil(t, h12)
   232  	require.NotNil(t, h21)
   233  	require.Nil(t, h21.Close())
   234  	time.Sleep(100 * time.Millisecond)
   235  
   236  	sentLen, err = h1.Send(h2.ServerIdentity, &SimpleMessage{12})
   237  	require.Nil(t, err)
   238  	require.NotZero(t, sentLen)
   239  	<-proc.relay
   240  
   241  	if err := h2.Stop(); err != nil {
   242  		t.Fatal("Should be able to stop h2")
   243  	}
   244  	_, err = h1.Send(h2.ServerIdentity, &SimpleMessage{12})
   245  	if err == nil {
   246  		// This should not happen, but it can due to a race in
   247  		// the kernel between closing and writing to the
   248  		// existing h1->h2 TCP connections.  It would be nice
   249  		// to fix this to make the tests more deterministic,
   250  		// but for now we'll just give up and log it.
   251  		t.Log("h1 let us send still")
   252  	}
   253  }
   254  
   255  // Test connection of multiple Hosts and sending messages back and forth
   256  // also tests for the counterIO interface that it works well
   257  func TestRouterMessaging(t *testing.T) {
   258  	h1, err1 := NewTestRouterTCP(2009)
   259  	h2, err2 := NewTestRouterTCP(2010)
   260  	if err1 != nil || err2 != nil {
   261  		t.Fatal("Could not setup hosts")
   262  	}
   263  
   264  	go h1.Start()
   265  	go h2.Start()
   266  
   267  	defer func() {
   268  		h1.Stop()
   269  		h2.Stop()
   270  		time.Sleep(250 * time.Millisecond)
   271  	}()
   272  
   273  	proc := &simpleMessageProc{t, make(chan SimpleMessage)}
   274  	h1.RegisterProcessor(proc, SimpleMessageType)
   275  	h2.RegisterProcessor(proc, SimpleMessageType)
   276  
   277  	msgSimple := &SimpleMessage{3}
   278  	sentLen, err := h1.Send(h2.ServerIdentity, msgSimple)
   279  	require.Nil(t, err)
   280  	require.NotZero(t, sentLen)
   281  
   282  	decoded := <-proc.relay
   283  	require.Equal(t, int64(3), decoded.I)
   284  
   285  	// make sure the connection is registered in host1 (because it's launched in
   286  	// a go routine). Since we try to avoid random timeout, let's send a msg
   287  	// from host2 -> host1.
   288  	sentLen, err = h2.Send(h1.ServerIdentity, msgSimple)
   289  	require.Nil(t, err)
   290  	require.NotZero(t, sentLen)
   291  
   292  	decoded = <-proc.relay
   293  	require.Equal(t, int64(3), decoded.I)
   294  
   295  	written := h1.Tx()
   296  	read := h2.Rx()
   297  	if written == 0 || read == 0 || written != read {
   298  		log.Errorf("Tx = %d, Rx = %d", written, read)
   299  		log.Errorf("h1.Tx() %d vs h2.Rx() %d", h1.Tx(), h2.Rx())
   300  		log.Errorf("Something is wrong with Host.CounterIO")
   301  	}
   302  }
   303  
   304  func TestRouterLotsOfConnTCP(t *testing.T) {
   305  	testRouterLotsOfConn(t, NewTestRouterTCP, 5)
   306  }
   307  
   308  func TestRouterLotsOfConnLocal(t *testing.T) {
   309  	testRouterLotsOfConn(t, NewTestRouterLocal, 5)
   310  }
   311  
   312  // nSquareProc will send back all packet sent and stop when it has received
   313  // enough, it releases the waitgroup.
   314  type nSquareProc struct {
   315  	t           *testing.T
   316  	r           *Router
   317  	expected    int
   318  	wg          *sync.WaitGroup
   319  	firstRound  map[Address]bool
   320  	secondRound map[Address]bool
   321  	sync.Mutex
   322  }
   323  
   324  func newNSquareProc(t *testing.T, r *Router, expect int, wg *sync.WaitGroup) *nSquareProc {
   325  	return &nSquareProc{t, r, expect, wg, make(map[Address]bool), make(map[Address]bool), sync.Mutex{}}
   326  }
   327  
   328  func (p *nSquareProc) Process(env *Envelope) {
   329  	p.Lock()
   330  	defer p.Unlock()
   331  	remote := env.ServerIdentity.Address
   332  	ok := p.firstRound[remote]
   333  	if ok {
   334  		// second round
   335  		if ok := p.secondRound[remote]; ok {
   336  			p.t.Fatal("Already received second round")
   337  		}
   338  		p.secondRound[remote] = true
   339  
   340  		if len(p.secondRound) == p.expected {
   341  			// release
   342  			p.wg.Done()
   343  		}
   344  		return
   345  	}
   346  
   347  	p.firstRound[remote] = true
   348  	if _, err := p.r.Send(env.ServerIdentity, &SimpleMessage{3}); err != nil {
   349  		p.t.Fatal("Could not send to first round dest.")
   350  	}
   351  
   352  }
   353  
   354  // Makes a big mesh where every host send and receive to every other hosts
   355  func testRouterLotsOfConn(t *testing.T, fac routerFactory, nbrRouter int) {
   356  	// create all the routers
   357  	routers := make([]*Router, nbrRouter)
   358  	// to wait for the creation of all hosts
   359  	var wg1 sync.WaitGroup
   360  	wg1.Add(nbrRouter)
   361  	var wg2 sync.WaitGroup
   362  	wg2.Add(nbrRouter)
   363  	for i := 0; i < nbrRouter; i++ {
   364  		go func(j int) {
   365  			r, err := fac(2000 + j)
   366  			if err != nil {
   367  				t.Fatal(err)
   368  			}
   369  			go r.Start()
   370  			for !r.Listening() {
   371  				time.Sleep(10 * time.Millisecond)
   372  			}
   373  
   374  			routers[j] = r
   375  			// expect nbrRouter - 1 messages
   376  			proc := newNSquareProc(t, r, nbrRouter-1, &wg2)
   377  			r.RegisterProcessor(proc, SimpleMessageType)
   378  			wg1.Done()
   379  		}(i)
   380  	}
   381  	wg1.Wait()
   382  
   383  	for i := 0; i < nbrRouter; i++ {
   384  		go func(j int) {
   385  			r := routers[j]
   386  			for k := 0; k < nbrRouter; k++ {
   387  				if k == j {
   388  					// don't send to yourself
   389  					continue
   390  				}
   391  				// send to everyone else
   392  				if _, err := r.Send(routers[k].ServerIdentity, &SimpleMessage{3}); err != nil {
   393  					t.Fatal(err)
   394  				}
   395  			}
   396  		}(i)
   397  	}
   398  	wg2.Wait()
   399  	for i := 0; i < nbrRouter; i++ {
   400  		r := routers[i]
   401  		if err := r.Stop(); err != nil {
   402  			t.Fatal(err)
   403  		}
   404  
   405  	}
   406  }
   407  
   408  // Test sending data back and forth using the sendProtocolMsg
   409  func TestRouterSendMsgDuplexTCP(t *testing.T) {
   410  	testRouterSendMsgDuplex(t, NewTestRouterTCP)
   411  }
   412  
   413  func TestRouterSendMsgDuplexLocal(t *testing.T) {
   414  	testRouterSendMsgDuplex(t, NewTestRouterLocal)
   415  }
   416  func testRouterSendMsgDuplex(t *testing.T, fac routerFactory) {
   417  	h1, err1 := fac(2011)
   418  	h2, err2 := fac(2012)
   419  	if err1 != nil {
   420  		t.Fatal("Could not setup hosts: ", err1)
   421  	}
   422  	if err2 != nil {
   423  		t.Fatal("Could not setup hosts: ", err2)
   424  	}
   425  	go h1.Start()
   426  	go h2.Start()
   427  
   428  	defer func() {
   429  		h1.Stop()
   430  		h2.Stop()
   431  		time.Sleep(250 * time.Millisecond)
   432  	}()
   433  
   434  	proc := &simpleMessageProc{t, make(chan SimpleMessage)}
   435  	h1.RegisterProcessor(proc, SimpleMessageType)
   436  	h2.RegisterProcessor(proc, SimpleMessageType)
   437  
   438  	msgSimple := &SimpleMessage{5}
   439  	sentLen, err := h1.Send(h2.ServerIdentity, msgSimple)
   440  	require.Nil(t, err, "Couldn't send message from h1 to h2")
   441  	require.NotZero(t, sentLen)
   442  
   443  	msg := <-proc.relay
   444  	log.Lvl2("Received msg h1 -> h2", msg)
   445  
   446  	sentLen, err = h2.Send(h1.ServerIdentity, msgSimple)
   447  	require.Nil(t, err, "Couldn't send message from h2 to h1")
   448  	require.NotZero(t, sentLen)
   449  
   450  	msg = <-proc.relay
   451  	log.Lvl2("Received msg h2 -> h1", msg)
   452  }
   453  
   454  func TestRouterExchange(t *testing.T) {
   455  	log.OutputToBuf()
   456  	defer log.OutputToOs()
   457  	router1, err := NewTestRouterTCP(7878)
   458  	router2, err2 := NewTestRouterTCP(8787)
   459  	if err != nil || err2 != nil {
   460  		t.Fatal("Could not setup host", err, err2)
   461  	}
   462  
   463  	done := make(chan bool)
   464  	go func() {
   465  		done <- true
   466  		router1.Start()
   467  		done <- true
   468  	}()
   469  	<-done
   470  	// try correctly
   471  	c, err := NewTCPConn(router1.ServerIdentity.Address, tSuite)
   472  	if err != nil {
   473  		t.Fatal("Couldn't connect to host1:", err)
   474  	}
   475  	sentLen, err := c.Send(router2.ServerIdentity)
   476  	require.Nil(t, err, "Wrong negotiation")
   477  	require.NotZero(t, sentLen)
   478  
   479  	// triggers the dispatching conditional branch error router.go:
   480  	//  `log.Lvl3("Error dispatching:", err)`
   481  	sentLen, err = router2.Send(router1.ServerIdentity, &SimpleMessage{12})
   482  	require.Nil(t, err, "Could not send")
   483  	require.NotZero(t, sentLen)
   484  	c.Close()
   485  
   486  	// try messing with the connections here
   487  	c, err = NewTCPConn(router1.ServerIdentity.Address, tSuite)
   488  	if err != nil {
   489  		t.Fatal("Couldn't connect to host1:", err)
   490  	}
   491  	// closing before sending
   492  	c.Close()
   493  	_, err = c.Send(router2.ServerIdentity)
   494  	require.NotNil(t, err, "negotiation should have aborted")
   495  
   496  	// stop everything
   497  	log.Lvl4("Closing connections")
   498  	if err := router2.Stop(); err != nil {
   499  		t.Fatal("Couldn't close host", err)
   500  	}
   501  	if err := router1.Stop(); err != nil {
   502  		t.Fatal("Couldn't close host", err)
   503  	}
   504  	<-done
   505  }
   506  
   507  func TestRouterRxTx(t *testing.T) {
   508  	router1, err := NewTestRouterTCP(0)
   509  	log.ErrFatal(err)
   510  	router2, err := NewTestRouterTCP(0)
   511  	log.ErrFatal(err)
   512  	go router1.Start()
   513  	go router2.Start()
   514  
   515  	addr := NewAddress(router1.address.ConnType(), "127.0.0.1:"+router1.address.Port())
   516  	si1 := NewServerIdentity(Suite.Point(tSuite).Null(), addr)
   517  
   518  	sentLen, err := router2.Send(si1, si1)
   519  	require.Nil(t, err)
   520  	require.NotZero(t, sentLen)
   521  
   522  	// Wait for the message to be sent and received
   523  	waitTimeout(time.Second, 10, func() bool {
   524  		return router1.Rx() > 0 && router1.Rx() == router2.Tx()
   525  	})
   526  	rx := router1.Rx()
   527  	require.Equal(t, 1, len(router1.connections))
   528  	router1.Lock()
   529  	var si2 ServerIdentityID
   530  	for si2 = range router1.connections {
   531  		log.Lvl3("Connection:", si2)
   532  	}
   533  	router1.Unlock()
   534  	router2.Stop()
   535  	waitTimeout(time.Second, 10, func() bool {
   536  		router1.Lock()
   537  		defer router1.Unlock()
   538  		return len(router1.connections[si2]) == 0
   539  	})
   540  	require.Equal(t, rx, router1.Rx())
   541  	require.Equal(t, uint64(1), router1.MsgRx())
   542  	require.Equal(t, uint64(0), router1.MsgTx())
   543  	require.Equal(t, uint64(1), router2.MsgTx())
   544  	require.Equal(t, uint64(0), router2.MsgRx())
   545  	defer router1.Stop()
   546  }
   547  
   548  func waitTimeout(timeout time.Duration, repeat int,
   549  	f func() bool) {
   550  	success := make(chan bool)
   551  	go func() {
   552  		for !f() {
   553  			time.Sleep(timeout / time.Duration(repeat))
   554  		}
   555  		success <- true
   556  	}()
   557  	select {
   558  	case <-success:
   559  	case <-time.After(timeout):
   560  		log.Fatal("Timeout" + log.Stack())
   561  	}
   562  
   563  }
   564  
   565  type testConn struct{}
   566  
   567  func (c *testConn) Receive() (*Envelope, error) {
   568  	return nil, ErrUnknown
   569  }
   570  
   571  func (c *testConn) Close() error {
   572  	return nil
   573  }
   574  
   575  func (c *testConn) Local() Address {
   576  	return ""
   577  }
   578  
   579  func (c *testConn) Remote() Address {
   580  	return ""
   581  }
   582  
   583  func (c *testConn) Rx() uint64 {
   584  	return 0
   585  }
   586  
   587  func (c *testConn) Tx() uint64 {
   588  	return 0
   589  }
   590  
   591  func (c *testConn) Send(msg Message) (uint64, error) {
   592  	return 0, nil
   593  }
   594  
   595  func (c *testConn) Type() ConnType {
   596  	return "testConn"
   597  }
   598  
   599  // This test insures that an unknown error cannot end up as an infinite loop
   600  // when handling a connection
   601  func TestRouterHandleUnknownError(t *testing.T) {
   602  	router, err := NewTestRouterTCP(0)
   603  	require.NoError(t, err)
   604  
   605  	router.wg.Add(1)
   606  	// The test will leak 1 goroutine if the connection is not dropped
   607  	go router.handleConn(router.ServerIdentity, &testConn{})
   608  }