github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/klauspost/compress/gzip/gunzip_test.go (about)

     1  // Copyright 2009 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 gzip
     6  
     7  import (
     8  	"bytes"
     9  	oldgz "compress/gzip"
    10  	"crypto/rand"
    11  	"io"
    12  	"io/ioutil"
    13  	"os"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  type gunzipTest struct {
    20  	name string
    21  	desc string
    22  	raw  string
    23  	gzip []byte
    24  	err  error
    25  }
    26  
    27  var gunzipTests = []gunzipTest{
    28  	{ // has 1 empty fixed-huffman block
    29  		"empty.txt",
    30  		"empty.txt",
    31  		"",
    32  		[]byte{
    33  			0x1f, 0x8b, 0x08, 0x08, 0xf7, 0x5e, 0x14, 0x4a,
    34  			0x00, 0x03, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
    35  			0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
    36  			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    37  		},
    38  		nil,
    39  	},
    40  	{ // has 1 non-empty fixed huffman block
    41  		"hello.txt",
    42  		"hello.txt",
    43  		"hello world\n",
    44  		[]byte{
    45  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
    46  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
    47  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
    48  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
    49  			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
    50  			0x00, 0x00,
    51  		},
    52  		nil,
    53  	},
    54  	{ // concatenation
    55  		"hello.txt",
    56  		"hello.txt x2",
    57  		"hello world\n" +
    58  			"hello world\n",
    59  		[]byte{
    60  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
    61  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
    62  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
    63  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
    64  			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
    65  			0x00, 0x00,
    66  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
    67  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
    68  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
    69  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
    70  			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
    71  			0x00, 0x00,
    72  		},
    73  		nil,
    74  	},
    75  	{ // has a fixed huffman block with some length-distance pairs
    76  		"shesells.txt",
    77  		"shesells.txt",
    78  		"she sells seashells by the seashore\n",
    79  		[]byte{
    80  			0x1f, 0x8b, 0x08, 0x08, 0x72, 0x66, 0x8b, 0x4a,
    81  			0x00, 0x03, 0x73, 0x68, 0x65, 0x73, 0x65, 0x6c,
    82  			0x6c, 0x73, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x2b,
    83  			0xce, 0x48, 0x55, 0x28, 0x4e, 0xcd, 0xc9, 0x29,
    84  			0x06, 0x92, 0x89, 0xc5, 0x19, 0x60, 0x56, 0x52,
    85  			0xa5, 0x42, 0x09, 0x58, 0x18, 0x28, 0x90, 0x5f,
    86  			0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
    87  			0x24, 0x00, 0x00, 0x00,
    88  		},
    89  		nil,
    90  	},
    91  	{ // has dynamic huffman blocks
    92  		"gettysburg",
    93  		"gettysburg",
    94  		"  Four score and seven years ago our fathers brought forth on\n" +
    95  			"this continent, a new nation, conceived in Liberty, and dedicated\n" +
    96  			"to the proposition that all men are created equal.\n" +
    97  			"  Now we are engaged in a great Civil War, testing whether that\n" +
    98  			"nation, or any nation so conceived and so dedicated, can long\n" +
    99  			"endure.\n" +
   100  			"  We are met on a great battle-field of that war.\n" +
   101  			"  We have come to dedicate a portion of that field, as a final\n" +
   102  			"resting place for those who here gave their lives that that\n" +
   103  			"nation might live.  It is altogether fitting and proper that\n" +
   104  			"we should do this.\n" +
   105  			"  But, in a larger sense, we can not dedicate — we can not\n" +
   106  			"consecrate — we can not hallow — this ground.\n" +
   107  			"  The brave men, living and dead, who struggled here, have\n" +
   108  			"consecrated it, far above our poor power to add or detract.\n" +
   109  			"The world will little note, nor long remember what we say here,\n" +
   110  			"but it can never forget what they did here.\n" +
   111  			"  It is for us the living, rather, to be dedicated here to the\n" +
   112  			"unfinished work which they who fought here have thus far so\n" +
   113  			"nobly advanced.  It is rather for us to be here dedicated to\n" +
   114  			"the great task remaining before us — that from these honored\n" +
   115  			"dead we take increased devotion to that cause for which they\n" +
   116  			"gave the last full measure of devotion —\n" +
   117  			"  that we here highly resolve that these dead shall not have\n" +
   118  			"died in vain — that this nation, under God, shall have a new\n" +
   119  			"birth of freedom — and that government of the people, by the\n" +
   120  			"people, for the people, shall not perish from this earth.\n" +
   121  			"\n" +
   122  			"Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania\n",
   123  		[]byte{
   124  			0x1f, 0x8b, 0x08, 0x08, 0xd1, 0x12, 0x2b, 0x4a,
   125  			0x00, 0x03, 0x67, 0x65, 0x74, 0x74, 0x79, 0x73,
   126  			0x62, 0x75, 0x72, 0x67, 0x00, 0x65, 0x54, 0xcd,
   127  			0x6e, 0xd4, 0x30, 0x10, 0xbe, 0xfb, 0x29, 0xe6,
   128  			0x01, 0x42, 0xa5, 0x0a, 0x09, 0xc1, 0x11, 0x90,
   129  			0x40, 0x48, 0xa8, 0xe2, 0x80, 0xd4, 0xf3, 0x24,
   130  			0x9e, 0x24, 0x56, 0xbd, 0x9e, 0xc5, 0x76, 0x76,
   131  			0x95, 0x1b, 0x0f, 0xc1, 0x13, 0xf2, 0x24, 0x7c,
   132  			0x63, 0x77, 0x9b, 0x4a, 0x5c, 0xaa, 0x6e, 0x6c,
   133  			0xcf, 0x7c, 0x7f, 0x33, 0x44, 0x5f, 0x74, 0xcb,
   134  			0x54, 0x26, 0xcd, 0x42, 0x9c, 0x3c, 0x15, 0xb9,
   135  			0x48, 0xa2, 0x5d, 0x38, 0x17, 0xe2, 0x45, 0xc9,
   136  			0x4e, 0x67, 0xae, 0xab, 0xe0, 0xf7, 0x98, 0x75,
   137  			0x5b, 0xd6, 0x4a, 0xb3, 0xe6, 0xba, 0x92, 0x26,
   138  			0x57, 0xd7, 0x50, 0x68, 0xd2, 0x54, 0x43, 0x92,
   139  			0x54, 0x07, 0x62, 0x4a, 0x72, 0xa5, 0xc4, 0x35,
   140  			0x68, 0x1a, 0xec, 0x60, 0x92, 0x70, 0x11, 0x4f,
   141  			0x21, 0xd1, 0xf7, 0x30, 0x4a, 0xae, 0xfb, 0xd0,
   142  			0x9a, 0x78, 0xf1, 0x61, 0xe2, 0x2a, 0xde, 0x55,
   143  			0x25, 0xd4, 0xa6, 0x73, 0xd6, 0xb3, 0x96, 0x60,
   144  			0xef, 0xf0, 0x9b, 0x2b, 0x71, 0x8c, 0x74, 0x02,
   145  			0x10, 0x06, 0xac, 0x29, 0x8b, 0xdd, 0x25, 0xf9,
   146  			0xb5, 0x71, 0xbc, 0x73, 0x44, 0x0f, 0x7a, 0xa5,
   147  			0xab, 0xb4, 0x33, 0x49, 0x0b, 0x2f, 0xbd, 0x03,
   148  			0xd3, 0x62, 0x17, 0xe9, 0x73, 0xb8, 0x84, 0x48,
   149  			0x8f, 0x9c, 0x07, 0xaa, 0x52, 0x00, 0x6d, 0xa1,
   150  			0xeb, 0x2a, 0xc6, 0xa0, 0x95, 0x76, 0x37, 0x78,
   151  			0x9a, 0x81, 0x65, 0x7f, 0x46, 0x4b, 0x45, 0x5f,
   152  			0xe1, 0x6d, 0x42, 0xe8, 0x01, 0x13, 0x5c, 0x38,
   153  			0x51, 0xd4, 0xb4, 0x38, 0x49, 0x7e, 0xcb, 0x62,
   154  			0x28, 0x1e, 0x3b, 0x82, 0x93, 0x54, 0x48, 0xf1,
   155  			0xd2, 0x7d, 0xe4, 0x5a, 0xa3, 0xbc, 0x99, 0x83,
   156  			0x44, 0x4f, 0x3a, 0x77, 0x36, 0x57, 0xce, 0xcf,
   157  			0x2f, 0x56, 0xbe, 0x80, 0x90, 0x9e, 0x84, 0xea,
   158  			0x51, 0x1f, 0x8f, 0xcf, 0x90, 0xd4, 0x60, 0xdc,
   159  			0x5e, 0xb4, 0xf7, 0x10, 0x0b, 0x26, 0xe0, 0xff,
   160  			0xc4, 0xd1, 0xe5, 0x67, 0x2e, 0xe7, 0xc8, 0x93,
   161  			0x98, 0x05, 0xb8, 0xa8, 0x45, 0xc0, 0x4d, 0x09,
   162  			0xdc, 0x84, 0x16, 0x2b, 0x0d, 0x9a, 0x21, 0x53,
   163  			0x04, 0x8b, 0xd2, 0x0b, 0xbd, 0xa2, 0x4c, 0xa7,
   164  			0x60, 0xee, 0xd9, 0xe1, 0x1d, 0xd1, 0xb7, 0x4a,
   165  			0x30, 0x8f, 0x63, 0xd5, 0xa5, 0x8b, 0x33, 0x87,
   166  			0xda, 0x1a, 0x18, 0x79, 0xf3, 0xe3, 0xa6, 0x17,
   167  			0x94, 0x2e, 0xab, 0x6e, 0xa0, 0xe3, 0xcd, 0xac,
   168  			0x50, 0x8c, 0xca, 0xa7, 0x0d, 0x76, 0x37, 0xd1,
   169  			0x23, 0xe7, 0x05, 0x57, 0x8b, 0xa4, 0x22, 0x83,
   170  			0xd9, 0x62, 0x52, 0x25, 0xad, 0x07, 0xbb, 0xbf,
   171  			0xbf, 0xff, 0xbc, 0xfa, 0xee, 0x20, 0x73, 0x91,
   172  			0x29, 0xff, 0x7f, 0x02, 0x71, 0x62, 0x84, 0xb5,
   173  			0xf6, 0xb5, 0x25, 0x6b, 0x41, 0xde, 0x92, 0xb7,
   174  			0x76, 0x3f, 0x91, 0x91, 0x31, 0x1b, 0x41, 0x84,
   175  			0x62, 0x30, 0x0a, 0x37, 0xa4, 0x5e, 0x18, 0x3a,
   176  			0x99, 0x08, 0xa5, 0xe6, 0x6d, 0x59, 0x22, 0xec,
   177  			0x33, 0x39, 0x86, 0x26, 0xf5, 0xab, 0x66, 0xc8,
   178  			0x08, 0x20, 0xcf, 0x0c, 0xd7, 0x47, 0x45, 0x21,
   179  			0x0b, 0xf6, 0x59, 0xd5, 0xfe, 0x5c, 0x8d, 0xaa,
   180  			0x12, 0x7b, 0x6f, 0xa1, 0xf0, 0x52, 0x33, 0x4f,
   181  			0xf5, 0xce, 0x59, 0xd3, 0xab, 0x66, 0x10, 0xbf,
   182  			0x06, 0xc4, 0x31, 0x06, 0x73, 0xd6, 0x80, 0xa2,
   183  			0x78, 0xc2, 0x45, 0xcb, 0x03, 0x65, 0x39, 0xc9,
   184  			0x09, 0xd1, 0x06, 0x04, 0x33, 0x1a, 0x5a, 0xf1,
   185  			0xde, 0x01, 0xb8, 0x71, 0x83, 0xc4, 0xb5, 0xb3,
   186  			0xc3, 0x54, 0x65, 0x33, 0x0d, 0x5a, 0xf7, 0x9b,
   187  			0x90, 0x7c, 0x27, 0x1f, 0x3a, 0x58, 0xa3, 0xd8,
   188  			0xfd, 0x30, 0x5f, 0xb7, 0xd2, 0x66, 0xa2, 0x93,
   189  			0x1c, 0x28, 0xb7, 0xe9, 0x1b, 0x0c, 0xe1, 0x28,
   190  			0x47, 0x26, 0xbb, 0xe9, 0x7d, 0x7e, 0xdc, 0x96,
   191  			0x10, 0x92, 0x50, 0x56, 0x7c, 0x06, 0xe2, 0x27,
   192  			0xb4, 0x08, 0xd3, 0xda, 0x7b, 0x98, 0x34, 0x73,
   193  			0x9f, 0xdb, 0xf6, 0x62, 0xed, 0x31, 0x41, 0x13,
   194  			0xd3, 0xa2, 0xa8, 0x4b, 0x3a, 0xc6, 0x1d, 0xe4,
   195  			0x2f, 0x8c, 0xf8, 0xfb, 0x97, 0x64, 0xf4, 0xb6,
   196  			0x2f, 0x80, 0x5a, 0xf3, 0x56, 0xe0, 0x40, 0x50,
   197  			0xd5, 0x19, 0xd0, 0x1e, 0xfc, 0xca, 0xe5, 0xc9,
   198  			0xd4, 0x60, 0x00, 0x81, 0x2e, 0xa3, 0xcc, 0xb6,
   199  			0x52, 0xf0, 0xb4, 0xdb, 0x69, 0x99, 0xce, 0x7a,
   200  			0x32, 0x4c, 0x08, 0xed, 0xaa, 0x10, 0x10, 0xe3,
   201  			0x6f, 0xee, 0x99, 0x68, 0x95, 0x9f, 0x04, 0x71,
   202  			0xb2, 0x49, 0x2f, 0x62, 0xa6, 0x5e, 0xb4, 0xef,
   203  			0x02, 0xed, 0x4f, 0x27, 0xde, 0x4a, 0x0f, 0xfd,
   204  			0xc1, 0xcc, 0xdd, 0x02, 0x8f, 0x08, 0x16, 0x54,
   205  			0xdf, 0xda, 0xca, 0xe0, 0x82, 0xf1, 0xb4, 0x31,
   206  			0x7a, 0xa9, 0x81, 0xfe, 0x90, 0xb7, 0x3e, 0xdb,
   207  			0xd3, 0x35, 0xc0, 0x20, 0x80, 0x33, 0x46, 0x4a,
   208  			0x63, 0xab, 0xd1, 0x0d, 0x29, 0xd2, 0xe2, 0x84,
   209  			0xb8, 0xdb, 0xfa, 0xe9, 0x89, 0x44, 0x86, 0x7c,
   210  			0xe8, 0x0b, 0xe6, 0x02, 0x6a, 0x07, 0x9b, 0x96,
   211  			0xd0, 0xdb, 0x2e, 0x41, 0x4c, 0xa1, 0xd5, 0x57,
   212  			0x45, 0x14, 0xfb, 0xe3, 0xa6, 0x72, 0x5b, 0x87,
   213  			0x6e, 0x0c, 0x6d, 0x5b, 0xce, 0xe0, 0x2f, 0xe2,
   214  			0x21, 0x81, 0x95, 0xb0, 0xe8, 0xb6, 0x32, 0x0b,
   215  			0xb2, 0x98, 0x13, 0x52, 0x5d, 0xfb, 0xec, 0x63,
   216  			0x17, 0x8a, 0x9e, 0x23, 0x22, 0x36, 0xee, 0xcd,
   217  			0xda, 0xdb, 0xcf, 0x3e, 0xf1, 0xc7, 0xf1, 0x01,
   218  			0x12, 0x93, 0x0a, 0xeb, 0x6f, 0xf2, 0x02, 0x15,
   219  			0x96, 0x77, 0x5d, 0xef, 0x9c, 0xfb, 0x88, 0x91,
   220  			0x59, 0xf9, 0x84, 0xdd, 0x9b, 0x26, 0x8d, 0x80,
   221  			0xf9, 0x80, 0x66, 0x2d, 0xac, 0xf7, 0x1f, 0x06,
   222  			0xba, 0x7f, 0xff, 0xee, 0xed, 0x40, 0x5f, 0xa5,
   223  			0xd6, 0xbd, 0x8c, 0x5b, 0x46, 0xd2, 0x7e, 0x48,
   224  			0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
   225  			0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
   226  		},
   227  		nil,
   228  	},
   229  	{ // has 1 non-empty fixed huffman block then garbage
   230  		"hello.txt",
   231  		"hello.txt + garbage",
   232  		"hello world\n",
   233  		[]byte{
   234  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
   235  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
   236  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
   237  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
   238  			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
   239  			0x00, 0x00, 'g', 'a', 'r', 'b', 'a', 'g', 'e', '!', '!', '!',
   240  		},
   241  		ErrHeader,
   242  	},
   243  	{ // has 1 non-empty fixed huffman block not enough header
   244  		"hello.txt",
   245  		"hello.txt + garbage",
   246  		"hello world\n",
   247  		[]byte{
   248  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
   249  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
   250  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
   251  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
   252  			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
   253  			0x00, 0x00, gzipID1,
   254  		},
   255  		io.ErrUnexpectedEOF,
   256  	},
   257  	{ // has 1 non-empty fixed huffman block but corrupt checksum
   258  		"hello.txt",
   259  		"hello.txt + corrupt checksum",
   260  		"hello world\n",
   261  		[]byte{
   262  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
   263  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
   264  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
   265  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
   266  			0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00,
   267  			0x00, 0x00,
   268  		},
   269  		ErrChecksum,
   270  	},
   271  	{ // has 1 non-empty fixed huffman block but corrupt size
   272  		"hello.txt",
   273  		"hello.txt + corrupt size",
   274  		"hello world\n",
   275  		[]byte{
   276  			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
   277  			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
   278  			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
   279  			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
   280  			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0xff, 0x00,
   281  			0x00, 0x00,
   282  		},
   283  		ErrChecksum,
   284  	},
   285  }
   286  
   287  func TestDecompressor(t *testing.T) {
   288  	b := new(bytes.Buffer)
   289  	for _, tt := range gunzipTests {
   290  		in := bytes.NewReader(tt.gzip)
   291  		gzip, err := NewReader(in)
   292  		if err != nil {
   293  			t.Errorf("%s: NewReader: %s", tt.name, err)
   294  			continue
   295  		}
   296  		defer gzip.Close()
   297  		if tt.name != gzip.Name {
   298  			t.Errorf("%s: got name %s", tt.name, gzip.Name)
   299  		}
   300  		b.Reset()
   301  		n, err := io.Copy(b, gzip)
   302  		if err != tt.err {
   303  			t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err)
   304  		}
   305  		s := b.String()
   306  		if s != tt.raw {
   307  			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw)
   308  		}
   309  
   310  		// Test Reader Reset.
   311  		in = bytes.NewReader(tt.gzip)
   312  		err = gzip.Reset(in)
   313  		if err != nil {
   314  			t.Errorf("%s: Reset: %s", tt.name, err)
   315  			continue
   316  		}
   317  		if tt.name != gzip.Name {
   318  			t.Errorf("%s: got name %s", tt.name, gzip.Name)
   319  		}
   320  		b.Reset()
   321  		n, err = io.Copy(b, gzip)
   322  		if err != tt.err {
   323  			t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err)
   324  		}
   325  		s = b.String()
   326  		if s != tt.raw {
   327  			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw)
   328  		}
   329  	}
   330  }
   331  
   332  func TestIssue6550(t *testing.T) {
   333  	f, err := os.Open("testdata/issue6550.gz")
   334  	if err != nil {
   335  		t.Fatal(err)
   336  	}
   337  	gzip, err := NewReader(f)
   338  	if err != nil {
   339  		t.Fatalf("NewReader(testdata/issue6550.gz): %v", err)
   340  	}
   341  	defer gzip.Close()
   342  	done := make(chan bool, 1)
   343  	go func() {
   344  		_, err := io.Copy(ioutil.Discard, gzip)
   345  		if err == nil {
   346  			t.Errorf("Copy succeeded")
   347  		} else {
   348  			t.Logf("Copy failed (correctly): %v", err)
   349  		}
   350  		done <- true
   351  	}()
   352  	select {
   353  	case <-time.After(1 * time.Second):
   354  		t.Errorf("Copy hung")
   355  	case <-done:
   356  		// ok
   357  	}
   358  }
   359  
   360  func TestInitialReset(t *testing.T) {
   361  	var r Reader
   362  	if err := r.Reset(bytes.NewReader(gunzipTests[1].gzip)); err != nil {
   363  		t.Error(err)
   364  	}
   365  	var buf bytes.Buffer
   366  	if _, err := io.Copy(&buf, &r); err != nil {
   367  		t.Error(err)
   368  	}
   369  	if s := buf.String(); s != gunzipTests[1].raw {
   370  		t.Errorf("got %q want %q", s, gunzipTests[1].raw)
   371  	}
   372  }
   373  
   374  func TestMultistreamFalse(t *testing.T) {
   375  	// Find concatenation test.
   376  	var tt gunzipTest
   377  	for _, tt = range gunzipTests {
   378  		if strings.HasSuffix(tt.desc, " x2") {
   379  			goto Found
   380  		}
   381  	}
   382  	t.Fatal("cannot find hello.txt x2 in gunzip tests")
   383  
   384  Found:
   385  	br := bytes.NewReader(tt.gzip)
   386  	var r Reader
   387  	if err := r.Reset(br); err != nil {
   388  		t.Fatalf("first reset: %v", err)
   389  	}
   390  
   391  	// Expect two streams with "hello world\n", then real EOF.
   392  	const hello = "hello world\n"
   393  
   394  	r.Multistream(false)
   395  	data, err := ioutil.ReadAll(&r)
   396  	if string(data) != hello || err != nil {
   397  		t.Fatalf("first stream = %q, %v, want %q, %v", string(data), err, hello, nil)
   398  	}
   399  
   400  	if err := r.Reset(br); err != nil {
   401  		t.Fatalf("second reset: %v", err)
   402  	}
   403  	r.Multistream(false)
   404  	data, err = ioutil.ReadAll(&r)
   405  	if string(data) != hello || err != nil {
   406  		t.Fatalf("second stream = %q, %v, want %q, %v", string(data), err, hello, nil)
   407  	}
   408  
   409  	if err := r.Reset(br); err != io.EOF {
   410  		t.Fatalf("third reset: err=%v, want io.EOF", err)
   411  	}
   412  }
   413  
   414  func TestWriteTo(t *testing.T) {
   415  	input := make([]byte, 100000)
   416  	n, err := rand.Read(input)
   417  	if err != nil {
   418  		t.Fatal(err)
   419  	}
   420  	if n != len(input) {
   421  		t.Fatal("did not fill buffer")
   422  	}
   423  	compressed := &bytes.Buffer{}
   424  	// Do it twice to test MultiStream functionality
   425  	for i := 0; i < 2; i++ {
   426  		w, err := NewWriterLevel(compressed, -2)
   427  		if err != nil {
   428  			t.Fatal(err)
   429  		}
   430  		n, err = w.Write(input)
   431  		if err != nil {
   432  			t.Fatal(err)
   433  		}
   434  		if n != len(input) {
   435  			t.Fatal("did not fill buffer")
   436  		}
   437  		w.Close()
   438  	}
   439  	input = append(input, input...)
   440  	buf := compressed.Bytes()
   441  
   442  	dec, err := NewReader(bytes.NewBuffer(buf))
   443  	if err != nil {
   444  		t.Fatal(err)
   445  	}
   446  	// ReadAll does not use WriteTo, but we wrap it in a NopCloser to be sure.
   447  	readall, err := ioutil.ReadAll(ioutil.NopCloser(dec))
   448  	if err != nil {
   449  		t.Fatal(err)
   450  	}
   451  	if len(readall) != len(input) {
   452  		t.Fatal("did not decompress everything")
   453  	}
   454  	if bytes.Compare(readall, input) != 0 {
   455  		t.Fatal("output did not match input")
   456  	}
   457  
   458  	dec, err = NewReader(bytes.NewBuffer(buf))
   459  	if err != nil {
   460  		t.Fatal(err)
   461  	}
   462  	wtbuf := &bytes.Buffer{}
   463  	written, err := dec.WriteTo(wtbuf)
   464  	if err != nil {
   465  		t.Fatal(err)
   466  	}
   467  	if written != int64(len(input)) {
   468  		t.Error("Returned length did not match, expected", len(input), "got", written)
   469  	}
   470  	if wtbuf.Len() != len(input) {
   471  		t.Error("Actual Length did not match, expected", len(input), "got", wtbuf.Len())
   472  	}
   473  	if bytes.Compare(wtbuf.Bytes(), input) != 0 {
   474  		t.Fatal("output did not match input")
   475  	}
   476  }
   477  
   478  func BenchmarkGunzipCopy(b *testing.B) {
   479  	dat, _ := ioutil.ReadFile("testdata/test.json")
   480  	dat = append(dat, dat...)
   481  	dat = append(dat, dat...)
   482  	dat = append(dat, dat...)
   483  	dat = append(dat, dat...)
   484  	dat = append(dat, dat...)
   485  	dst := &bytes.Buffer{}
   486  	w, _ := NewWriterLevel(dst, 1)
   487  	_, err := w.Write(dat)
   488  	if err != nil {
   489  		b.Fatal(err)
   490  	}
   491  	w.Close()
   492  	input := dst.Bytes()
   493  	b.SetBytes(int64(len(dat)))
   494  	b.ResetTimer()
   495  	for n := 0; n < b.N; n++ {
   496  		r, err := NewReader(bytes.NewBuffer(input))
   497  		if err != nil {
   498  			b.Fatal(err)
   499  		}
   500  		_, err = io.Copy(ioutil.Discard, r)
   501  		if err != nil {
   502  			b.Fatal(err)
   503  		}
   504  	}
   505  }
   506  
   507  func BenchmarkGunzipNoWriteTo(b *testing.B) {
   508  	dat, _ := ioutil.ReadFile("testdata/test.json")
   509  	dat = append(dat, dat...)
   510  	dat = append(dat, dat...)
   511  	dat = append(dat, dat...)
   512  	dat = append(dat, dat...)
   513  	dat = append(dat, dat...)
   514  	dst := &bytes.Buffer{}
   515  	w, _ := NewWriterLevel(dst, 1)
   516  	_, err := w.Write(dat)
   517  	if err != nil {
   518  		b.Fatal(err)
   519  	}
   520  	w.Close()
   521  	input := dst.Bytes()
   522  	r, err := NewReader(bytes.NewBuffer(input))
   523  	if err != nil {
   524  		b.Fatal(err)
   525  	}
   526  	b.SetBytes(int64(len(dat)))
   527  	b.ResetTimer()
   528  	for n := 0; n < b.N; n++ {
   529  		err := r.Reset(bytes.NewBuffer(input))
   530  		if err != nil {
   531  			b.Fatal(err)
   532  		}
   533  		_, err = io.Copy(ioutil.Discard, ioutil.NopCloser(r))
   534  		if err != nil {
   535  			b.Fatal(err)
   536  		}
   537  	}
   538  }
   539  
   540  func BenchmarkGunzipStdlib(b *testing.B) {
   541  	dat, _ := ioutil.ReadFile("testdata/test.json")
   542  	dat = append(dat, dat...)
   543  	dat = append(dat, dat...)
   544  	dat = append(dat, dat...)
   545  	dat = append(dat, dat...)
   546  	dat = append(dat, dat...)
   547  	dst := &bytes.Buffer{}
   548  	w, _ := NewWriterLevel(dst, 1)
   549  	_, err := w.Write(dat)
   550  	if err != nil {
   551  		b.Fatal(err)
   552  	}
   553  	w.Close()
   554  	input := dst.Bytes()
   555  	r, err := oldgz.NewReader(bytes.NewBuffer(input))
   556  	if err != nil {
   557  		b.Fatal(err)
   558  	}
   559  	b.SetBytes(int64(len(dat)))
   560  	b.ResetTimer()
   561  	for n := 0; n < b.N; n++ {
   562  		err := r.Reset(bytes.NewBuffer(input))
   563  		if err != nil {
   564  			b.Fatal(err)
   565  		}
   566  		_, err = io.Copy(ioutil.Discard, r)
   567  		if err != nil {
   568  			b.Fatal(err)
   569  		}
   570  	}
   571  }