Source file src/bufio/net_test.go

     1  // Copyright 2025 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.
     4  
     5  //go:build unix
     6  
     7  package bufio_test
     8  
     9  import (
    10  	"bufio"
    11  	"io"
    12  	"net"
    13  	"path/filepath"
    14  	"strings"
    15  	"sync"
    16  	"testing"
    17  )
    18  
    19  // TestCopyUnixpacket tests that we can use bufio when copying
    20  // across a unixpacket socket. This used to fail due to an unnecessary
    21  // empty Write call that was interpreted as an EOF.
    22  func TestCopyUnixpacket(t *testing.T) {
    23  	tmpDir := t.TempDir()
    24  	socket := filepath.Join(tmpDir, "unixsock")
    25  
    26  	// Start a unixpacket server.
    27  	addr := &net.UnixAddr{
    28  		Name: socket,
    29  		Net:  "unixpacket",
    30  	}
    31  	server, err := net.ListenUnix("unixpacket", addr)
    32  	if err != nil {
    33  		t.Skipf("skipping test because opening a unixpacket socket failed: %v", err)
    34  	}
    35  
    36  	// Start a goroutine for the server to accept one connection
    37  	// and read all the data sent on the connection,
    38  	// reporting the number of bytes read on ch.
    39  	ch := make(chan int, 1)
    40  	var wg sync.WaitGroup
    41  	wg.Add(1)
    42  	go func() {
    43  		defer wg.Done()
    44  
    45  		tot := 0
    46  		defer func() {
    47  			ch <- tot
    48  		}()
    49  
    50  		serverConn, err := server.Accept()
    51  		if err != nil {
    52  			t.Error(err)
    53  			return
    54  		}
    55  
    56  		buf := make([]byte, 1024)
    57  		for {
    58  			n, err := serverConn.Read(buf)
    59  			tot += n
    60  			if err == io.EOF {
    61  				return
    62  			}
    63  			if err != nil {
    64  				t.Error(err)
    65  				return
    66  			}
    67  		}
    68  	}()
    69  
    70  	clientConn, err := net.DialUnix("unixpacket", nil, addr)
    71  	if err != nil {
    72  		// Leaves the server goroutine hanging. Oh well.
    73  		t.Fatal(err)
    74  	}
    75  
    76  	defer wg.Wait()
    77  	defer clientConn.Close()
    78  
    79  	const data = "data"
    80  	r := bufio.NewReader(strings.NewReader(data))
    81  	n, err := io.Copy(clientConn, r)
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  
    86  	if n != int64(len(data)) {
    87  		t.Errorf("io.Copy returned %d, want %d", n, len(data))
    88  	}
    89  
    90  	clientConn.Close()
    91  	tot := <-ch
    92  
    93  	if tot != len(data) {
    94  		t.Errorf("server read %d, want %d", tot, len(data))
    95  	}
    96  }
    97  

View as plain text