github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/src/compress/gzip/gzip_test.go (about) 1 // Copyright 2010 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 "bufio" 9 "bytes" 10 "io/ioutil" 11 "reflect" 12 "testing" 13 "time" 14 ) 15 16 // TestEmpty tests that an empty payload still forms a valid GZIP stream. 17 func TestEmpty(t *testing.T) { 18 buf := new(bytes.Buffer) 19 20 if err := NewWriter(buf).Close(); err != nil { 21 t.Fatalf("Writer.Close: %v", err) 22 } 23 24 r, err := NewReader(buf) 25 if err != nil { 26 t.Fatalf("NewReader: %v", err) 27 } 28 if want := (Header{OS: 255}); !reflect.DeepEqual(r.Header, want) { 29 t.Errorf("Header mismatch:\ngot %#v\nwant %#v", r.Header, want) 30 } 31 b, err := ioutil.ReadAll(r) 32 if err != nil { 33 t.Fatalf("ReadAll: %v", err) 34 } 35 if len(b) != 0 { 36 t.Fatalf("got %d bytes, want 0", len(b)) 37 } 38 if err := r.Close(); err != nil { 39 t.Fatalf("Reader.Close: %v", err) 40 } 41 } 42 43 // TestRoundTrip tests that gzipping and then gunzipping is the identity 44 // function. 45 func TestRoundTrip(t *testing.T) { 46 buf := new(bytes.Buffer) 47 48 w := NewWriter(buf) 49 w.Comment = "comment" 50 w.Extra = []byte("extra") 51 w.ModTime = time.Unix(1e8, 0) 52 w.Name = "name" 53 if _, err := w.Write([]byte("payload")); err != nil { 54 t.Fatalf("Write: %v", err) 55 } 56 if err := w.Close(); err != nil { 57 t.Fatalf("Writer.Close: %v", err) 58 } 59 60 r, err := NewReader(buf) 61 if err != nil { 62 t.Fatalf("NewReader: %v", err) 63 } 64 b, err := ioutil.ReadAll(r) 65 if err != nil { 66 t.Fatalf("ReadAll: %v", err) 67 } 68 if string(b) != "payload" { 69 t.Fatalf("payload is %q, want %q", string(b), "payload") 70 } 71 if r.Comment != "comment" { 72 t.Fatalf("comment is %q, want %q", r.Comment, "comment") 73 } 74 if string(r.Extra) != "extra" { 75 t.Fatalf("extra is %q, want %q", r.Extra, "extra") 76 } 77 if r.ModTime.Unix() != 1e8 { 78 t.Fatalf("mtime is %d, want %d", r.ModTime.Unix(), uint32(1e8)) 79 } 80 if r.Name != "name" { 81 t.Fatalf("name is %q, want %q", r.Name, "name") 82 } 83 if err := r.Close(); err != nil { 84 t.Fatalf("Reader.Close: %v", err) 85 } 86 } 87 88 // TestLatin1 tests the internal functions for converting to and from Latin-1. 89 func TestLatin1(t *testing.T) { 90 latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0} 91 utf8 := "Äußerung" 92 z := Reader{r: bufio.NewReader(bytes.NewReader(latin1))} 93 s, err := z.readString() 94 if err != nil { 95 t.Fatalf("readString: %v", err) 96 } 97 if s != utf8 { 98 t.Fatalf("read latin-1: got %q, want %q", s, utf8) 99 } 100 101 buf := bytes.NewBuffer(make([]byte, 0, len(latin1))) 102 c := Writer{w: buf} 103 if err = c.writeString(utf8); err != nil { 104 t.Fatalf("writeString: %v", err) 105 } 106 s = buf.String() 107 if s != string(latin1) { 108 t.Fatalf("write utf-8: got %q, want %q", s, string(latin1)) 109 } 110 } 111 112 // TestLatin1RoundTrip tests that metadata that is representable in Latin-1 113 // survives a round trip. 114 func TestLatin1RoundTrip(t *testing.T) { 115 testCases := []struct { 116 name string 117 ok bool 118 }{ 119 {"", true}, 120 {"ASCII is OK", true}, 121 {"unless it contains a NUL\x00", false}, 122 {"no matter where \x00 occurs", false}, 123 {"\x00\x00\x00", false}, 124 {"Látin-1 also passes (U+00E1)", true}, 125 {"but LĀtin Extended-A (U+0100) does not", false}, 126 {"neither does 日本語", false}, 127 {"invalid UTF-8 also \xffails", false}, 128 {"\x00 as does Látin-1 with NUL", false}, 129 } 130 for _, tc := range testCases { 131 buf := new(bytes.Buffer) 132 133 w := NewWriter(buf) 134 w.Name = tc.name 135 err := w.Close() 136 if (err == nil) != tc.ok { 137 t.Errorf("Writer.Close: name = %q, err = %v", tc.name, err) 138 continue 139 } 140 if !tc.ok { 141 continue 142 } 143 144 r, err := NewReader(buf) 145 if err != nil { 146 t.Errorf("NewReader: %v", err) 147 continue 148 } 149 _, err = ioutil.ReadAll(r) 150 if err != nil { 151 t.Errorf("ReadAll: %v", err) 152 continue 153 } 154 if r.Name != tc.name { 155 t.Errorf("name is %q, want %q", r.Name, tc.name) 156 continue 157 } 158 if err := r.Close(); err != nil { 159 t.Errorf("Reader.Close: %v", err) 160 continue 161 } 162 } 163 } 164 165 func TestWriterFlush(t *testing.T) { 166 buf := new(bytes.Buffer) 167 168 w := NewWriter(buf) 169 w.Comment = "comment" 170 w.Extra = []byte("extra") 171 w.ModTime = time.Unix(1e8, 0) 172 w.Name = "name" 173 174 n0 := buf.Len() 175 if n0 != 0 { 176 t.Fatalf("buffer size = %d before writes; want 0", n0) 177 } 178 179 if err := w.Flush(); err != nil { 180 t.Fatal(err) 181 } 182 183 n1 := buf.Len() 184 if n1 == 0 { 185 t.Fatal("no data after first flush") 186 } 187 188 w.Write([]byte("x")) 189 190 n2 := buf.Len() 191 if n1 != n2 { 192 t.Fatalf("after writing a single byte, size changed from %d to %d; want no change", n1, n2) 193 } 194 195 if err := w.Flush(); err != nil { 196 t.Fatal(err) 197 } 198 199 n3 := buf.Len() 200 if n2 == n3 { 201 t.Fatal("Flush didn't flush any data") 202 } 203 } 204 205 // Multiple gzip files concatenated form a valid gzip file. 206 func TestConcat(t *testing.T) { 207 var buf bytes.Buffer 208 w := NewWriter(&buf) 209 w.Write([]byte("hello ")) 210 w.Close() 211 w = NewWriter(&buf) 212 w.Write([]byte("world\n")) 213 w.Close() 214 215 r, err := NewReader(&buf) 216 data, err := ioutil.ReadAll(r) 217 if string(data) != "hello world\n" || err != nil { 218 t.Fatalf("ReadAll = %q, %v, want %q, nil", data, err, "hello world") 219 } 220 } 221 222 func TestWriterReset(t *testing.T) { 223 buf := new(bytes.Buffer) 224 buf2 := new(bytes.Buffer) 225 z := NewWriter(buf) 226 msg := []byte("hello world") 227 z.Write(msg) 228 z.Close() 229 z.Reset(buf2) 230 z.Write(msg) 231 z.Close() 232 if buf.String() != buf2.String() { 233 t.Errorf("buf2 %q != original buf of %q", buf2.String(), buf.String()) 234 } 235 }