...
Run Format

Source file src/net/sendfile_test.go

Documentation: net

     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  	twain       = "testdata/Mark.Twain-Tom.Sawyer.txt"
    21  	twainLen    = 387851
    22  	twainSHA256 = "461eb7cb2d57d293fc680c836464c9125e4382be3596f7d415093ae9db8fcb0e"
    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(twain)
    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 != twainLen {
    62  				errc <- fmt.Errorf("sent %d bytes; expected %d", sbytes, twainLen)
    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 != twainLen {
    83  		t.Errorf("received %d bytes; expected %d", rbytes, twainLen)
    84  	}
    85  
    86  	if res := hex.EncodeToString(h.Sum(nil)); res != twainSHA256 {
    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(twain)
   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(twain)
   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  }
   213  

View as plain text