1// Copyright (c) 2011 Mikkel Krautz 2// The use of this source code is goverened by a BSD-style 3// license that can be found in the LICENSE-file. 4 5package ar 6 7import ( 8 "bytes" 9 "io" 10 "os" 11 "testing" 12) 13 14var fbsd82Archive []archiveTest = []archiveTest{ 15 { 16 &Header{ 17 Name: "/", 18 Mode: 0, 19 Mtime: 1315607407, 20 Uid: 0, 21 Gid: 0, 22 Size: 4, 23 }, 24 []byte{0x0, 0x0, 0x0, 0x0}, 25 }, 26 { 27 &Header{ 28 Name: "a", 29 Mode: 0100644, 30 Mtime: 1315607373, 31 Uid: 1001, 32 Gid: 1001, 33 Size: 2, 34 }, 35 []byte{'a', '\n'}, 36 }, 37 { 38 &Header{ 39 Name: "b", 40 Mode: 0100644, 41 Mtime: 1315607374, 42 Uid: 1001, 43 Gid: 1001, 44 Size: 2, 45 }, 46 []byte{'b', '\n'}, 47 }, 48 { 49 &Header{ 50 Name: "c", 51 Mode: 0100644, 52 Mtime: 1315607376, 53 Uid: 1001, 54 Gid: 1001, 55 Size: 2, 56 }, 57 []byte{'c', '\n'}, 58 }, 59} 60 61var lionArchive []archiveTest = []archiveTest{ 62 { 63 &Header{ 64 Name: "__.SYMDEF SORTED", 65 Mode: 0100644, 66 Mtime: 1315593186, 67 Uid: 501, 68 Gid: 20, 69 Size: 8, 70 }, 71 []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 72 }, 73 { 74 &Header{ 75 Name: "a", 76 Mode: 0100644, 77 Mtime: 1315593158, 78 Uid: 501, 79 Gid: 20, 80 Size: 8, 81 }, 82 []byte("a\n\n\n\n\n\n\n"), 83 }, 84 { 85 &Header{ 86 Name: "b", 87 Mode: 0100644, 88 Mtime: 1315593165, 89 Uid: 501, 90 Gid: 20, 91 Size: 8, 92 }, 93 []byte("b\n\n\n\n\n\n\n"), 94 }, 95 { 96 &Header{ 97 Name: "c", 98 Mode: 0100644, 99 Mtime: 1315593166, 100 Uid: 501, 101 Gid: 20, 102 Size: 8, 103 }, 104 []byte("c\n\n\n\n\n\n\n"), 105 }, 106} 107 108var linuxArchive []archiveTest = []archiveTest{ 109 { 110 &Header{ 111 Name: "0", 112 Mode: 0100770, 113 Mtime: 1369126995, 114 Uid: 0, 115 Gid: 1001, 116 Size: 0, 117 }, 118 []byte{}, 119 }, 120 { 121 &Header{ 122 Name: "1", 123 Mode: 0100770, 124 Mtime: 1369127013, 125 Uid: 0, 126 Gid: 1001, 127 Size: 1, 128 }, 129 []byte("a"), 130 }, 131 { 132 &Header{ 133 Name: "2", 134 Mode: 0100770, 135 Mtime: 1369127016, 136 Uid: 0, 137 Gid: 1001, 138 Size: 2, 139 }, 140 []byte("ab"), 141 }, 142 { 143 &Header{ 144 Name: "3", 145 Mode: 0100770, 146 Mtime: 1369127019, 147 Uid: 0, 148 Gid: 1001, 149 Size: 3, 150 }, 151 []byte("abc"), 152 }, 153 { 154 &Header{ 155 Name: "long-long-file-name", 156 Mode: 0100770, 157 Mtime: 1369127028, 158 Uid: 0, 159 Gid: 1001, 160 Size: 25, 161 }, 162 []byte("Gopher's name is Gordon.\n"), 163 }, 164} 165 166func read(t *testing.T, r io.Reader, testArchive []archiveTest, readBody bool) { 167 ar := NewReader(r) 168 for _, testEntry := range testArchive { 169 hdr, err := ar.Next() 170 if err != nil { 171 t.Fatal(err) 172 } 173 if !headerCmp(hdr, testEntry.hdr) { 174 t.Fatalf("header mismatch:\nread = %+v\norig = %+v", hdr, testEntry.hdr) 175 } 176 if readBody { 177 fbuf := make([]byte, hdr.Size) 178 _, err = io.ReadFull(ar, fbuf) 179 if err != nil { 180 t.Fatal(err) 181 } 182 if !bytes.Equal(fbuf, testEntry.data) { 183 t.Fatalf("data mismatch\nread = %v\norig = %v", fbuf, testEntry.data) 184 } 185 } 186 } 187 188 _, err := ar.Next() 189 if err != io.EOF { 190 t.Fatalf("expected EOF, got %v", err) 191 } 192} 193 194func testRead(t *testing.T, r io.ReadSeeker, testArchive []archiveTest) { 195 read(t, r, testArchive, true) 196 r.Seek(0, 0) 197 read(t, r, testArchive, false) 198} 199 200// Test the we can correctly read and parse a FreeBSD 8.2 generated ar file. 201func TestReadFreeBSD82LibArchive(t *testing.T) { 202 f, err := os.Open("testdata/test-bsd-freebsd82-libarchive.ar") 203 if err != nil { 204 t.Fatal(err) 205 } 206 defer f.Close() 207 testRead(t, f, fbsd82Archive) 208} 209 210// Test the we can correctly read and parse a Mac OS X Lion generated ar file. 211// It is generated in the same way as the FreeBSD archive ahove, but ar on OS X 212// seems to pad the archived files with a lot of newlines. 213// Attempting to "ar x" the archive also reproduces the newlines in the extracted 214// files, so they are not a form of padding, but are intended to be there, somehow. 215func TestReadMacOSXLionOld(t *testing.T) { 216 f, err := os.Open("testdata/test-bsd-macosx.ar") 217 if err != nil { 218 t.Fatal(err) 219 } 220 defer f.Close() 221 testRead(t, f, lionArchive) 222} 223 224func TestReadLinux(t *testing.T) { 225 f, err := os.Open("testdata/test-gnu-linux.ar") 226 if err != nil { 227 t.Fatal(err) 228 } 229 defer f.Close() 230 testRead(t, f, linuxArchive) 231} 232