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{})