aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/nat/nat_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'p2p/nat/nat_test.go')
-rw-r--r--p2p/nat/nat_test.go48
1 files changed, 48 insertions, 0 deletions
diff --git a/p2p/nat/nat_test.go b/p2p/nat/nat_test.go
new file mode 100644
index 000000000..95c50522e
--- /dev/null
+++ b/p2p/nat/nat_test.go
@@ -0,0 +1,48 @@
+package nat
+
+import (
+ "bytes"
+ "net"
+ "testing"
+ "time"
+)
+
+// This test checks that autodisc doesn't hang and returns
+// consistent results when multiple goroutines call its methods
+// concurrently.
+func TestAutoDiscRace(t *testing.T) {
+ ad := startautodisc("thing", func() Interface {
+ time.Sleep(500 * time.Millisecond)
+ return extIP{33, 44, 55, 66}
+ })
+
+ // Spawn a few concurrent calls to ad.ExternalIP.
+ type rval struct {
+ ip net.IP
+ err error
+ }
+ results := make(chan rval, 50)
+ for i := 0; i < cap(results); i++ {
+ go func() {
+ ip, err := ad.ExternalIP()
+ results <- rval{ip, err}
+ }()
+ }
+
+ // Check that they all return the correct result within the deadline.
+ deadline := time.After(550 * time.Millisecond)
+ for i := 0; i < cap(results); i++ {
+ select {
+ case <-deadline:
+ t.Fatal("deadline exceeded")
+ case rval := <-results:
+ if rval.err != nil {
+ t.Errorf("result %d: unexpected error: %v", i, rval.err)
+ }
+ wantIP := net.IP{33, 44, 55, 66}
+ if !bytes.Equal(rval.ip, wantIP) {
+ t.Errorf("result %d: got IP %v, want %v", i, rval.ip, wantIP)
+ }
+ }
+ }
+}