// 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 map[string]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", map[string]string{ "foo.c.o": "foo.c.o", "bar.cc.o": "bar.cc.o", }, false, }, { "mac", "libsample.a", map[string]string{ "foo.c.o": "foo.c.o", "bar.cc.o": "bar.cc.o", }, true, }, { "windows", "sample.lib", map[string]string{ "CMakeFiles\\sample.dir\\foo.c.obj": "foo.c.obj", "CMakeFiles\\sample.dir\\bar.cc.obj": "bar.cc.obj", }, false, }, } 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) } for file, contentsPath := range test.out { expected, err := ioutil.ReadFile(test.Path(contentsPath)) if err != nil { t.Fatalf("error reading %s: %s", contentsPath, 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 := test.out[file]; !ok { t.Errorf("output contained unexpected file %q", file) } } }) } }