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.
20 func TestFileInfoHeader(t
*testing
.T
) {
21 fi
, err
:= os
.Stat("testdata/small.txt")
25 h
, err
:= FileInfoHeader(fi
, "")
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")
52 h
, err
:= FileInfoHeader(fi
, "")
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")
78 defer os
.RemoveAll(tmpdir
)
80 link
:= filepath
.Join(tmpdir
, "link")
82 err
= os
.Symlink(target
, link
)
86 fi
, err
:= os
.Lstat(link
)
91 h
, err
:= FileInfoHeader(fi
, target
)
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")
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
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
)
134 rHdr
, err
:= tr
.Next()
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
)
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 {
155 func TestHeaderRoundTrip(t
*testing
.T
) {
156 vectors
:= []headerRoundTripTest
{{
162 ModTime
: time
.Unix(1360600916, 0),
172 ModTime
: time
.Unix(1360600852, 0),
173 Typeflag
: TypeSymlink
,
175 fm
: 0777 | os
.ModeSymlink
,
177 // character device node.
182 ModTime
: time
.Unix(1360578951, 0),
185 fm
: 0666 | os
.ModeDevice | os
.ModeCharDevice
,
187 // block device node.
192 ModTime
: time
.Unix(1360578954, 0),
195 fm
: 0660 | os
.ModeDevice
,
202 ModTime
: time
.Unix(1360601116, 0),
205 fm
: 0755 | os
.ModeDir
,
212 ModTime
: time
.Unix(1360578949, 0),
215 fm
: 0600 | os
.ModeNamedPipe
,
220 Mode
: 0755 | c_ISUID
,
222 ModTime
: time
.Unix(1355405093, 0),
225 fm
: 0755 | os
.ModeSetuid
,
230 Mode
: 0750 | c_ISGID
,
232 ModTime
: time
.Unix(1360602346, 0),
235 fm
: 0750 | os
.ModeSetgid
,
240 Mode
: 0600 | c_ISVTX
,
242 ModTime
: time
.Unix(1360602540, 0),
245 fm
: 0600 | os
.ModeSticky
,
252 Linkname
: "file.txt",
253 ModTime
: time
.Unix(1360600916, 0),
265 ModTime
: time
.Unix(1360602540, 0),
266 Uname
: "slartibartfast",
273 for i
, v
:= range vectors
{
275 h2
, err
:= FileInfoHeader(fi
, "")
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
)
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
)