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