github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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 // +build !js 6 7 package net 8 9 import ( 10 "bytes" 11 "crypto/sha256" 12 "encoding/hex" 13 "fmt" 14 "io" 15 "os" 16 "testing" 17 ) 18 19 const ( 20 newton = "../testdata/Isaac.Newton-Opticks.txt" 21 newtonLen = 567198 22 newtonSHA256 = "d4a9ac22462b35e7821a4f2706c211093da678620a8f9997989ee7cf8d507bbd" 23 ) 24 25 func TestSendfile(t *testing.T) { 26 ln, err := newLocalListener("tcp") 27 if err != nil { 28 t.Fatal(err) 29 } 30 defer ln.Close() 31 32 errc := make(chan error, 1) 33 go func(ln Listener) { 34 // Wait for a connection. 35 conn, err := ln.Accept() 36 if err != nil { 37 errc <- err 38 close(errc) 39 return 40 } 41 42 go func() { 43 defer close(errc) 44 defer conn.Close() 45 46 f, err := os.Open(newton) 47 if err != nil { 48 errc <- err 49 return 50 } 51 defer f.Close() 52 53 // Return file data using io.Copy, which should use 54 // sendFile if available. 55 sbytes, err := io.Copy(conn, f) 56 if err != nil { 57 errc <- err 58 return 59 } 60 61 if sbytes != newtonLen { 62 errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, newtonLen) 63 return 64 } 65 }() 66 }(ln) 67 68 // Connect to listener to retrieve file and verify digest matches 69 // expected. 70 c, err := Dial("tcp", ln.Addr().String()) 71 if err != nil { 72 t.Fatal(err) 73 } 74 defer c.Close() 75 76 h := sha256.New() 77 rbytes, err := io.Copy(h, c) 78 if err != nil { 79 t.Error(err) 80 } 81 82 if rbytes != newtonLen { 83 t.Errorf("received %d bytes; expected %d", rbytes, newtonLen) 84 } 85 86 if res := hex.EncodeToString(h.Sum(nil)); res != newtonSHA256 { 87 t.Error("retrieved data hash did not match") 88 } 89 90 for err := range errc { 91 t.Error(err) 92 } 93 } 94 95 func TestSendfileParts(t *testing.T) { 96 ln, err := newLocalListener("tcp") 97 if err != nil { 98 t.Fatal(err) 99 } 100 defer ln.Close() 101 102 errc := make(chan error, 1) 103 go func(ln Listener) { 104 // Wait for a connection. 105 conn, err := ln.Accept() 106 if err != nil { 107 errc <- err 108 close(errc) 109 return 110 } 111 112 go func() { 113 defer close(errc) 114 defer conn.Close() 115 116 f, err := os.Open(newton) 117 if err != nil { 118 errc <- err 119 return 120 } 121 defer f.Close() 122 123 for i := 0; i < 3; i++ { 124 // Return file data using io.CopyN, which should use 125 // sendFile if available. 126 _, err = io.CopyN(conn, f, 3) 127 if err != nil { 128 errc <- err 129 return 130 } 131 } 132 }() 133 }(ln) 134 135 c, err := Dial("tcp", ln.Addr().String()) 136 if err != nil { 137 t.Fatal(err) 138 } 139 defer c.Close() 140 141 buf := new(bytes.Buffer) 142 buf.ReadFrom(c) 143 144 if want, have := "Produced ", buf.String(); have != want { 145 t.Errorf("unexpected server reply %q, want %q", have, want) 146 } 147 148 for err := range errc { 149 t.Error(err) 150 } 151 } 152 153 func TestSendfileSeeked(t *testing.T) { 154 ln, err := newLocalListener("tcp") 155 if err != nil { 156 t.Fatal(err) 157 } 158 defer ln.Close() 159 160 const seekTo = 65 << 10 161 const sendSize = 10 << 10 162 163 errc := make(chan error, 1) 164 go func(ln Listener) { 165 // Wait for a connection. 166 conn, err := ln.Accept() 167 if err != nil { 168 errc <- err 169 close(errc) 170 return 171 } 172 173 go func() { 174 defer close(errc) 175 defer conn.Close() 176 177 f, err := os.Open(newton) 178 if err != nil { 179 errc <- err 180 return 181 } 182 defer f.Close() 183 if _, err := f.Seek(seekTo, os.SEEK_SET); err != nil { 184 errc <- err 185 return 186 } 187 188 _, err = io.CopyN(conn, f, sendSize) 189 if err != nil { 190 errc <- err 191 return 192 } 193 }() 194 }(ln) 195 196 c, err := Dial("tcp", ln.Addr().String()) 197 if err != nil { 198 t.Fatal(err) 199 } 200 defer c.Close() 201 202 buf := new(bytes.Buffer) 203 buf.ReadFrom(c) 204 205 if buf.Len() != sendSize { 206 t.Errorf("Got %d bytes; want %d", buf.Len(), sendSize) 207 } 208 209 for err := range errc { 210 t.Error(err) 211 } 212 }