libgo: update to go1.9
[official-gcc.git] / libgo / go / archive / tar / tar_test.go
blobfb7a9dcfc47451f43b26c964741993fc8775df73
1 // Copyright 2012 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 "internal/testenv"
10 "io/ioutil"
11 "os"
12 "path"
13 "path/filepath"
14 "reflect"
15 "strings"
16 "testing"
17 "time"
20 func TestFileInfoHeader(t *testing.T) {
21 fi, err := os.Stat("testdata/small.txt")
22 if err != nil {
23 t.Fatal(err)
25 h, err := FileInfoHeader(fi, "")
26 if err != nil {
27 t.Fatalf("FileInfoHeader: %v", err)
29 if g, e := h.Name, "small.txt"; g != e {
30 t.Errorf("Name = %q; want %q", g, e)
32 if g, e := h.Mode, int64(fi.Mode().Perm()); g != e {
33 t.Errorf("Mode = %#o; want %#o", g, e)
35 if g, e := h.Size, int64(5); g != e {
36 t.Errorf("Size = %v; want %v", g, e)
38 if g, e := h.ModTime, fi.ModTime(); !g.Equal(e) {
39 t.Errorf("ModTime = %v; want %v", g, e)
41 // FileInfoHeader should error when passing nil FileInfo
42 if _, err := FileInfoHeader(nil, ""); err == nil {
43 t.Fatalf("Expected error when passing nil to FileInfoHeader")
47 func TestFileInfoHeaderDir(t *testing.T) {
48 fi, err := os.Stat("testdata")
49 if err != nil {
50 t.Fatal(err)
52 h, err := FileInfoHeader(fi, "")
53 if err != nil {
54 t.Fatalf("FileInfoHeader: %v", err)
56 if g, e := h.Name, "testdata/"; g != e {
57 t.Errorf("Name = %q; want %q", g, e)
59 // Ignoring c_ISGID for golang.org/issue/4867
60 if g, e := h.Mode&^c_ISGID, int64(fi.Mode().Perm()); g != e {
61 t.Errorf("Mode = %#o; want %#o", g, e)
63 if g, e := h.Size, int64(0); g != e {
64 t.Errorf("Size = %v; want %v", g, e)
66 if g, e := h.ModTime, fi.ModTime(); !g.Equal(e) {
67 t.Errorf("ModTime = %v; want %v", g, e)
71 func TestFileInfoHeaderSymlink(t *testing.T) {
72 testenv.MustHaveSymlink(t)
74 tmpdir, err := ioutil.TempDir("", "TestFileInfoHeaderSymlink")
75 if err != nil {
76 t.Fatal(err)
78 defer os.RemoveAll(tmpdir)
80 link := filepath.Join(tmpdir, "link")
81 target := tmpdir
82 err = os.Symlink(target, link)
83 if err != nil {
84 t.Fatal(err)
86 fi, err := os.Lstat(link)
87 if err != nil {
88 t.Fatal(err)
91 h, err := FileInfoHeader(fi, target)
92 if err != nil {
93 t.Fatal(err)
95 if g, e := h.Name, fi.Name(); g != e {
96 t.Errorf("Name = %q; want %q", g, e)
98 if g, e := h.Linkname, target; g != e {
99 t.Errorf("Linkname = %q; want %q", g, e)
101 if g, e := h.Typeflag, byte(TypeSymlink); g != e {
102 t.Errorf("Typeflag = %v; want %v", g, e)
106 func TestRoundTrip(t *testing.T) {
107 data := []byte("some file contents")
109 var b bytes.Buffer
110 tw := NewWriter(&b)
111 hdr := &Header{
112 Name: "file.txt",
113 Uid: 1 << 21, // too big for 8 octal digits
114 Size: int64(len(data)),
115 // AddDate to strip monotonic clock reading,
116 // and Round to discard sub-second precision,
117 // both of which are not included in the tar header
118 // and would otherwise break the round-trip check
119 // below.
120 ModTime: time.Now().AddDate(0, 0, 0).Round(1 * time.Second),
122 if err := tw.WriteHeader(hdr); err != nil {
123 t.Fatalf("tw.WriteHeader: %v", err)
125 if _, err := tw.Write(data); err != nil {
126 t.Fatalf("tw.Write: %v", err)
128 if err := tw.Close(); err != nil {
129 t.Fatalf("tw.Close: %v", err)
132 // Read it back.
133 tr := NewReader(&b)
134 rHdr, err := tr.Next()
135 if err != nil {
136 t.Fatalf("tr.Next: %v", err)
138 if !reflect.DeepEqual(rHdr, hdr) {
139 t.Errorf("Header mismatch.\n got %+v\nwant %+v", rHdr, hdr)
141 rData, err := ioutil.ReadAll(tr)
142 if err != nil {
143 t.Fatalf("Read: %v", err)
145 if !bytes.Equal(rData, data) {
146 t.Errorf("Data mismatch.\n got %q\nwant %q", rData, data)
150 type headerRoundTripTest struct {
151 h *Header
152 fm os.FileMode
155 func TestHeaderRoundTrip(t *testing.T) {
156 vectors := []headerRoundTripTest{{
157 // regular file.
158 h: &Header{
159 Name: "test.txt",
160 Mode: 0644,
161 Size: 12,
162 ModTime: time.Unix(1360600916, 0),
163 Typeflag: TypeReg,
165 fm: 0644,
166 }, {
167 // symbolic link.
168 h: &Header{
169 Name: "link.txt",
170 Mode: 0777,
171 Size: 0,
172 ModTime: time.Unix(1360600852, 0),
173 Typeflag: TypeSymlink,
175 fm: 0777 | os.ModeSymlink,
176 }, {
177 // character device node.
178 h: &Header{
179 Name: "dev/null",
180 Mode: 0666,
181 Size: 0,
182 ModTime: time.Unix(1360578951, 0),
183 Typeflag: TypeChar,
185 fm: 0666 | os.ModeDevice | os.ModeCharDevice,
186 }, {
187 // block device node.
188 h: &Header{
189 Name: "dev/sda",
190 Mode: 0660,
191 Size: 0,
192 ModTime: time.Unix(1360578954, 0),
193 Typeflag: TypeBlock,
195 fm: 0660 | os.ModeDevice,
196 }, {
197 // directory.
198 h: &Header{
199 Name: "dir/",
200 Mode: 0755,
201 Size: 0,
202 ModTime: time.Unix(1360601116, 0),
203 Typeflag: TypeDir,
205 fm: 0755 | os.ModeDir,
206 }, {
207 // fifo node.
208 h: &Header{
209 Name: "dev/initctl",
210 Mode: 0600,
211 Size: 0,
212 ModTime: time.Unix(1360578949, 0),
213 Typeflag: TypeFifo,
215 fm: 0600 | os.ModeNamedPipe,
216 }, {
217 // setuid.
218 h: &Header{
219 Name: "bin/su",
220 Mode: 0755 | c_ISUID,
221 Size: 23232,
222 ModTime: time.Unix(1355405093, 0),
223 Typeflag: TypeReg,
225 fm: 0755 | os.ModeSetuid,
226 }, {
227 // setguid.
228 h: &Header{
229 Name: "group.txt",
230 Mode: 0750 | c_ISGID,
231 Size: 0,
232 ModTime: time.Unix(1360602346, 0),
233 Typeflag: TypeReg,
235 fm: 0750 | os.ModeSetgid,
236 }, {
237 // sticky.
238 h: &Header{
239 Name: "sticky.txt",
240 Mode: 0600 | c_ISVTX,
241 Size: 7,
242 ModTime: time.Unix(1360602540, 0),
243 Typeflag: TypeReg,
245 fm: 0600 | os.ModeSticky,
246 }, {
247 // hard link.
248 h: &Header{
249 Name: "hard.txt",
250 Mode: 0644,
251 Size: 0,
252 Linkname: "file.txt",
253 ModTime: time.Unix(1360600916, 0),
254 Typeflag: TypeLink,
256 fm: 0644,
257 }, {
258 // More information.
259 h: &Header{
260 Name: "info.txt",
261 Mode: 0600,
262 Size: 0,
263 Uid: 1000,
264 Gid: 1000,
265 ModTime: time.Unix(1360602540, 0),
266 Uname: "slartibartfast",
267 Gname: "users",
268 Typeflag: TypeReg,
270 fm: 0600,
273 for i, v := range vectors {
274 fi := v.h.FileInfo()
275 h2, err := FileInfoHeader(fi, "")
276 if err != nil {
277 t.Error(err)
278 continue
280 if strings.Contains(fi.Name(), "/") {
281 t.Errorf("FileInfo of %q contains slash: %q", v.h.Name, fi.Name())
283 name := path.Base(v.h.Name)
284 if fi.IsDir() {
285 name += "/"
287 if got, want := h2.Name, name; got != want {
288 t.Errorf("i=%d: Name: got %v, want %v", i, got, want)
290 if got, want := h2.Size, v.h.Size; got != want {
291 t.Errorf("i=%d: Size: got %v, want %v", i, got, want)
293 if got, want := h2.Uid, v.h.Uid; got != want {
294 t.Errorf("i=%d: Uid: got %d, want %d", i, got, want)
296 if got, want := h2.Gid, v.h.Gid; got != want {
297 t.Errorf("i=%d: Gid: got %d, want %d", i, got, want)
299 if got, want := h2.Uname, v.h.Uname; got != want {
300 t.Errorf("i=%d: Uname: got %q, want %q", i, got, want)
302 if got, want := h2.Gname, v.h.Gname; got != want {
303 t.Errorf("i=%d: Gname: got %q, want %q", i, got, want)
305 if got, want := h2.Linkname, v.h.Linkname; got != want {
306 t.Errorf("i=%d: Linkname: got %v, want %v", i, got, want)
308 if got, want := h2.Typeflag, v.h.Typeflag; got != want {
309 t.Logf("%#v %#v", v.h, fi.Sys())
310 t.Errorf("i=%d: Typeflag: got %q, want %q", i, got, want)
312 if got, want := h2.Mode, v.h.Mode; got != want {
313 t.Errorf("i=%d: Mode: got %o, want %o", i, got, want)
315 if got, want := fi.Mode(), v.fm; got != want {
316 t.Errorf("i=%d: fi.Mode: got %o, want %o", i, got, want)
318 if got, want := h2.AccessTime, v.h.AccessTime; got != want {
319 t.Errorf("i=%d: AccessTime: got %v, want %v", i, got, want)
321 if got, want := h2.ChangeTime, v.h.ChangeTime; got != want {
322 t.Errorf("i=%d: ChangeTime: got %v, want %v", i, got, want)
324 if got, want := h2.ModTime, v.h.ModTime; got != want {
325 t.Errorf("i=%d: ModTime: got %v, want %v", i, got, want)
327 if sysh, ok := fi.Sys().(*Header); !ok || sysh != v.h {
328 t.Errorf("i=%d: Sys didn't return original *Header", i)