github.com/ethereum/go-ethereum@v1.16.1/p2p/nat/nat_test.go (about)

     1  // Copyright 2015 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 nat
    18  
    19  import (
    20  	"net"
    21  	"strings"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  // This test checks that autodisc doesn't hang and returns
    29  // consistent results when multiple goroutines call its methods
    30  // concurrently.
    31  func TestAutoDiscRace(t *testing.T) {
    32  	ad := startautodisc("thing", func() Interface {
    33  		time.Sleep(500 * time.Millisecond)
    34  		return ExtIP{33, 44, 55, 66}
    35  	})
    36  
    37  	// Spawn a few concurrent calls to ad.ExternalIP.
    38  	type rval struct {
    39  		ip  net.IP
    40  		err error
    41  	}
    42  	results := make(chan rval, 50)
    43  	for i := 0; i < cap(results); i++ {
    44  		go func() {
    45  			ip, err := ad.ExternalIP()
    46  			results <- rval{ip, err}
    47  		}()
    48  	}
    49  
    50  	// Check that they all return the correct result within the deadline.
    51  	deadline := time.After(2 * time.Second)
    52  	for i := 0; i < cap(results); i++ {
    53  		select {
    54  		case <-deadline:
    55  			t.Fatal("deadline exceeded")
    56  		case rval := <-results:
    57  			if rval.err != nil {
    58  				t.Errorf("result %d: unexpected error: %v", i, rval.err)
    59  			}
    60  			wantIP := net.IP{33, 44, 55, 66}
    61  			if !rval.ip.Equal(wantIP) {
    62  				t.Errorf("result %d: got IP %v, want %v", i, rval.ip, wantIP)
    63  			}
    64  		}
    65  	}
    66  }
    67  
    68  // stun should work well
    69  func TestParseStun(t *testing.T) {
    70  	testcases := []struct {
    71  		natStr string
    72  		want   *stun
    73  	}{
    74  		{"stun", &stun{serverList: strings.Split(stunDefaultServers, "\n")}},
    75  		{"stun:1.2.3.4:1234", &stun{serverList: []string{"1.2.3.4:1234"}}},
    76  	}
    77  
    78  	for _, tc := range testcases {
    79  		nat, err := Parse(tc.natStr)
    80  		if err != nil {
    81  			t.Errorf("should no err, but get %v", err)
    82  		}
    83  		stun := nat.(*stun)
    84  		assert.Equal(t, stun.serverList, tc.want.serverList)
    85  	}
    86  }