| // Copyright (c) 2018, Google Inc. |
| // |
| // Permission to use, copy, modify, and/or distribute this software for any |
| // purpose with or without fee is hereby granted, provided that the above |
| // copyright notice and this permission notice appear in all copies. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| // OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| // CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
| |
| package ar |
| |
| import ( |
| "bytes" |
| "flag" |
| "io/ioutil" |
| "os" |
| "path/filepath" |
| "testing" |
| ) |
| |
| var testDataDir = flag.String("testdata", "testdata", "The path to the test data directory.") |
| |
| type arTest struct { |
| name string |
| in string |
| out []string |
| // allowPadding is true if the contents may have trailing newlines at end. |
| // On macOS, ar calls ranlib which pads all inputs up to eight bytes with |
| // newlines. Unlike ar's native padding up to two bytes, this padding is |
| // included in the size field, so it is not removed when decoding. |
| allowPadding bool |
| } |
| |
| func (test *arTest) Path(file string) string { |
| return filepath.Join(*testDataDir, test.name, file) |
| } |
| |
| func removeTrailingNewlines(in []byte) []byte { |
| for len(in) > 0 && in[len(in)-1] == '\n' { |
| in = in[:len(in)-1] |
| } |
| return in |
| } |
| |
| var arTests = []arTest{ |
| {"linux", "libsample.a", []string{"foo.c.o", "bar.cc.o"}, false}, |
| {"mac", "libsample.a", []string{"foo.c.o", "bar.cc.o"}, true}, |
| } |
| |
| func TestAR(t *testing.T) { |
| for _, test := range arTests { |
| t.Run(test.name, func(t *testing.T) { |
| in, err := os.Open(test.Path(test.in)) |
| if err != nil { |
| t.Fatalf("opening input failed: %s", err) |
| } |
| defer in.Close() |
| |
| ret, err := ParseAR(in) |
| if err != nil { |
| t.Fatalf("reading input failed: %s", err) |
| } |
| |
| expectedFiles := make(map[string]struct{}) |
| for _, file := range test.out { |
| expectedFiles[file] = struct{}{} |
| expected, err := ioutil.ReadFile(test.Path(file)) |
| if err != nil { |
| t.Fatalf("error reading %s: %s", file, err) |
| } |
| got, ok := ret[file] |
| if test.allowPadding { |
| got = removeTrailingNewlines(got) |
| expected = removeTrailingNewlines(got) |
| } |
| if !ok { |
| t.Errorf("file %s missing from output", file) |
| } else if !bytes.Equal(got, expected) { |
| t.Errorf("contents for file %s did not match", file) |
| } |
| } |
| |
| for file, _ := range ret { |
| if _, ok := expectedFiles[file]; !ok { |
| t.Errorf("output contained unexpected file %q", file) |
| } |
| } |
| }) |
| } |
| } |