github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/pkg/net/http/fcgi/fcgi_test.go (about)

     1  // Copyright 2011 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 fcgi
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"io"
    11  	"testing"
    12  )
    13  
    14  var sizeTests = []struct {
    15  	size  uint32
    16  	bytes []byte
    17  }{
    18  	{0, []byte{0x00}},
    19  	{127, []byte{0x7F}},
    20  	{128, []byte{0x80, 0x00, 0x00, 0x80}},
    21  	{1000, []byte{0x80, 0x00, 0x03, 0xE8}},
    22  	{33554431, []byte{0x81, 0xFF, 0xFF, 0xFF}},
    23  }
    24  
    25  func TestSize(t *testing.T) {
    26  	b := make([]byte, 4)
    27  	for i, test := range sizeTests {
    28  		n := encodeSize(b, test.size)
    29  		if !bytes.Equal(b[:n], test.bytes) {
    30  			t.Errorf("%d expected %x, encoded %x", i, test.bytes, b)
    31  		}
    32  		size, n := readSize(test.bytes)
    33  		if size != test.size {
    34  			t.Errorf("%d expected %d, read %d", i, test.size, size)
    35  		}
    36  		if len(test.bytes) != n {
    37  			t.Errorf("%d did not consume all the bytes", i)
    38  		}
    39  	}
    40  }
    41  
    42  var streamTests = []struct {
    43  	desc    string
    44  	recType recType
    45  	reqId   uint16
    46  	content []byte
    47  	raw     []byte
    48  }{
    49  	{"single record", typeStdout, 1, nil,
    50  		[]byte{1, byte(typeStdout), 0, 1, 0, 0, 0, 0},
    51  	},
    52  	// this data will have to be split into two records
    53  	{"two records", typeStdin, 300, make([]byte, 66000),
    54  		bytes.Join([][]byte{
    55  			// header for the first record
    56  			{1, byte(typeStdin), 0x01, 0x2C, 0xFF, 0xFF, 1, 0},
    57  			make([]byte, 65536),
    58  			// header for the second
    59  			{1, byte(typeStdin), 0x01, 0x2C, 0x01, 0xD1, 7, 0},
    60  			make([]byte, 472),
    61  			// header for the empty record
    62  			{1, byte(typeStdin), 0x01, 0x2C, 0, 0, 0, 0},
    63  		},
    64  			nil),
    65  	},
    66  }
    67  
    68  type nilCloser struct {
    69  	io.ReadWriter
    70  }
    71  
    72  func (c *nilCloser) Close() error { return nil }
    73  
    74  func TestStreams(t *testing.T) {
    75  	var rec record
    76  outer:
    77  	for _, test := range streamTests {
    78  		buf := bytes.NewBuffer(test.raw)
    79  		var content []byte
    80  		for buf.Len() > 0 {
    81  			if err := rec.read(buf); err != nil {
    82  				t.Errorf("%s: error reading record: %v", test.desc, err)
    83  				continue outer
    84  			}
    85  			content = append(content, rec.content()...)
    86  		}
    87  		if rec.h.Type != test.recType {
    88  			t.Errorf("%s: got type %d expected %d", test.desc, rec.h.Type, test.recType)
    89  			continue
    90  		}
    91  		if rec.h.Id != test.reqId {
    92  			t.Errorf("%s: got request ID %d expected %d", test.desc, rec.h.Id, test.reqId)
    93  			continue
    94  		}
    95  		if !bytes.Equal(content, test.content) {
    96  			t.Errorf("%s: read wrong content", test.desc)
    97  			continue
    98  		}
    99  		buf.Reset()
   100  		c := newConn(&nilCloser{buf})
   101  		w := newWriter(c, test.recType, test.reqId)
   102  		if _, err := w.Write(test.content); err != nil {
   103  			t.Errorf("%s: error writing record: %v", test.desc, err)
   104  			continue
   105  		}
   106  		if err := w.Close(); err != nil {
   107  			t.Errorf("%s: error closing stream: %v", test.desc, err)
   108  			continue
   109  		}
   110  		if !bytes.Equal(buf.Bytes(), test.raw) {
   111  			t.Errorf("%s: wrote wrong content", test.desc)
   112  		}
   113  	}
   114  }
   115  
   116  type writeOnlyConn struct {
   117  	buf []byte
   118  }
   119  
   120  func (c *writeOnlyConn) Write(p []byte) (int, error) {
   121  	c.buf = append(c.buf, p...)
   122  	return len(p), nil
   123  }
   124  
   125  func (c *writeOnlyConn) Read(p []byte) (int, error) {
   126  	return 0, errors.New("conn is write-only")
   127  }
   128  
   129  func (c *writeOnlyConn) Close() error {
   130  	return nil
   131  }
   132  
   133  func TestGetValues(t *testing.T) {
   134  	var rec record
   135  	rec.h.Type = typeGetValues
   136  
   137  	wc := new(writeOnlyConn)
   138  	c := newChild(wc, nil)
   139  	err := c.handleRecord(&rec)
   140  	if err != nil {
   141  		t.Fatalf("handleRecord: %v", err)
   142  	}
   143  
   144  	const want = "\x01\n\x00\x00\x00\x12\x06\x00" +
   145  		"\x0f\x01FCGI_MPXS_CONNS1" +
   146  		"\x00\x00\x00\x00\x00\x00\x01\n\x00\x00\x00\x00\x00\x00"
   147  	if got := string(wc.buf); got != want {
   148  		t.Errorf(" got: %q\nwant: %q\n", got, want)
   149  	}
   150  }