Validating Cross-Platform AR Archive Parsing in Telegram
This test suite validates the parsing and handling of AR archive files across different operating systems (Linux, macOS, Windows) in the BoringSSL library used by Telegram. It ensures correct extraction and verification of object files from static libraries.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
drklo/telegram
TMessagesProj/jni/boringssl/util/ar/ar_test.go
// 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)
}
}
})
}
}