github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/net/sendfile_test.go (about) 1 // Copyright 2016 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 package net 6 7 import ( 8 "bytes" 9 "crypto/sha256" 10 "encoding/hex" 11 "fmt" 12 "io" 13 "os" 14 "testing" 15 ) 16 17 const ( 18 twain = "testdata/Mark.Twain-Tom.Sawyer.txt" 19 twainLen = 387851 20 twainSHA256 = "461eb7cb2d57d293fc680c836464c9125e4382be3596f7d415093ae9db8fcb0e" 21 ) 22 23 func TestSendfile(t *testing.T) { 24 ln, err := newLocalListener("tcp") 25 if err != nil { 26 t.Fatal(err) 27 } 28 defer ln.Close() 29 30 errc := make(chan error, 1) 31 go func(ln Listener) { 32 // Wait for a connection. 33 conn, err := ln.Accept() 34 if err != nil { 35 errc <- err 36 close(errc) 37 return 38 } 39 40 go func() { 41 defer close(errc) 42 defer conn.Close() 43 44 f, err := os.Open(twain) 45 if err != nil { 46 errc <- err 47 return 48 } 49 defer f.Close() 50 51 // Return file data using io.Copy, which should use 52 // sendFile if available. 53 sbytes, err := io.Copy(conn, f) 54 if err != nil { 55 errc <- err 56 return 57 } 58 59 if sbytes != twainLen { 60 errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, twainLen) 61 return 62 } 63 }() 64 }(ln) 65 66 // Connect to listener to retrieve file and verify digest matches 67 // expected. 68 c, err := Dial("tcp", ln.Addr().String()) 69 if err != nil { 70 t.Fatal(err) 71 } 72 defer c.Close() 73 74 h := sha256.New() 75 rbytes, err := io.Copy(h, c) 76 if err != nil { 77 t.Error(err) 78 } 79 80 if rbytes != twainLen { 81 t.Errorf("received %d bytes; expected %d", rbytes, twainLen) 82 } 83 84 if res := hex.EncodeToString(h.Sum(nil)); res != twainSHA256 { 85 t.Error("retrieved data hash did not match") 86 } 87 88 for err := range errc { 89 t.Error(err) 90 } 91 } 92 93 func TestSendfileSeeked(t *testing.T) { 94 ln, err := newLocalListener("tcp") 95 if err != nil { 96 t.Fatal(err) 97 } 98 defer ln.Close() 99 100 const seekTo = 65 << 10 101 const sendSize = 10 << 10 102 103 errc := make(chan error, 1) 104 go func(ln Listener) { 105 // Wait for a connection. 106 conn, err := ln.Accept() 107 if err != nil { 108 errc <- err 109 close(errc) 110 return 111 } 112 113 go func() { 114 defer close(errc) 115 defer conn.Close() 116 117 f, err := os.Open(twain) 118 if err != nil { 119 errc <- err 120 return 121 } 122 defer f.Close() 123 if _, err := f.Seek(seekTo, os.SEEK_SET); err != nil { 124 errc <- err 125 return 126 } 127 128 _, err = io.CopyN(conn, f, sendSize) 129 if err != nil { 130 errc <- err 131 return 132 } 133 }() 134 }(ln) 135 136 c, err := Dial("tcp", ln.Addr().String()) 137 if err != nil { 138 t.Fatal(err) 139 } 140 defer c.Close() 141 142 buf := new(bytes.Buffer) 143 buf.ReadFrom(c) 144 145 if buf.Len() != sendSize { 146 t.Errorf("Got %d bytes; want %d", buf.Len(), sendSize) 147 } 148 149 for err := range errc { 150 t.Error(err) 151 } 152 }