OSDN Git Service

5829d03faa63072e7c5a638796b33aed957bc213
[pf3gnuchains/gcc-fork.git] / libgo / go / archive / tar / reader_test.go
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 tar
6
7 import (
8         "bytes"
9         "crypto/md5"
10         "fmt"
11         "io"
12         "os"
13         "reflect"
14         "testing"
15         "time"
16 )
17
18 type untarTest struct {
19         file    string
20         headers []*Header
21         cksums  []string
22 }
23
24 var gnuTarTest = &untarTest{
25         file: "testdata/gnu.tar",
26         headers: []*Header{
27                 {
28                         Name:     "small.txt",
29                         Mode:     0640,
30                         Uid:      73025,
31                         Gid:      5000,
32                         Size:     5,
33                         ModTime:  time.Unix(1244428340, 0),
34                         Typeflag: '0',
35                         Uname:    "dsymonds",
36                         Gname:    "eng",
37                 },
38                 {
39                         Name:     "small2.txt",
40                         Mode:     0640,
41                         Uid:      73025,
42                         Gid:      5000,
43                         Size:     11,
44                         ModTime:  time.Unix(1244436044, 0),
45                         Typeflag: '0',
46                         Uname:    "dsymonds",
47                         Gname:    "eng",
48                 },
49         },
50         cksums: []string{
51                 "e38b27eaccb4391bdec553a7f3ae6b2f",
52                 "c65bd2e50a56a2138bf1716f2fd56fe9",
53         },
54 }
55
56 var untarTests = []*untarTest{
57         gnuTarTest,
58         {
59                 file: "testdata/star.tar",
60                 headers: []*Header{
61                         {
62                                 Name:       "small.txt",
63                                 Mode:       0640,
64                                 Uid:        73025,
65                                 Gid:        5000,
66                                 Size:       5,
67                                 ModTime:    time.Unix(1244592783, 0),
68                                 Typeflag:   '0',
69                                 Uname:      "dsymonds",
70                                 Gname:      "eng",
71                                 AccessTime: time.Unix(1244592783, 0),
72                                 ChangeTime: time.Unix(1244592783, 0),
73                         },
74                         {
75                                 Name:       "small2.txt",
76                                 Mode:       0640,
77                                 Uid:        73025,
78                                 Gid:        5000,
79                                 Size:       11,
80                                 ModTime:    time.Unix(1244592783, 0),
81                                 Typeflag:   '0',
82                                 Uname:      "dsymonds",
83                                 Gname:      "eng",
84                                 AccessTime: time.Unix(1244592783, 0),
85                                 ChangeTime: time.Unix(1244592783, 0),
86                         },
87                 },
88         },
89         {
90                 file: "testdata/v7.tar",
91                 headers: []*Header{
92                         {
93                                 Name:     "small.txt",
94                                 Mode:     0444,
95                                 Uid:      73025,
96                                 Gid:      5000,
97                                 Size:     5,
98                                 ModTime:  time.Unix(1244593104, 0),
99                                 Typeflag: '\x00',
100                         },
101                         {
102                                 Name:     "small2.txt",
103                                 Mode:     0444,
104                                 Uid:      73025,
105                                 Gid:      5000,
106                                 Size:     11,
107                                 ModTime:  time.Unix(1244593104, 0),
108                                 Typeflag: '\x00',
109                         },
110                 },
111         },
112 }
113
114 func TestReader(t *testing.T) {
115 testLoop:
116         for i, test := range untarTests {
117                 f, err := os.Open(test.file)
118                 if err != nil {
119                         t.Errorf("test %d: Unexpected error: %v", i, err)
120                         continue
121                 }
122                 tr := NewReader(f)
123                 for j, header := range test.headers {
124                         hdr, err := tr.Next()
125                         if err != nil || hdr == nil {
126                                 t.Errorf("test %d, entry %d: Didn't get entry: %v", i, j, err)
127                                 f.Close()
128                                 continue testLoop
129                         }
130                         if !reflect.DeepEqual(hdr, header) {
131                                 t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v",
132                                         i, j, *hdr, *header)
133                         }
134                 }
135                 hdr, err := tr.Next()
136                 if err == io.EOF {
137                         break
138                 }
139                 if hdr != nil || err != nil {
140                         t.Errorf("test %d: Unexpected entry or error: hdr=%v err=%v", i, hdr, err)
141                 }
142                 f.Close()
143         }
144 }
145
146 func TestPartialRead(t *testing.T) {
147         f, err := os.Open("testdata/gnu.tar")
148         if err != nil {
149                 t.Fatalf("Unexpected error: %v", err)
150         }
151         defer f.Close()
152
153         tr := NewReader(f)
154
155         // Read the first four bytes; Next() should skip the last byte.
156         hdr, err := tr.Next()
157         if err != nil || hdr == nil {
158                 t.Fatalf("Didn't get first file: %v", err)
159         }
160         buf := make([]byte, 4)
161         if _, err := io.ReadFull(tr, buf); err != nil {
162                 t.Fatalf("Unexpected error: %v", err)
163         }
164         if expected := []byte("Kilt"); !bytes.Equal(buf, expected) {
165                 t.Errorf("Contents = %v, want %v", buf, expected)
166         }
167
168         // Second file
169         hdr, err = tr.Next()
170         if err != nil || hdr == nil {
171                 t.Fatalf("Didn't get second file: %v", err)
172         }
173         buf = make([]byte, 6)
174         if _, err := io.ReadFull(tr, buf); err != nil {
175                 t.Fatalf("Unexpected error: %v", err)
176         }
177         if expected := []byte("Google"); !bytes.Equal(buf, expected) {
178                 t.Errorf("Contents = %v, want %v", buf, expected)
179         }
180 }
181
182 func TestIncrementalRead(t *testing.T) {
183         test := gnuTarTest
184         f, err := os.Open(test.file)
185         if err != nil {
186                 t.Fatalf("Unexpected error: %v", err)
187         }
188         defer f.Close()
189
190         tr := NewReader(f)
191
192         headers := test.headers
193         cksums := test.cksums
194         nread := 0
195
196         // loop over all files
197         for ; ; nread++ {
198                 hdr, err := tr.Next()
199                 if hdr == nil || err == io.EOF {
200                         break
201                 }
202
203                 // check the header
204                 if !reflect.DeepEqual(hdr, headers[nread]) {
205                         t.Errorf("Incorrect header:\nhave %+v\nwant %+v",
206                                 *hdr, headers[nread])
207                 }
208
209                 // read file contents in little chunks EOF,
210                 // checksumming all the way
211                 h := md5.New()
212                 rdbuf := make([]uint8, 8)
213                 for {
214                         nr, err := tr.Read(rdbuf)
215                         if err == io.EOF {
216                                 break
217                         }
218                         if err != nil {
219                                 t.Errorf("Read: unexpected error %v\n", err)
220                                 break
221                         }
222                         h.Write(rdbuf[0:nr])
223                 }
224                 // verify checksum
225                 have := fmt.Sprintf("%x", h.Sum(nil))
226                 want := cksums[nread]
227                 if want != have {
228                         t.Errorf("Bad checksum on file %s:\nhave %+v\nwant %+v", hdr.Name, have, want)
229                 }
230         }
231         if nread != len(headers) {
232                 t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(headers), nread)
233         }
234 }
235
236 func TestNonSeekable(t *testing.T) {
237         test := gnuTarTest
238         f, err := os.Open(test.file)
239         if err != nil {
240                 t.Fatalf("Unexpected error: %v", err)
241         }
242         defer f.Close()
243
244         // pipe the data in
245         r, w, err := os.Pipe()
246         if err != nil {
247                 t.Fatalf("Unexpected error %s", err)
248         }
249         go func() {
250                 rdbuf := make([]uint8, 1<<16)
251                 for {
252                         nr, err := f.Read(rdbuf)
253                         w.Write(rdbuf[0:nr])
254                         if err == io.EOF {
255                                 break
256                         }
257                 }
258                 w.Close()
259         }()
260
261         tr := NewReader(r)
262         nread := 0
263
264         for ; ; nread++ {
265                 hdr, err := tr.Next()
266                 if hdr == nil || err == io.EOF {
267                         break
268                 }
269         }
270
271         if nread != len(test.headers) {
272                 t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(test.headers), nread)
273         }
274 }