github.com/julesgoullee/go-ethereum@v1.9.7/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  	"testing"
    22  	"time"
    23  )
    24  
    25  // This test checks that autodisc doesn't hang and returns
    26  // consistent results when multiple goroutines call its methods
    27  // concurrently.
    28  func TestAutoDiscRace(t *testing.T) {
    29  	ad := startautodisc("thing", func() Interface {
    30  		time.Sleep(500 * time.Millisecond)
    31  		return ExtIP{33, 44, 55, 66}
    32  	})
    33  
    34  	// Spawn a few concurrent calls to ad.ExternalIP.
    35  	type rval struct {
    36  		ip  net.IP
    37  		err error
    38  	}
    39  	results := make(chan rval, 50)
    40  	for i := 0; i < cap(results); i++ {
    41  		go func() {
    42  			ip, err := ad.ExternalIP()
    43  			results <- rval{ip, err}
    44  		}()
    45  	}
    46  
    47  	// Check that they all return the correct result within the deadline.
    48  	deadline := time.After(2 * time.Second)
    49  	for i := 0; i < cap(results); i++ {
    50  		select {
    51  		case <-deadline:
    52  			t.Fatal("deadline exceeded")
    53  		case rval := <-results:
    54  			if rval.err != nil {
    55  				t.Errorf("result %d: unexpected error: %v", i, rval.err)
    56  			}
    57  			wantIP := net.IP{33, 44, 55, 66}
    58  			if !rval.ip.Equal(wantIP) {
    59  				t.Errorf("result %d: got IP %v, want %v", i, rval.ip, wantIP)
    60  			}
    61  		}
    62  	}
    63  }