github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 "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 := io.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 := io.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 = io.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 if err := w.Close(); err != nil { 205 t.Fatal(err) 206 } 207 208 } 209 210 // Multiple gzip files concatenated form a valid gzip file. 211 func TestConcat(t *testing.T) { 212 var buf bytes.Buffer 213 w := NewWriter(&buf) 214 w.Write([]byte("hello ")) 215 w.Close() 216 w = NewWriter(&buf) 217 w.Write([]byte("world\n")) 218 w.Close() 219 220 r, err := NewReader(&buf) 221 if err != nil { 222 t.Fatal(err) 223 } 224 data, err := io.ReadAll(r) 225 if string(data) != "hello world\n" || err != nil { 226 t.Fatalf("ReadAll = %q, %v, want %q, nil", data, err, "hello world") 227 } 228 } 229 230 func TestWriterReset(t *testing.T) { 231 buf := new(bytes.Buffer) 232 buf2 := new(bytes.Buffer) 233 z := NewWriter(buf) 234 msg := []byte("hello world") 235 z.Write(msg) 236 z.Close() 237 z.Reset(buf2) 238 z.Write(msg) 239 z.Close() 240 if buf.String() != buf2.String() { 241 t.Errorf("buf2 %q != original buf of %q", buf2.String(), buf.String()) 242 } 243 } 244 245 type limitedWriter struct { 246 N int 247 } 248 249 func (l *limitedWriter) Write(p []byte) (n int, err error) { 250 if n := l.N; n < len(p) { 251 l.N = 0 252 return n, io.ErrShortWrite 253 } 254 l.N -= len(p) 255 return len(p), nil 256 } 257 258 // Write should never return more bytes than the input slice. 259 func TestLimitedWrite(t *testing.T) { 260 msg := []byte("a") 261 262 for lim := 2; lim < 20; lim++ { 263 z := NewWriter(&limitedWriter{lim}) 264 if n, _ := z.Write(msg); n > len(msg) { 265 t.Errorf("Write() = %d, want %d or less", n, len(msg)) 266 } 267 268 z.Reset(&limitedWriter{lim}) 269 z.Header = Header{ 270 Comment: "comment", 271 Extra: []byte("extra"), 272 ModTime: time.Now(), 273 Name: "name", 274 OS: 1, 275 } 276 if n, _ := z.Write(msg); n > len(msg) { 277 t.Errorf("Write() = %d, want %d or less", n, len(msg)) 278 } 279 } 280 }