X7ROOT File Manager
Current Path:
/opt/golang/1.22.0/src/net
opt
/
golang
/
1.22.0
/
src
/
net
/
📁
..
📄
addrselect.go
(9.69 KB)
📄
addrselect_test.go
(8.5 KB)
📄
cgo_aix.go
(582 B)
📄
cgo_android.go
(272 B)
📄
cgo_bsd.go
(343 B)
📄
cgo_darwin.go
(298 B)
📄
cgo_linux.go
(642 B)
📄
cgo_netbsd.go
(276 B)
📄
cgo_openbsd.go
(276 B)
📄
cgo_resnew.go
(580 B)
📄
cgo_resold.go
(579 B)
📄
cgo_socknew.go
(753 B)
📄
cgo_sockold.go
(842 B)
📄
cgo_solaris.go
(343 B)
📄
cgo_stub.go
(1.33 KB)
📄
cgo_unix.go
(11.35 KB)
📄
cgo_unix_cgo.go
(2.24 KB)
📄
cgo_unix_cgo_darwin.go
(461 B)
📄
cgo_unix_cgo_res.go
(911 B)
📄
cgo_unix_cgo_resn.go
(998 B)
📄
cgo_unix_syscall.go
(2.99 KB)
📄
cgo_unix_test.go
(1.44 KB)
📄
conf.go
(15.63 KB)
📄
conf_test.go
(12.28 KB)
📄
conn_test.go
(1.82 KB)
📄
dial.go
(25.68 KB)
📄
dial_test.go
(30.14 KB)
📄
dial_unix_test.go
(2.77 KB)
📄
dnsclient.go
(5.65 KB)
📄
dnsclient_test.go
(1.51 KB)
📄
dnsclient_unix.go
(24.26 KB)
📄
dnsclient_unix_test.go
(69.13 KB)
📄
dnsconfig.go
(1.73 KB)
📄
dnsconfig_unix.go
(4.16 KB)
📄
dnsconfig_unix_test.go
(7.07 KB)
📄
dnsconfig_windows.go
(1.6 KB)
📄
dnsname_test.go
(1.96 KB)
📄
error_plan9.go
(224 B)
📄
error_plan9_test.go
(437 B)
📄
error_posix.go
(543 B)
📄
error_posix_test.go
(981 B)
📄
error_test.go
(20.32 KB)
📄
error_unix.go
(382 B)
📄
error_unix_test.go
(723 B)
📄
error_windows.go
(355 B)
📄
error_windows_test.go
(757 B)
📄
example_test.go
(8.45 KB)
📄
external_test.go
(4.05 KB)
📄
fd_fake.go
(3.79 KB)
📄
fd_js.go
(627 B)
📄
fd_plan9.go
(3.56 KB)
📄
fd_posix.go
(4.29 KB)
📄
fd_unix.go
(5.43 KB)
📄
fd_wasip1.go
(496 B)
📄
fd_windows.go
(6.14 KB)
📄
file.go
(1.69 KB)
📄
file_plan9.go
(2.72 KB)
📄
file_stub.go
(481 B)
📄
file_test.go
(6.43 KB)
📄
file_unix.go
(2.5 KB)
📄
file_unix_test.go
(2.07 KB)
📄
file_wasip1.go
(2.2 KB)
📄
file_wasip1_test.go
(3.76 KB)
📄
file_windows.go
(521 B)
📄
hook.go
(894 B)
📄
hook_plan9.go
(211 B)
📄
hook_unix.go
(658 B)
📄
hook_windows.go
(720 B)
📄
hosts.go
(3.48 KB)
📄
hosts_test.go
(5.6 KB)
📁
http
📄
interface.go
(7.26 KB)
📄
interface_aix.go
(4.46 KB)
📄
interface_bsd.go
(2.82 KB)
📄
interface_bsd_test.go
(1.44 KB)
📄
interface_bsdvar.go
(718 B)
📄
interface_darwin.go
(1.29 KB)
📄
interface_freebsd.go
(1.29 KB)
📄
interface_linux.go
(6.96 KB)
📄
interface_linux_test.go
(3.65 KB)
📄
interface_plan9.go
(4.71 KB)
📄
interface_solaris.go
(2.13 KB)
📄
interface_stub.go
(814 B)
📄
interface_test.go
(9.76 KB)
📄
interface_unix_test.go
(4.85 KB)
📄
interface_windows.go
(5.43 KB)
📁
internal
📄
ip.go
(13.88 KB)
📄
ip_test.go
(25.6 KB)
📄
iprawsock.go
(7.11 KB)
📄
iprawsock_plan9.go
(874 B)
📄
iprawsock_posix.go
(3.89 KB)
📄
iprawsock_test.go
(5.98 KB)
📄
ipsock.go
(9.05 KB)
📄
ipsock_plan9.go
(7.48 KB)
📄
ipsock_plan9_test.go
(645 B)
📄
ipsock_posix.go
(7.86 KB)
📄
ipsock_test.go
(6.81 KB)
📄
listen_test.go
(20.5 KB)
📄
lookup.go
(29.04 KB)
📄
lookup_plan9.go
(9.94 KB)
📄
lookup_test.go
(40.62 KB)
📄
lookup_unix.go
(3.35 KB)
📄
lookup_windows.go
(13.8 KB)
📄
lookup_windows_test.go
(8.93 KB)
📄
mac.go
(1.88 KB)
📄
mac_test.go
(3.26 KB)
📁
mail
📄
main_cloexec_test.go
(693 B)
📄
main_conf_test.go
(1.39 KB)
📄
main_noconf_test.go
(467 B)
📄
main_plan9_test.go
(392 B)
📄
main_posix_test.go
(1.37 KB)
📄
main_test.go
(7.53 KB)
📄
main_unix_test.go
(1.19 KB)
📄
main_wasm_test.go
(284 B)
📄
main_windows_test.go
(1 KB)
📄
mockserver_test.go
(10.77 KB)
📄
mptcpsock_linux.go
(3.96 KB)
📄
mptcpsock_linux_test.go
(4.06 KB)
📄
mptcpsock_stub.go
(542 B)
📄
net.go
(24.56 KB)
📄
net_fake.go
(26.36 KB)
📄
net_fake_test.go
(2.79 KB)
📄
net_test.go
(14 KB)
📄
net_windows_test.go
(16.28 KB)
📄
netcgo_off.go
(222 B)
📄
netcgo_on.go
(220 B)
📄
netgo_netcgo.go
(453 B)
📄
netgo_off.go
(220 B)
📄
netgo_on.go
(218 B)
📁
netip
📄
nss.go
(5.48 KB)
📄
nss_test.go
(3.4 KB)
📄
packetconn_test.go
(3.02 KB)
📄
parse.go
(6.04 KB)
📄
parse_test.go
(1.55 KB)
📄
pipe.go
(5.43 KB)
📄
pipe_test.go
(1.2 KB)
📄
platform_test.go
(4.33 KB)
📄
port.go
(1.46 KB)
📄
port_test.go
(1.34 KB)
📄
port_unix.go
(1.24 KB)
📄
protoconn_test.go
(7.44 KB)
📄
rawconn.go
(2.7 KB)
📄
rawconn_stub_test.go
(631 B)
📄
rawconn_test.go
(4.33 KB)
📄
rawconn_unix_test.go
(2.96 KB)
📄
rawconn_windows_test.go
(3.12 KB)
📄
resolverdialfunc_test.go
(8.25 KB)
📄
rlimit_js.go
(346 B)
📄
rlimit_unix.go
(1.1 KB)
📁
rpc
📄
sendfile_linux.go
(1.12 KB)
📄
sendfile_linux_test.go
(1.93 KB)
📄
sendfile_stub.go
(344 B)
📄
sendfile_test.go
(8.25 KB)
📄
sendfile_unix_alt.go
(2.04 KB)
📄
sendfile_windows.go
(1.02 KB)
📄
server_test.go
(11.67 KB)
📁
smtp
📄
sock_bsd.go
(918 B)
📄
sock_cloexec.go
(1.38 KB)
📄
sock_linux.go
(993 B)
📄
sock_linux_test.go
(575 B)
📄
sock_plan9.go
(262 B)
📄
sock_posix.go
(6.29 KB)
📄
sock_stub.go
(390 B)
📄
sock_windows.go
(802 B)
📄
sockaddr_posix.go
(1.45 KB)
📄
sockopt_aix.go
(1.43 KB)
📄
sockopt_bsd.go
(2.21 KB)
📄
sockopt_fake.go
(955 B)
📄
sockopt_linux.go
(1.25 KB)
📄
sockopt_plan9.go
(406 B)
📄
sockopt_posix.go
(2.13 KB)
📄
sockopt_solaris.go
(1.25 KB)
📄
sockopt_windows.go
(1.51 KB)
📄
sockoptip_bsdvar.go
(867 B)
📄
sockoptip_linux.go
(735 B)
📄
sockoptip_posix.go
(1.38 KB)
📄
sockoptip_stub.go
(769 B)
📄
sockoptip_windows.go
(786 B)
📄
splice_linux.go
(1.69 KB)
📄
splice_stub.go
(376 B)
📄
splice_test.go
(13.48 KB)
📄
sys_cloexec.go
(962 B)
📄
tcpsock.go
(11.75 KB)
📄
tcpsock_plan9.go
(2.18 KB)
📄
tcpsock_posix.go
(6.16 KB)
📄
tcpsock_test.go
(17.68 KB)
📄
tcpsock_unix_test.go
(2.34 KB)
📄
tcpsockopt_darwin.go
(770 B)
📄
tcpsockopt_dragonfly.go
(698 B)
📄
tcpsockopt_openbsd.go
(365 B)
📄
tcpsockopt_plan9.go
(525 B)
📄
tcpsockopt_posix.go
(442 B)
📄
tcpsockopt_solaris.go
(1.15 KB)
📄
tcpsockopt_stub.go
(399 B)
📄
tcpsockopt_unix.go
(722 B)
📄
tcpsockopt_windows.go
(741 B)
📁
testdata
📁
textproto
📄
timeout_test.go
(29.11 KB)
📄
udpsock.go
(11.83 KB)
📄
udpsock_plan9.go
(4.64 KB)
📄
udpsock_plan9_test.go
(1.31 KB)
📄
udpsock_posix.go
(7.53 KB)
📄
udpsock_test.go
(17.24 KB)
📄
unixsock.go
(10.12 KB)
📄
unixsock_linux_test.go
(2.29 KB)
📄
unixsock_plan9.go
(1.24 KB)
📄
unixsock_posix.go
(6.64 KB)
📄
unixsock_readmsg_cloexec.go
(654 B)
📄
unixsock_readmsg_cmsg_cloexec.go
(332 B)
📄
unixsock_readmsg_other.go
(275 B)
📄
unixsock_readmsg_test.go
(2.51 KB)
📄
unixsock_test.go
(10.64 KB)
📄
unixsock_windows_test.go
(2.03 KB)
📁
url
📄
write_unix_test.go
(1.61 KB)
📄
writev_test.go
(5.03 KB)
📄
writev_unix.go
(666 B)
Editing: splice_test.go
// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build linux package net import ( "io" "log" "os" "os/exec" "strconv" "sync" "testing" "time" ) func TestSplice(t *testing.T) { t.Run("tcp-to-tcp", func(t *testing.T) { testSplice(t, "tcp", "tcp") }) if !testableNetwork("unixgram") { t.Skip("skipping unix-to-tcp tests") } t.Run("unix-to-tcp", func(t *testing.T) { testSplice(t, "unix", "tcp") }) t.Run("tcp-to-unix", func(t *testing.T) { testSplice(t, "tcp", "unix") }) t.Run("tcp-to-file", func(t *testing.T) { testSpliceToFile(t, "tcp", "file") }) t.Run("unix-to-file", func(t *testing.T) { testSpliceToFile(t, "unix", "file") }) t.Run("no-unixpacket", testSpliceNoUnixpacket) t.Run("no-unixgram", testSpliceNoUnixgram) } func testSpliceToFile(t *testing.T, upNet, downNet string) { t.Run("simple", spliceTestCase{upNet, downNet, 128, 128, 0}.testFile) t.Run("multipleWrite", spliceTestCase{upNet, downNet, 4096, 1 << 20, 0}.testFile) t.Run("big", spliceTestCase{upNet, downNet, 5 << 20, 1 << 30, 0}.testFile) t.Run("honorsLimitedReader", spliceTestCase{upNet, downNet, 4096, 1 << 20, 1 << 10}.testFile) t.Run("updatesLimitedReaderN", spliceTestCase{upNet, downNet, 1024, 4096, 4096 + 100}.testFile) t.Run("limitedReaderAtLimit", spliceTestCase{upNet, downNet, 32, 128, 128}.testFile) } func testSplice(t *testing.T, upNet, downNet string) { t.Run("simple", spliceTestCase{upNet, downNet, 128, 128, 0}.test) t.Run("multipleWrite", spliceTestCase{upNet, downNet, 4096, 1 << 20, 0}.test) t.Run("big", spliceTestCase{upNet, downNet, 5 << 20, 1 << 30, 0}.test) t.Run("honorsLimitedReader", spliceTestCase{upNet, downNet, 4096, 1 << 20, 1 << 10}.test) t.Run("updatesLimitedReaderN", spliceTestCase{upNet, downNet, 1024, 4096, 4096 + 100}.test) t.Run("limitedReaderAtLimit", spliceTestCase{upNet, downNet, 32, 128, 128}.test) t.Run("readerAtEOF", func(t *testing.T) { testSpliceReaderAtEOF(t, upNet, downNet) }) t.Run("issue25985", func(t *testing.T) { testSpliceIssue25985(t, upNet, downNet) }) } type spliceTestCase struct { upNet, downNet string chunkSize, totalSize int limitReadSize int } func (tc spliceTestCase) test(t *testing.T) { clientUp, serverUp := spliceTestSocketPair(t, tc.upNet) defer serverUp.Close() cleanup, err := startSpliceClient(clientUp, "w", tc.chunkSize, tc.totalSize) if err != nil { t.Fatal(err) } defer cleanup() clientDown, serverDown := spliceTestSocketPair(t, tc.downNet) defer serverDown.Close() cleanup, err = startSpliceClient(clientDown, "r", tc.chunkSize, tc.totalSize) if err != nil { t.Fatal(err) } defer cleanup() var ( r io.Reader = serverUp size = tc.totalSize ) if tc.limitReadSize > 0 { if tc.limitReadSize < size { size = tc.limitReadSize } r = &io.LimitedReader{ N: int64(tc.limitReadSize), R: serverUp, } defer serverUp.Close() } n, err := io.Copy(serverDown, r) serverDown.Close() if err != nil { t.Fatal(err) } if want := int64(size); want != n { t.Errorf("want %d bytes spliced, got %d", want, n) } if tc.limitReadSize > 0 { wantN := 0 if tc.limitReadSize > size { wantN = tc.limitReadSize - size } if n := r.(*io.LimitedReader).N; n != int64(wantN) { t.Errorf("r.N = %d, want %d", n, wantN) } } } func (tc spliceTestCase) testFile(t *testing.T) { f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0) if err != nil { t.Fatal(err) } defer f.Close() client, server := spliceTestSocketPair(t, tc.upNet) defer server.Close() cleanup, err := startSpliceClient(client, "w", tc.chunkSize, tc.totalSize) if err != nil { client.Close() t.Fatal("failed to start splice client:", err) } defer cleanup() var ( r io.Reader = server actualSize = tc.totalSize ) if tc.limitReadSize > 0 { if tc.limitReadSize < actualSize { actualSize = tc.limitReadSize } r = &io.LimitedReader{ N: int64(tc.limitReadSize), R: r, } } got, err := io.Copy(f, r) if err != nil { t.Fatalf("failed to ReadFrom with error: %v", err) } if want := int64(actualSize); got != want { t.Errorf("got %d bytes, want %d", got, want) } if tc.limitReadSize > 0 { wantN := 0 if tc.limitReadSize > actualSize { wantN = tc.limitReadSize - actualSize } if gotN := r.(*io.LimitedReader).N; gotN != int64(wantN) { t.Errorf("r.N = %d, want %d", gotN, wantN) } } } func testSpliceReaderAtEOF(t *testing.T, upNet, downNet string) { // UnixConn doesn't implement io.ReaderFrom, which will fail // the following test in asserting a UnixConn to be an io.ReaderFrom, // so skip this test. if upNet == "unix" || downNet == "unix" { t.Skip("skipping test on unix socket") } clientUp, serverUp := spliceTestSocketPair(t, upNet) defer clientUp.Close() clientDown, serverDown := spliceTestSocketPair(t, downNet) defer clientDown.Close() serverUp.Close() // We'd like to call net.spliceFrom here and check the handled return // value, but we disable splice on old Linux kernels. // // In that case, poll.Splice and net.spliceFrom return a non-nil error // and handled == false. We'd ideally like to see handled == true // because the source reader is at EOF, but if we're running on an old // kernel, and splice is disabled, we won't see EOF from net.spliceFrom, // because we won't touch the reader at all. // // Trying to untangle the errors from net.spliceFrom and match them // against the errors created by the poll package would be brittle, // so this is a higher level test. // // The following ReadFrom should return immediately, regardless of // whether splice is disabled or not. The other side should then // get a goodbye signal. Test for the goodbye signal. msg := "bye" go func() { serverDown.(io.ReaderFrom).ReadFrom(serverUp) io.WriteString(serverDown, msg) serverDown.Close() }() buf := make([]byte, 3) _, err := io.ReadFull(clientDown, buf) if err != nil { t.Errorf("clientDown: %v", err) } if string(buf) != msg { t.Errorf("clientDown got %q, want %q", buf, msg) } } func testSpliceIssue25985(t *testing.T, upNet, downNet string) { front := newLocalListener(t, upNet) defer front.Close() back := newLocalListener(t, downNet) defer back.Close() var wg sync.WaitGroup wg.Add(2) proxy := func() { src, err := front.Accept() if err != nil { return } dst, err := Dial(downNet, back.Addr().String()) if err != nil { return } defer dst.Close() defer src.Close() go func() { io.Copy(src, dst) wg.Done() }() go func() { io.Copy(dst, src) wg.Done() }() } go proxy() toFront, err := Dial(upNet, front.Addr().String()) if err != nil { t.Fatal(err) } io.WriteString(toFront, "foo") toFront.Close() fromProxy, err := back.Accept() if err != nil { t.Fatal(err) } defer fromProxy.Close() _, err = io.ReadAll(fromProxy) if err != nil { t.Fatal(err) } wg.Wait() } func testSpliceNoUnixpacket(t *testing.T) { clientUp, serverUp := spliceTestSocketPair(t, "unixpacket") defer clientUp.Close() defer serverUp.Close() clientDown, serverDown := spliceTestSocketPair(t, "tcp") defer clientDown.Close() defer serverDown.Close() // If splice called poll.Splice here, we'd get err == syscall.EINVAL // and handled == false. If poll.Splice gets an EINVAL on the first // try, it assumes the kernel it's running on doesn't support splice // for unix sockets and returns handled == false. This works for our // purposes by somewhat of an accident, but is not entirely correct. // // What we want is err == nil and handled == false, i.e. we never // called poll.Splice, because we know the unix socket's network. _, err, handled := spliceFrom(serverDown.(*TCPConn).fd, serverUp) if err != nil || handled != false { t.Fatalf("got err = %v, handled = %t, want nil error, handled == false", err, handled) } } func testSpliceNoUnixgram(t *testing.T) { addr, err := ResolveUnixAddr("unixgram", testUnixAddr(t)) if err != nil { t.Fatal(err) } defer os.Remove(addr.Name) up, err := ListenUnixgram("unixgram", addr) if err != nil { t.Fatal(err) } defer up.Close() clientDown, serverDown := spliceTestSocketPair(t, "tcp") defer clientDown.Close() defer serverDown.Close() // Analogous to testSpliceNoUnixpacket. _, err, handled := spliceFrom(serverDown.(*TCPConn).fd, up) if err != nil || handled != false { t.Fatalf("got err = %v, handled = %t, want nil error, handled == false", err, handled) } } func BenchmarkSplice(b *testing.B) { testHookUninstaller.Do(uninstallTestHooks) b.Run("tcp-to-tcp", func(b *testing.B) { benchSplice(b, "tcp", "tcp") }) b.Run("unix-to-tcp", func(b *testing.B) { benchSplice(b, "unix", "tcp") }) b.Run("tcp-to-unix", func(b *testing.B) { benchSplice(b, "tcp", "unix") }) } func benchSplice(b *testing.B, upNet, downNet string) { for i := 0; i <= 10; i++ { chunkSize := 1 << uint(i+10) tc := spliceTestCase{ upNet: upNet, downNet: downNet, chunkSize: chunkSize, } b.Run(strconv.Itoa(chunkSize), tc.bench) } } func (tc spliceTestCase) bench(b *testing.B) { // To benchmark the genericReadFrom code path, set this to false. useSplice := true clientUp, serverUp := spliceTestSocketPair(b, tc.upNet) defer serverUp.Close() cleanup, err := startSpliceClient(clientUp, "w", tc.chunkSize, tc.chunkSize*b.N) if err != nil { b.Fatal(err) } defer cleanup() clientDown, serverDown := spliceTestSocketPair(b, tc.downNet) defer serverDown.Close() cleanup, err = startSpliceClient(clientDown, "r", tc.chunkSize, tc.chunkSize*b.N) if err != nil { b.Fatal(err) } defer cleanup() b.SetBytes(int64(tc.chunkSize)) b.ResetTimer() if useSplice { _, err := io.Copy(serverDown, serverUp) if err != nil { b.Fatal(err) } } else { type onlyReader struct { io.Reader } _, err := io.Copy(serverDown, onlyReader{serverUp}) if err != nil { b.Fatal(err) } } } func spliceTestSocketPair(t testing.TB, net string) (client, server Conn) { t.Helper() ln := newLocalListener(t, net) defer ln.Close() var cerr, serr error acceptDone := make(chan struct{}) go func() { server, serr = ln.Accept() acceptDone <- struct{}{} }() client, cerr = Dial(ln.Addr().Network(), ln.Addr().String()) <-acceptDone if cerr != nil { if server != nil { server.Close() } t.Fatal(cerr) } if serr != nil { if client != nil { client.Close() } t.Fatal(serr) } return client, server } func startSpliceClient(conn Conn, op string, chunkSize, totalSize int) (func(), error) { f, err := conn.(interface{ File() (*os.File, error) }).File() if err != nil { return nil, err } cmd := exec.Command(os.Args[0], os.Args[1:]...) cmd.Env = []string{ "GO_NET_TEST_SPLICE=1", "GO_NET_TEST_SPLICE_OP=" + op, "GO_NET_TEST_SPLICE_CHUNK_SIZE=" + strconv.Itoa(chunkSize), "GO_NET_TEST_SPLICE_TOTAL_SIZE=" + strconv.Itoa(totalSize), "TMPDIR=" + os.Getenv("TMPDIR"), } cmd.ExtraFiles = append(cmd.ExtraFiles, f) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { return nil, err } donec := make(chan struct{}) go func() { cmd.Wait() conn.Close() f.Close() close(donec) }() return func() { select { case <-donec: case <-time.After(5 * time.Second): log.Printf("killing splice client after 5 second shutdown timeout") cmd.Process.Kill() select { case <-donec: case <-time.After(5 * time.Second): log.Printf("splice client didn't die after 10 seconds") } } }, nil } func init() { if os.Getenv("GO_NET_TEST_SPLICE") == "" { return } defer os.Exit(0) f := os.NewFile(uintptr(3), "splice-test-conn") defer f.Close() conn, err := FileConn(f) if err != nil { log.Fatal(err) } var chunkSize int if chunkSize, err = strconv.Atoi(os.Getenv("GO_NET_TEST_SPLICE_CHUNK_SIZE")); err != nil { log.Fatal(err) } buf := make([]byte, chunkSize) var totalSize int if totalSize, err = strconv.Atoi(os.Getenv("GO_NET_TEST_SPLICE_TOTAL_SIZE")); err != nil { log.Fatal(err) } var fn func([]byte) (int, error) switch op := os.Getenv("GO_NET_TEST_SPLICE_OP"); op { case "r": fn = conn.Read case "w": defer conn.Close() fn = conn.Write default: log.Fatalf("unknown op %q", op) } var n int for count := 0; count < totalSize; count += n { if count+chunkSize > totalSize { buf = buf[:totalSize-count] } var err error if n, err = fn(buf); err != nil { return } } } func BenchmarkSpliceFile(b *testing.B) { b.Run("tcp-to-file", func(b *testing.B) { benchmarkSpliceFile(b, "tcp") }) b.Run("unix-to-file", func(b *testing.B) { benchmarkSpliceFile(b, "unix") }) } func benchmarkSpliceFile(b *testing.B, proto string) { for i := 0; i <= 10; i++ { size := 1 << (i + 10) bench := spliceFileBench{ proto: proto, chunkSize: size, } b.Run(strconv.Itoa(size), bench.benchSpliceFile) } } type spliceFileBench struct { proto string chunkSize int } func (bench spliceFileBench) benchSpliceFile(b *testing.B) { f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0) if err != nil { b.Fatal(err) } defer f.Close() totalSize := b.N * bench.chunkSize client, server := spliceTestSocketPair(b, bench.proto) defer server.Close() cleanup, err := startSpliceClient(client, "w", bench.chunkSize, totalSize) if err != nil { client.Close() b.Fatalf("failed to start splice client: %v", err) } defer cleanup() b.ReportAllocs() b.SetBytes(int64(bench.chunkSize)) b.ResetTimer() got, err := io.Copy(f, server) if err != nil { b.Fatalf("failed to ReadFrom with error: %v", err) } if want := int64(totalSize); got != want { b.Errorf("bytes sent mismatch, got: %d, want: %d", got, want) } }
Upload File
Create Folder