]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/archive/tar/writer_test.go
Add Go frontend, libgo library, and Go testsuite.
[thirdparty/gcc.git] / libgo / go / archive / tar / writer_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 "fmt"
10 "io"
11 "io/ioutil"
12 "testing"
13 "testing/iotest"
14 )
15
16 type writerTestEntry struct {
17 header *Header
18 contents string
19 }
20
21 type writerTest struct {
22 file string // filename of expected output
23 entries []*writerTestEntry
24 }
25
26 var writerTests = []*writerTest{
27 &writerTest{
28 file: "testdata/writer.tar",
29 entries: []*writerTestEntry{
30 &writerTestEntry{
31 header: &Header{
32 Name: "small.txt",
33 Mode: 0640,
34 Uid: 73025,
35 Gid: 5000,
36 Size: 5,
37 Mtime: 1246508266,
38 Typeflag: '0',
39 Uname: "dsymonds",
40 Gname: "eng",
41 },
42 contents: "Kilts",
43 },
44 &writerTestEntry{
45 header: &Header{
46 Name: "small2.txt",
47 Mode: 0640,
48 Uid: 73025,
49 Gid: 5000,
50 Size: 11,
51 Mtime: 1245217492,
52 Typeflag: '0',
53 Uname: "dsymonds",
54 Gname: "eng",
55 },
56 contents: "Google.com\n",
57 },
58 },
59 },
60 // The truncated test file was produced using these commands:
61 // dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt
62 // tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar
63 &writerTest{
64 file: "testdata/writer-big.tar",
65 entries: []*writerTestEntry{
66 &writerTestEntry{
67 header: &Header{
68 Name: "tmp/16gig.txt",
69 Mode: 0640,
70 Uid: 73025,
71 Gid: 5000,
72 Size: 16 << 30,
73 Mtime: 1254699560,
74 Typeflag: '0',
75 Uname: "dsymonds",
76 Gname: "eng",
77 },
78 // no contents
79 },
80 },
81 },
82 }
83
84 // Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
85 func bytestr(offset int, b []byte) string {
86 const rowLen = 32
87 s := fmt.Sprintf("%04x ", offset)
88 for _, ch := range b {
89 switch {
90 case '0' <= ch && ch <= '9', 'A' <= ch && ch <= 'Z', 'a' <= ch && ch <= 'z':
91 s += fmt.Sprintf(" %c", ch)
92 default:
93 s += fmt.Sprintf(" %02x", ch)
94 }
95 }
96 return s
97 }
98
99 // Render a pseudo-diff between two blocks of bytes.
100 func bytediff(a []byte, b []byte) string {
101 const rowLen = 32
102 s := fmt.Sprintf("(%d bytes vs. %d bytes)\n", len(a), len(b))
103 for offset := 0; len(a)+len(b) > 0; offset += rowLen {
104 na, nb := rowLen, rowLen
105 if na > len(a) {
106 na = len(a)
107 }
108 if nb > len(b) {
109 nb = len(b)
110 }
111 sa := bytestr(offset, a[0:na])
112 sb := bytestr(offset, b[0:nb])
113 if sa != sb {
114 s += fmt.Sprintf("-%v\n+%v\n", sa, sb)
115 }
116 a = a[na:]
117 b = b[nb:]
118 }
119 return s
120 }
121
122 func TestWriter(t *testing.T) {
123 testLoop:
124 for i, test := range writerTests {
125 expected, err := ioutil.ReadFile(test.file)
126 if err != nil {
127 t.Errorf("test %d: Unexpected error: %v", i, err)
128 continue
129 }
130
131 buf := new(bytes.Buffer)
132 tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
133 for j, entry := range test.entries {
134 if err := tw.WriteHeader(entry.header); err != nil {
135 t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
136 continue testLoop
137 }
138 if _, err := io.WriteString(tw, entry.contents); err != nil {
139 t.Errorf("test %d, entry %d: Failed writing contents: %v", i, j, err)
140 continue testLoop
141 }
142 }
143 if err := tw.Close(); err != nil {
144 t.Errorf("test %d: Failed closing archive: %v", err)
145 continue testLoop
146 }
147
148 actual := buf.Bytes()
149 if !bytes.Equal(expected, actual) {
150 t.Errorf("test %d: Incorrect result: (-=expected, +=actual)\n%v",
151 i, bytediff(expected, actual))
152 }
153 }
154 }