LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package tar | 5 package tar |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "crypto/md5" | 9 "crypto/md5" |
10 "fmt" | 10 "fmt" |
11 "io" | 11 "io" |
12 "os" | 12 "os" |
| 13 "reflect" |
| 14 "strings" |
13 "testing" | 15 "testing" |
14 "time" | 16 "time" |
15 ) | 17 ) |
16 | 18 |
17 type untarTest struct { | 19 type untarTest struct { |
18 file string | 20 file string |
19 headers []*Header | 21 headers []*Header |
20 cksums []string | 22 cksums []string |
21 } | 23 } |
22 | 24 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 Name: "small2.txt", | 103 Name: "small2.txt", |
102 Mode: 0444, | 104 Mode: 0444, |
103 Uid: 73025, | 105 Uid: 73025, |
104 Gid: 5000, | 106 Gid: 5000, |
105 Size: 11, | 107 Size: 11, |
106 ModTime: time.Unix(1244593104, 0), | 108 ModTime: time.Unix(1244593104, 0), |
107 Typeflag: '\x00', | 109 Typeflag: '\x00', |
108 }, | 110 }, |
109 }, | 111 }, |
110 }, | 112 }, |
| 113 { |
| 114 file: "testdata/pax.tar", |
| 115 headers: []*Header{ |
| 116 { |
| 117 Name: "a/123456789101112131415161718192021
22232425262728293031323334353637383940414243444546474849505152535455565758596061
6263646566676869707172737475767778798081828384858687888990919293949596979899100"
, |
| 118 Mode: 0664, |
| 119 Uid: 1000, |
| 120 Gid: 1000, |
| 121 Uname: "shane", |
| 122 Gname: "shane", |
| 123 Size: 7, |
| 124 ModTime: time.Unix(1350244992, 23960108), |
| 125 ChangeTime: time.Unix(1350244992, 23960108), |
| 126 AccessTime: time.Unix(1350244992, 23960108), |
| 127 Typeflag: TypeReg, |
| 128 }, |
| 129 { |
| 130 Name: "a/b", |
| 131 Mode: 0777, |
| 132 Uid: 1000, |
| 133 Gid: 1000, |
| 134 Uname: "shane", |
| 135 Gname: "shane", |
| 136 Size: 0, |
| 137 ModTime: time.Unix(1350266320, 910238425), |
| 138 ChangeTime: time.Unix(1350266320, 910238425), |
| 139 AccessTime: time.Unix(1350266320, 910238425), |
| 140 Typeflag: TypeSymlink, |
| 141 Linkname: "12345678910111213141516171819202122
23242526272829303132333435363738394041424344454647484950515253545556575859606162
63646566676869707172737475767778798081828384858687888990919293949596979899100", |
| 142 }, |
| 143 }, |
| 144 }, |
111 } | 145 } |
112 | 146 |
113 func TestReader(t *testing.T) { | 147 func TestReader(t *testing.T) { |
114 testLoop: | 148 testLoop: |
115 for i, test := range untarTests { | 149 for i, test := range untarTests { |
116 f, err := os.Open(test.file) | 150 f, err := os.Open(test.file) |
117 if err != nil { | 151 if err != nil { |
118 t.Errorf("test %d: Unexpected error: %v", i, err) | 152 t.Errorf("test %d: Unexpected error: %v", i, err) |
119 continue | 153 continue |
120 } | 154 } |
121 tr := NewReader(f) | 155 tr := NewReader(f) |
122 for j, header := range test.headers { | 156 for j, header := range test.headers { |
123 hdr, err := tr.Next() | 157 hdr, err := tr.Next() |
124 if err != nil || hdr == nil { | 158 if err != nil || hdr == nil { |
125 t.Errorf("test %d, entry %d: Didn't get entry: %
v", i, j, err) | 159 t.Errorf("test %d, entry %d: Didn't get entry: %
v", i, j, err) |
126 f.Close() | 160 f.Close() |
127 continue testLoop | 161 continue testLoop |
128 } | 162 } |
129 if *hdr != *header { | 163 if *hdr != *header { |
130 t.Errorf("test %d, entry %d: Incorrect header:\n
have %+v\nwant %+v", | 164 t.Errorf("test %d, entry %d: Incorrect header:\n
have %+v\nwant %+v", |
131 i, j, *hdr, *header) | 165 i, j, *hdr, *header) |
132 } | 166 } |
133 } | 167 } |
134 hdr, err := tr.Next() | 168 hdr, err := tr.Next() |
135 if err == io.EOF { | 169 if err == io.EOF { |
136 » » » break | 170 » » » continue testLoop |
137 } | 171 } |
138 if hdr != nil || err != nil { | 172 if hdr != nil || err != nil { |
139 t.Errorf("test %d: Unexpected entry or error: hdr=%v err
=%v", i, hdr, err) | 173 t.Errorf("test %d: Unexpected entry or error: hdr=%v err
=%v", i, hdr, err) |
140 } | 174 } |
141 f.Close() | 175 f.Close() |
142 } | 176 } |
143 } | 177 } |
144 | 178 |
145 func TestPartialRead(t *testing.T) { | 179 func TestPartialRead(t *testing.T) { |
146 f, err := os.Open("testdata/gnu.tar") | 180 f, err := os.Open("testdata/gnu.tar") |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 } | 287 } |
254 if err != nil { | 288 if err != nil { |
255 t.Fatalf("Unexpected error: %v", err) | 289 t.Fatalf("Unexpected error: %v", err) |
256 } | 290 } |
257 } | 291 } |
258 | 292 |
259 if nread != len(test.headers) { | 293 if nread != len(test.headers) { |
260 t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n
", len(test.headers), nread) | 294 t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n
", len(test.headers), nread) |
261 } | 295 } |
262 } | 296 } |
| 297 |
| 298 func TestParsePAXHeader(t *testing.T) { |
| 299 correctHeaders := []byte("30 mtime=1350244992.023960108\n") |
| 300 reader := bytes.NewBuffer(correctHeaders) |
| 301 headers, err := parsePAX(reader) |
| 302 if err != nil { |
| 303 t.Fatalf("Couldn't parse correctly formatted headers %s", err) |
| 304 } |
| 305 if strings.EqualFold(headers["mtime"], "mtime=1350244992.023960108") { |
| 306 t.Fatalf("mtime header incorrectly parsed") |
| 307 } |
| 308 trailer := make([]byte, 100) |
| 309 n, err := reader.Read(trailer) |
| 310 if err != io.EOF || n != 0 { |
| 311 t.Fatal("Buffer wasn't consumed") |
| 312 } |
| 313 badHeader := bytes.NewBuffer([]byte("3 somelongkey=")) |
| 314 if _, err := parsePAX(badHeader); err != ErrHeader { |
| 315 t.Fatal("Unexpected success when parsing bad header") |
| 316 } |
| 317 } |
| 318 |
| 319 func TestParsePAXTime(t *testing.T) { |
| 320 // Some valid PAX time values |
| 321 timestamps := map[string]time.Time{ |
| 322 "1350244992.023960108": time.Unix(1350244992, 23960108), // The
commoon case |
| 323 "1350244992.02396010": time.Unix(1350244992, 23960100), // Low
er precision value |
| 324 "1350244992.0239601089": time.Unix(1350244992, 23960108), // Hig
her precision value |
| 325 "1350244992": time.Unix(1350244992, 0), // Low
precision value |
| 326 } |
| 327 for input, expected := range timestamps { |
| 328 ts, err := parsePAXTime(input) |
| 329 if err != nil { |
| 330 t.Fatal(err) |
| 331 } |
| 332 if !ts.Equal(expected) { |
| 333 t.Fatalf("Time parsing failure %s %s", ts, expected) |
| 334 } |
| 335 } |
| 336 } |
| 337 |
| 338 func TestMergePAX(t *testing.T) { |
| 339 hdr := new(Header) |
| 340 // Test a string, integer, and time based value. |
| 341 headers := map[string]string{ |
| 342 "path": "a/b/c", |
| 343 "uid": "1000", |
| 344 "mtime": "1350244992.023960108", |
| 345 } |
| 346 err := mergePAX(hdr, headers) |
| 347 if err != nil { |
| 348 t.Fatal(err) |
| 349 } |
| 350 want := &Header{ |
| 351 Name: "a/b/c", |
| 352 Uid: 1000, |
| 353 ModTime: time.Unix(1350244992, 23960108), |
| 354 } |
| 355 if !reflect.DeepEqual(hdr, want) { |
| 356 t.Errorf("incorrect merge: got %+v, want %+v", hdr, want) |
| 357 } |
| 358 } |
LEFT | RIGHT |