Commit 04262986 authored by Joe Tsai's avatar Joe Tsai Committed by Joe Tsai

archive/tar: compact slices in tests

Took this opportunity to also embed tables in the functions
that they are actually used in and other stylistic cleanups.

There was no logical changes to the tests.

Change-Id: Ifa724060532175f6f4407d6cedc841891efd8f7b
Reviewed-on: https://go-review.googlesource.com/31436
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 5378dd77
This diff is collapsed.
......@@ -135,9 +135,8 @@ type headerRoundTripTest struct {
}
func TestHeaderRoundTrip(t *testing.T) {
golden := []headerRoundTripTest{
vectors := []headerRoundTripTest{{
// regular file.
{
h: &Header{
Name: "test.txt",
Mode: 0644 | c_ISREG,
......@@ -146,9 +145,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeReg,
},
fm: 0644,
},
}, {
// symbolic link.
{
h: &Header{
Name: "link.txt",
Mode: 0777 | c_ISLNK,
......@@ -157,9 +155,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeSymlink,
},
fm: 0777 | os.ModeSymlink,
},
}, {
// character device node.
{
h: &Header{
Name: "dev/null",
Mode: 0666 | c_ISCHR,
......@@ -168,9 +165,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeChar,
},
fm: 0666 | os.ModeDevice | os.ModeCharDevice,
},
}, {
// block device node.
{
h: &Header{
Name: "dev/sda",
Mode: 0660 | c_ISBLK,
......@@ -179,9 +175,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeBlock,
},
fm: 0660 | os.ModeDevice,
},
}, {
// directory.
{
h: &Header{
Name: "dir/",
Mode: 0755 | c_ISDIR,
......@@ -190,9 +185,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeDir,
},
fm: 0755 | os.ModeDir,
},
}, {
// fifo node.
{
h: &Header{
Name: "dev/initctl",
Mode: 0600 | c_ISFIFO,
......@@ -201,9 +195,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeFifo,
},
fm: 0600 | os.ModeNamedPipe,
},
}, {
// setuid.
{
h: &Header{
Name: "bin/su",
Mode: 0755 | c_ISREG | c_ISUID,
......@@ -212,9 +205,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeReg,
},
fm: 0755 | os.ModeSetuid,
},
}, {
// setguid.
{
h: &Header{
Name: "group.txt",
Mode: 0750 | c_ISREG | c_ISGID,
......@@ -223,9 +215,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeReg,
},
fm: 0750 | os.ModeSetgid,
},
}, {
// sticky.
{
h: &Header{
Name: "sticky.txt",
Mode: 0600 | c_ISREG | c_ISVTX,
......@@ -234,9 +225,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeReg,
},
fm: 0600 | os.ModeSticky,
},
}, {
// hard link.
{
h: &Header{
Name: "hard.txt",
Mode: 0644 | c_ISREG,
......@@ -246,9 +236,8 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeLink,
},
fm: 0644,
},
}, {
// More information.
{
h: &Header{
Name: "info.txt",
Mode: 0600 | c_ISREG,
......@@ -261,64 +250,63 @@ func TestHeaderRoundTrip(t *testing.T) {
Typeflag: TypeReg,
},
fm: 0600,
},
}
}}
for i, g := range golden {
fi := g.h.FileInfo()
for i, v := range vectors {
fi := v.h.FileInfo()
h2, err := FileInfoHeader(fi, "")
if err != nil {
t.Error(err)
continue
}
if strings.Contains(fi.Name(), "/") {
t.Errorf("FileInfo of %q contains slash: %q", g.h.Name, fi.Name())
t.Errorf("FileInfo of %q contains slash: %q", v.h.Name, fi.Name())
}
name := path.Base(g.h.Name)
name := path.Base(v.h.Name)
if fi.IsDir() {
name += "/"
}
if got, want := h2.Name, name; got != want {
t.Errorf("i=%d: Name: got %v, want %v", i, got, want)
}
if got, want := h2.Size, g.h.Size; got != want {
if got, want := h2.Size, v.h.Size; got != want {
t.Errorf("i=%d: Size: got %v, want %v", i, got, want)
}
if got, want := h2.Uid, g.h.Uid; got != want {
if got, want := h2.Uid, v.h.Uid; got != want {
t.Errorf("i=%d: Uid: got %d, want %d", i, got, want)
}
if got, want := h2.Gid, g.h.Gid; got != want {
if got, want := h2.Gid, v.h.Gid; got != want {
t.Errorf("i=%d: Gid: got %d, want %d", i, got, want)
}
if got, want := h2.Uname, g.h.Uname; got != want {
if got, want := h2.Uname, v.h.Uname; got != want {
t.Errorf("i=%d: Uname: got %q, want %q", i, got, want)
}
if got, want := h2.Gname, g.h.Gname; got != want {
if got, want := h2.Gname, v.h.Gname; got != want {
t.Errorf("i=%d: Gname: got %q, want %q", i, got, want)
}
if got, want := h2.Linkname, g.h.Linkname; got != want {
if got, want := h2.Linkname, v.h.Linkname; got != want {
t.Errorf("i=%d: Linkname: got %v, want %v", i, got, want)
}
if got, want := h2.Typeflag, g.h.Typeflag; got != want {
t.Logf("%#v %#v", g.h, fi.Sys())
if got, want := h2.Typeflag, v.h.Typeflag; got != want {
t.Logf("%#v %#v", v.h, fi.Sys())
t.Errorf("i=%d: Typeflag: got %q, want %q", i, got, want)
}
if got, want := h2.Mode, g.h.Mode; got != want {
if got, want := h2.Mode, v.h.Mode; got != want {
t.Errorf("i=%d: Mode: got %o, want %o", i, got, want)
}
if got, want := fi.Mode(), g.fm; got != want {
if got, want := fi.Mode(), v.fm; got != want {
t.Errorf("i=%d: fi.Mode: got %o, want %o", i, got, want)
}
if got, want := h2.AccessTime, g.h.AccessTime; got != want {
if got, want := h2.AccessTime, v.h.AccessTime; got != want {
t.Errorf("i=%d: AccessTime: got %v, want %v", i, got, want)
}
if got, want := h2.ChangeTime, g.h.ChangeTime; got != want {
if got, want := h2.ChangeTime, v.h.ChangeTime; got != want {
t.Errorf("i=%d: ChangeTime: got %v, want %v", i, got, want)
}
if got, want := h2.ModTime, g.h.ModTime; got != want {
if got, want := h2.ModTime, v.h.ModTime; got != want {
t.Errorf("i=%d: ModTime: got %v, want %v", i, got, want)
}
if sysh, ok := fi.Sys().(*Header); !ok || sysh != g.h {
if sysh, ok := fi.Sys().(*Header); !ok || sysh != v.h {
t.Errorf("i=%d: Sys didn't return original *Header", i)
}
}
......
......@@ -18,25 +18,60 @@ import (
"time"
)
type writerTestEntry struct {
header *Header
contents string
// Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
func bytestr(offset int, b []byte) string {
const rowLen = 32
s := fmt.Sprintf("%04x ", offset)
for _, ch := range b {
switch {
case '0' <= ch && ch <= '9', 'A' <= ch && ch <= 'Z', 'a' <= ch && ch <= 'z':
s += fmt.Sprintf(" %c", ch)
default:
s += fmt.Sprintf(" %02x", ch)
}
}
return s
}
type writerTest struct {
file string // filename of expected output
entries []*writerTestEntry
// Render a pseudo-diff between two blocks of bytes.
func bytediff(a []byte, b []byte) string {
const rowLen = 32
s := fmt.Sprintf("(%d bytes vs. %d bytes)\n", len(a), len(b))
for offset := 0; len(a)+len(b) > 0; offset += rowLen {
na, nb := rowLen, rowLen
if na > len(a) {
na = len(a)
}
if nb > len(b) {
nb = len(b)
}
sa := bytestr(offset, a[0:na])
sb := bytestr(offset, b[0:nb])
if sa != sb {
s += fmt.Sprintf("-%v\n+%v\n", sa, sb)
}
a = a[na:]
b = b[nb:]
}
return s
}
var writerTests = []*writerTest{
func TestWriter(t *testing.T) {
type entry struct {
header *Header
contents string
}
vectors := []struct {
file string // filename of expected output
entries []*entry
}{{
// The writer test file was produced with this command:
// tar (GNU tar) 1.26
// ln -s small.txt link.txt
// tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt
{
file: "testdata/writer.tar",
entries: []*writerTestEntry{
{
entries: []*entry{{
header: &Header{
Name: "small.txt",
Mode: 0640,
......@@ -49,8 +84,7 @@ var writerTests = []*writerTest{
Gname: "eng",
},
contents: "Kilts",
},
{
}, {
header: &Header{
Name: "small2.txt",
Mode: 0640,
......@@ -63,8 +97,7 @@ var writerTests = []*writerTest{
Gname: "eng",
},
contents: "Google.com\n",
},
{
}, {
header: &Header{
Name: "link.txt",
Mode: 0777,
......@@ -78,16 +111,13 @@ var writerTests = []*writerTest{
Gname: "strings",
},
// no contents
},
},
},
}},
}, {
// The truncated test file was produced using these commands:
// dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt
// tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar
{
file: "testdata/writer-big.tar",
entries: []*writerTestEntry{
{
entries: []*entry{{
header: &Header{
Name: "tmp/16gig.txt",
Mode: 0640,
......@@ -101,16 +131,13 @@ var writerTests = []*writerTest{
},
// fake contents
contents: strings.Repeat("\x00", 4<<10),
},
},
},
}},
}, {
// The truncated test file was produced using these commands:
// dd if=/dev/zero bs=1048576 count=16384 > (longname/)*15 /16gig.txt
// tar -b 1 -c -f- (longname/)*15 /16gig.txt | dd bs=512 count=8 > writer-big-long.tar
{
file: "testdata/writer-big-long.tar",
entries: []*writerTestEntry{
{
entries: []*entry{{
header: &Header{
Name: strings.Repeat("longname/", 15) + "16gig.txt",
Mode: 0644,
......@@ -124,15 +151,12 @@ var writerTests = []*writerTest{
},
// fake contents
contents: strings.Repeat("\x00", 4<<10),
},
},
},
}},
}, {
// This file was produced using gnu tar 1.17
// gnutar -b 4 --format=ustar (longname/)*15 + file.txt
{
file: "testdata/ustar.tar",
entries: []*writerTestEntry{
{
entries: []*entry{{
header: &Header{
Name: strings.Repeat("longname/", 15) + "file.txt",
Mode: 0644,
......@@ -145,17 +169,14 @@ var writerTests = []*writerTest{
Gname: "staff",
},
contents: "hello\n",
},
},
},
}},
}, {
// This file was produced using gnu tar 1.26
// echo "Slartibartfast" > file.txt
// ln file.txt hard.txt
// tar -b 1 --format=ustar -c -f hardlink.tar file.txt hard.txt
{
file: "testdata/hardlink.tar",
entries: []*writerTestEntry{
{
entries: []*entry{{
header: &Header{
Name: "file.txt",
Mode: 0644,
......@@ -168,8 +189,7 @@ var writerTests = []*writerTest{
Gname: "users",
},
contents: "Slartibartfast\n",
},
{
}, {
header: &Header{
Name: "hard.txt",
Mode: 0644,
......@@ -183,53 +203,12 @@ var writerTests = []*writerTest{
Gname: "users",
},
// no contents
},
},
},
}
// Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
func bytestr(offset int, b []byte) string {
const rowLen = 32
s := fmt.Sprintf("%04x ", offset)
for _, ch := range b {
switch {
case '0' <= ch && ch <= '9', 'A' <= ch && ch <= 'Z', 'a' <= ch && ch <= 'z':
s += fmt.Sprintf(" %c", ch)
default:
s += fmt.Sprintf(" %02x", ch)
}
}
return s
}
}},
}}
// Render a pseudo-diff between two blocks of bytes.
func bytediff(a []byte, b []byte) string {
const rowLen = 32
s := fmt.Sprintf("(%d bytes vs. %d bytes)\n", len(a), len(b))
for offset := 0; len(a)+len(b) > 0; offset += rowLen {
na, nb := rowLen, rowLen
if na > len(a) {
na = len(a)
}
if nb > len(b) {
nb = len(b)
}
sa := bytestr(offset, a[0:na])
sb := bytestr(offset, b[0:nb])
if sa != sb {
s += fmt.Sprintf("-%v\n+%v\n", sa, sb)
}
a = a[na:]
b = b[nb:]
}
return s
}
func TestWriter(t *testing.T) {
testLoop:
for i, test := range writerTests {
expected, err := ioutil.ReadFile(test.file)
for i, v := range vectors {
expected, err := ioutil.ReadFile(v.file)
if err != nil {
t.Errorf("test %d: Unexpected error: %v", i, err)
continue
......@@ -238,7 +217,7 @@ testLoop:
buf := new(bytes.Buffer)
tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
big := false
for j, entry := range test.entries {
for j, entry := range v.entries {
big = big || entry.header.Size > 1<<10
if err := tw.WriteHeader(entry.header); err != nil {
t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
......@@ -575,9 +554,9 @@ func TestWriteAfterClose(t *testing.T) {
}
func TestSplitUSTARPath(t *testing.T) {
var sr = strings.Repeat
sr := strings.Repeat
var vectors = []struct {
vectors := []struct {
input string // Input path
prefix string // Expected output prefix
suffix string // Expected output suffix
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment