Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / archive / tar / reader_test.go
blobcfc25850776fbb825cfd239a4189c2b13f04917d
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.
5 package tar
7 import (
8 "bytes"
9 "crypto/md5"
10 "fmt"
11 "io"
12 "os"
13 "reflect"
14 "testing"
17 type untarTest struct {
18 file string
19 headers []*Header
20 cksums []string
23 var gnuTarTest = &untarTest{
24 file: "testdata/gnu.tar",
25 headers: []*Header{
26 &Header{
27 Name: "small.txt",
28 Mode: 0640,
29 Uid: 73025,
30 Gid: 5000,
31 Size: 5,
32 Mtime: 1244428340,
33 Typeflag: '0',
34 Uname: "dsymonds",
35 Gname: "eng",
37 &Header{
38 Name: "small2.txt",
39 Mode: 0640,
40 Uid: 73025,
41 Gid: 5000,
42 Size: 11,
43 Mtime: 1244436044,
44 Typeflag: '0',
45 Uname: "dsymonds",
46 Gname: "eng",
49 cksums: []string{
50 "e38b27eaccb4391bdec553a7f3ae6b2f",
51 "c65bd2e50a56a2138bf1716f2fd56fe9",
55 var untarTests = []*untarTest{
56 gnuTarTest,
57 &untarTest{
58 file: "testdata/star.tar",
59 headers: []*Header{
60 &Header{
61 Name: "small.txt",
62 Mode: 0640,
63 Uid: 73025,
64 Gid: 5000,
65 Size: 5,
66 Mtime: 1244592783,
67 Typeflag: '0',
68 Uname: "dsymonds",
69 Gname: "eng",
70 Atime: 1244592783,
71 Ctime: 1244592783,
73 &Header{
74 Name: "small2.txt",
75 Mode: 0640,
76 Uid: 73025,
77 Gid: 5000,
78 Size: 11,
79 Mtime: 1244592783,
80 Typeflag: '0',
81 Uname: "dsymonds",
82 Gname: "eng",
83 Atime: 1244592783,
84 Ctime: 1244592783,
88 &untarTest{
89 file: "testdata/v7.tar",
90 headers: []*Header{
91 &Header{
92 Name: "small.txt",
93 Mode: 0444,
94 Uid: 73025,
95 Gid: 5000,
96 Size: 5,
97 Mtime: 1244593104,
98 Typeflag: '\x00',
100 &Header{
101 Name: "small2.txt",
102 Mode: 0444,
103 Uid: 73025,
104 Gid: 5000,
105 Size: 11,
106 Mtime: 1244593104,
107 Typeflag: '\x00',
113 func TestReader(t *testing.T) {
114 testLoop:
115 for i, test := range untarTests {
116 f, err := os.Open(test.file, os.O_RDONLY, 0444)
117 if err != nil {
118 t.Errorf("test %d: Unexpected error: %v", i, err)
119 continue
121 tr := NewReader(f)
122 for j, header := range test.headers {
123 hdr, err := tr.Next()
124 if err != nil || hdr == nil {
125 t.Errorf("test %d, entry %d: Didn't get entry: %v", i, j, err)
126 f.Close()
127 continue testLoop
129 if !reflect.DeepEqual(hdr, header) {
130 t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v",
131 i, j, *hdr, *header)
134 hdr, err := tr.Next()
135 if err == os.EOF {
136 break
138 if hdr != nil || err != nil {
139 t.Errorf("test %d: Unexpected entry or error: hdr=%v err=%v", i, err)
141 f.Close()
145 func TestPartialRead(t *testing.T) {
146 f, err := os.Open("testdata/gnu.tar", os.O_RDONLY, 0444)
147 if err != nil {
148 t.Fatalf("Unexpected error: %v", err)
150 defer f.Close()
152 tr := NewReader(f)
154 // Read the first four bytes; Next() should skip the last byte.
155 hdr, err := tr.Next()
156 if err != nil || hdr == nil {
157 t.Fatalf("Didn't get first file: %v", err)
159 buf := make([]byte, 4)
160 if _, err := io.ReadFull(tr, buf); err != nil {
161 t.Fatalf("Unexpected error: %v", err)
163 if expected := []byte("Kilt"); !bytes.Equal(buf, expected) {
164 t.Errorf("Contents = %v, want %v", buf, expected)
167 // Second file
168 hdr, err = tr.Next()
169 if err != nil || hdr == nil {
170 t.Fatalf("Didn't get second file: %v", err)
172 buf = make([]byte, 6)
173 if _, err := io.ReadFull(tr, buf); err != nil {
174 t.Fatalf("Unexpected error: %v", err)
176 if expected := []byte("Google"); !bytes.Equal(buf, expected) {
177 t.Errorf("Contents = %v, want %v", buf, expected)
182 func TestIncrementalRead(t *testing.T) {
183 test := gnuTarTest
184 f, err := os.Open(test.file, os.O_RDONLY, 0444)
185 if err != nil {
186 t.Fatalf("Unexpected error: %v", err)
188 defer f.Close()
190 tr := NewReader(f)
192 headers := test.headers
193 cksums := test.cksums
194 nread := 0
196 // loop over all files
197 for ; ; nread++ {
198 hdr, err := tr.Next()
199 if hdr == nil || err == os.EOF {
200 break
203 // check the header
204 if !reflect.DeepEqual(hdr, headers[nread]) {
205 t.Errorf("Incorrect header:\nhave %+v\nwant %+v",
206 *hdr, headers[nread])
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 == os.EOF {
216 break
218 if err != nil {
219 t.Errorf("Read: unexpected error %v\n", err)
220 break
222 h.Write(rdbuf[0:nr])
224 // verify checksum
225 have := fmt.Sprintf("%x", h.Sum())
226 want := cksums[nread]
227 if want != have {
228 t.Errorf("Bad checksum on file %s:\nhave %+v\nwant %+v", hdr.Name, have, want)
231 if nread != len(headers) {
232 t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(headers), nread)
236 func TestNonSeekable(t *testing.T) {
237 test := gnuTarTest
238 f, err := os.Open(test.file, os.O_RDONLY, 0444)
239 if err != nil {
240 t.Fatalf("Unexpected error: %v", err)
242 defer f.Close()
244 // pipe the data in
245 r, w, err := os.Pipe()
246 if err != nil {
247 t.Fatalf("Unexpected error %s", err)
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 == os.EOF {
255 break
258 w.Close()
261 tr := NewReader(r)
262 nread := 0
264 for ; ; nread++ {
265 hdr, err := tr.Next()
266 if hdr == nil || err == os.EOF {
267 break
271 if nread != len(test.headers) {
272 t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(test.headers), nread)