1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:build js || wasip1
9 // GOOS=js and GOOS=wasip1 do not have typical socket networking capabilities
10 // found on other platforms. To help run test suites of the stdlib packages,
11 // an in-memory "fake network" facility is implemented.
13 // The tests in this files are intended to validate the behavior of the fake
14 // network stack on these platforms.
22 func TestFakePortExhaustion(t *testing.T) {
24 t.Skipf("skipping test that opens 1<<16 connections")
27 ln := newLocalListener(t, "tcp")
28 done := make(chan struct{})
32 for _, c := range accepted {
43 accepted = append(accepted, c)
50 for _, c := range dialed {
56 // Since this test is not running in parallel, we expect to be able to open
57 // all 65535 valid (fake) ports. The listener is already using one, so
58 // we should be able to Dial the remaining 65534.
59 for len(dialed) < (1<<16)-2 {
60 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
62 t.Fatalf("unexpected error from Dial with %v connections: %v", len(dialed), err)
64 dialed = append(dialed, c)
65 if testing.Verbose() && len(dialed)%(1<<12) == 0 {
66 t.Logf("dialed %d connections", len(dialed))
69 t.Logf("dialed %d connections", len(dialed))
71 // Now that all of the ports are in use, dialing another should fail due
72 // to port exhaustion, which (for POSIX-like socket APIs) should return
73 // an EADDRINUSE error.
74 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
78 if errors.Is(err, syscall.EADDRINUSE) {
79 t.Logf("Dial returned expected error: %v", err)
81 t.Errorf("unexpected error from Dial: %v\nwant: %v", err, syscall.EADDRINUSE)
84 // Opening a Listener should fail at this point too.
85 ln2, err := Listen("tcp", "localhost:0")
89 if errors.Is(err, syscall.EADDRINUSE) {
90 t.Logf("Listen returned expected error: %v", err)
92 t.Errorf("unexpected error from Listen: %v\nwant: %v", err, syscall.EADDRINUSE)
95 // When we close an arbitrary connection, we should be able to reuse its port
96 // even if the server hasn't yet seen the ECONNRESET for the connection.
99 t.Logf("closed one connection")
100 c, err = Dial(ln.Addr().Network(), ln.Addr().String())
103 t.Logf("Dial succeeded")
105 t.Errorf("unexpected error from Dial: %v", err)