blob: 550aa4c304e086b573ebb3220d29bb5a33efbe31 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package metadata
import (
"os/exec"
"reflect"
"runtime"
"testing"
)
var allTests = []struct {
MD *T
XML string
B64 []string
}{
{
MD: FromMap(nil),
XML: `<metadata></metadata>`,
B64: []string{`eJyyyU0tSUxJLEm0s9GHMwEBAAD//1RmB6Y=`},
},
{
MD: FromMap(map[string]string{
"A": `a value`,
"B": `b value`,
"C": `c value`,
}),
XML: `<metadata>
<md id="A">a value</md>
<md id="B">b value</md>
<md id="C">c value</md>
</metadata>`,
B64: []string{`eJyyyU0tSUxJLEm0s8lNUchMsVVyVLJLVChLzClNtdHPTYELOynZJWERdlayS0YW1oebBwgAAP//H2Qc4g==`},
},
{
MD: FromMap(map[string]string{
"A": `a value`,
"B": `
b value
has newlines
galore
`,
"C": `c value`,
}),
XML: `<metadata>
<md id="A">a value</md>
<md id="B"><![CDATA[
b value
has newlines
galore
]]></md>
<md id="C">c value</md>
</metadata>`,
B64: []string{`eJyyyU0tSUxJLEm0s8lNUchMsVVyVLJLVChLzClNtdHPTYELOynZ2ShGO7s4hjhGcyVBFHApKChkJBYr5KWW52TmpRZzKaQn5uQXgcRjY+1QtDsr2SUjm6oPtxcQAAD//0qVKG0=`},
},
{
MD: FromMap(map[string]string{
"BuildPlatform": `amd64unknown-linux-unknown`,
"BuildTime": `2015-05-01T01:33:35Z`,
"Manifest": `
<manifest label="">
<projects>
<project exclude="false" name="release.go.v23" path="release/go/src/v.io/v23" protocol="git" remote="https://vanadium.googlesource.com/release.go.v23" revision="16889ec00eb4008849057a5e9014a025a231f836"></project>
<project exclude="false" name="release.go.x.devtools" path="release/go/src/v.io/x/devtools" protocol="git" remote="https://vanadium.googlesource.com/release.go.x.devtools" revision="de0bd3a5f0f9b30532c41bdb01661cfe8c24df76"></project>
</projects>
</manifest>
`,
"ZZZ": `zzz`,
}),
XML: `<metadata>
<md id="BuildPlatform">amd64unknown-linux-unknown</md>
<md id="BuildTime">2015-05-01T01:33:35Z</md>
<md id="Manifest"><![CDATA[
<manifest label="">
<projects>
<project exclude="false" name="release.go.v23" path="release/go/src/v.io/v23" protocol="git" remote="https://vanadium.googlesource.com/release.go.v23" revision="16889ec00eb4008849057a5e9014a025a231f836"></project>
<project exclude="false" name="release.go.x.devtools" path="release/go/src/v.io/x/devtools" protocol="git" remote="https://vanadium.googlesource.com/release.go.x.devtools" revision="de0bd3a5f0f9b30532c41bdb01661cfe8c24df76"></project>
</projects>
</manifest>
]]></md>
<md id="ZZZ">zzz</md>
</metadata>`,
B64: []string{
`eJyskrFu2zAQhvc8hcrdIilKimxIBNJ2LdDBk4MMJ/KksCV1hkiphp++COI6cYYCBTp+/x1x+MC/DZjAQgLdBps527HPi/P2u4c00ByYhmDrcpl+TvRr2ng3LafNhVoe7O2rvQvIdCFktRHVRsi9kDuldqo63Ox+g8kNGBPT7afHL18f9g+Pd224hJmHHn3HmL7LsvY40w80Kb7AG2Z4Mn6x2LEBfESWTRCwYzN6hIj5SPlaKJYdIT1fUz4Sj7Pha+6Iv45nSmTId2x0iWUzBkrYseeUjnHH+QoTWLeEfCQaPUZaZoO5ocA/3plxddHR1DFZN80WjRDYl0I0TbkV1T1UuBWyBFFUUCg5NKpmuuUXl381O+UW10Tk498ET/zd1n/wfH/1Tdei6K2CahDDtleiUoUpZW97IetamgEbU5R2uP+oe4Wo71r+5+NfJk9P+qYph8OB6fP5/Brya1d/BwAA//8zuuV+`,
`eJyskjFv2zAQhff8CpW7RVKUFNmQBaTtWqCDJwcZTuTJYUvqDJFSDf/6MojhxBkKFAjA5d0d7+HDvdZjBAMRutabzJot+zpbZ346iANNnnXgTV3O4++R/owrZ8f5tLqolntz+2tnPbKuELJaifTkTsiNUhtV7W9mf8BoBwyRde2Xx2/fH3YPj3etvxQzBz26LWPdXZa1x4l+oY7hRbzJDE/azQa3bAAXkGUj+CQmdAgB8wPlS6FYdoT4fK3yA/Ewab7klvhre6JImpLXwUaWTegppi3PMR7DhvMFRjB29mkdHRwGmieNuSbPP/pMuNhgadwyWTfNGrUQ2JdCNE25FtU9VLgWsgRRVFAoOTSqTuT8wvK/ZKfc4BKJXPgX4Im/m/oEzveub7gGRW8UVIMY1r0SlSp0KXvTC1nXUg/Y6KI0w/1H3KtIZ03BuBz+pfP01N0kZb/fs+58Pr8W+TWrfwMAAP//M7rlfg==`,
},
},
}
func TestToMap(t *testing.T) {
t.Parallel()
for _, test := range allTests {
if got, want := test.MD.ToMap(), test.MD.entries; !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}
}
}
func TestFromMap(t *testing.T) {
t.Parallel()
for _, test := range allTests {
if got, want := FromMap(test.MD.entries), test.MD; !reflect.DeepEqual(got, want) {
t.Errorf("got %#v, want %#v", got, want)
}
}
}
func TestToXML(t *testing.T) {
t.Parallel()
for _, test := range allTests {
if got, want := test.MD.ToXML(), test.XML; got != want {
t.Errorf("got %v, want %v", got, want)
}
}
}
func TestFromXML(t *testing.T) {
t.Parallel()
for _, test := range allTests {
got, err := FromXML([]byte(test.XML))
if err != nil {
t.Errorf("%v FromXML failed: %v", test.XML, err)
}
if want := test.MD; !reflect.DeepEqual(got, want) {
t.Errorf("got %#v, want %#v", got, want)
}
// Add some garbage and make sure it fails.
bad := "<notclosed" + test.XML
if got, err := FromXML([]byte(bad)); got != nil || err == nil {
t.Errorf("%v FromXML should have failed: (%#v, %v)", bad, got, err)
}
}
}
func TestToBase64(t *testing.T) {
t.Parallel()
for _, test := range allTests {
got := test.MD.ToBase64()
found := false
for _, want := range test.B64 {
if got == want {
found = true
break
}
}
if !found {
t.Errorf("got %q, want one of %q", got, test.B64)
}
}
}
func TestFromBase64(t *testing.T) {
t.Parallel()
for _, test := range allTests {
for _, b64 := range test.B64 {
got, err := FromBase64([]byte(b64))
if err != nil {
t.Errorf("%v FromBase64 failed: %v", b64, err)
}
if want := test.MD; !reflect.DeepEqual(got, want) {
t.Errorf("got %#v, want %#v", got, want)
}
// Add some garbage and make sure it fails.
bad := "!@#$%^&*()_+" + b64
if got, err := FromBase64([]byte(bad)); got != nil || err == nil {
t.Errorf("%v FromBase64 should have failed: (%#v, %v)", bad, got, err)
}
}
}
}
func TestInsertLookup(t *testing.T) {
t.Parallel()
tests := []struct {
ID, Value, Old string
Map map[string]string
}{
{"A", "abc", "", map[string]string{"A": "abc"}},
{"B", "123", "", map[string]string{"A": "abc", "B": "123"}},
{"A", "xyz", "abc", map[string]string{"A": "xyz", "B": "123"}},
{"C", "s p a c e s", "", map[string]string{"A": "xyz", "B": "123", "C": "s p a c e s"}},
}
var x T
for _, test := range tests {
if got, want := x.Lookup(test.ID), test.Old; got != want {
t.Errorf("(%q, %q) Lookup got %q, want %q", test.ID, test.Value, got, want)
}
if got, want := x.Insert(test.ID, test.Value), test.Old; got != want {
t.Errorf("(%q, %q) Insert got %q, want %q", test.ID, test.Value, got, want)
}
if got, want := x.Lookup(test.ID), test.Value; got != want {
t.Errorf("(%q, %q) Lookup got %q, want %q", test.ID, test.Value, got, want)
}
// Add some leading and trailing spaces, which will be stripped.
value2 := "ZZ" + test.Value + "ZZ"
if got, want := x.Insert(test.ID, " \n\t"+value2+"\n\t "), test.Value; got != want {
t.Errorf("(%q, %q) Insert got %q, want %q", test.ID, value2, got, want)
}
if got, want := x.Lookup(test.ID), value2; got != want {
t.Errorf("(%q, %q) Lookup got %q, want %q", test.ID, value2, got, want)
}
// Set the value back.
if got, want := x.Insert(test.ID, test.Value), value2; got != want {
t.Errorf("(%q, %q) Insert got %q, want %q", test.ID, test.Value, got, want)
}
// Check the map form.
if got, want := x.ToMap(), test.Map; !reflect.DeepEqual(got, want) {
t.Errorf("(%q, %q) ToMap got %q, want %q", test.ID, test.Value, got, want)
}
}
}
func TestLDFlag(t *testing.T) {
t.Parallel()
for _, test := range allTests {
got := LDFlag(test.MD)
found := false
for _, b64 := range test.B64 {
want := "-X " + thisPkgPath + ".initBuiltIn=" + b64
if got == want {
found = true
break
}
}
if !found {
t.Errorf("got %q, want one of %v", got, test.B64)
}
}
}
// TestBuiltIn tests the package-level functions that operate on BuiltIn.
func TestBuiltIn(t *testing.T) {
t.Parallel()
const id, value1, value2 = "TestID", "testvalue1", "testvalue2"
if got, want := Lookup(id), ""; got != want {
t.Errorf("Lookup %s got %q, want %q", id, got, want)
}
if got, want := Insert(id, value1), ""; got != want {
t.Errorf("Insert %s got %q, want %q", id, got, want)
}
if got, want := Lookup(id), value1; got != want {
t.Errorf("Lookup %s got %q, want %q", id, got, want)
}
if got, want := Insert(id, value2), value1; got != want {
t.Errorf("Insert %s got %q, want %q", id, got, want)
}
wantMap := map[string]string{
id: value2,
"go.Arch": runtime.GOARCH,
"go.OS": runtime.GOOS,
"go.Version": runtime.Version(),
}
if got, want := ToMap(), wantMap; !reflect.DeepEqual(got, want) {
t.Errorf("got map %q, want %q", got, want)
}
if got, want := ToXML(), FromMap(wantMap).ToXML(); got != want {
t.Errorf("got xml %q, want %q", got, want)
}
if got, want := ToBase64(), FromMap(wantMap).ToBase64(); got != want {
t.Errorf("got base64 %q, want %q", got, want)
}
}
// TestInitAndFlag builds a test binary with some metadata, and invokes the
// -metadata flag to make sure it dumps the expected metadata.
func TestInitAndFlag(t *testing.T) {
t.Parallel()
// Run the test binary.
const id, value = "zzzTestID", "abcdefg"
x := FromMap(map[string]string{id: value})
cmdRun := exec.Command("go", "run", "-ldflags="+LDFlag(x), "./testdata/testbin.go", "-metadata")
outXML, err := cmdRun.CombinedOutput()
if err != nil {
t.Errorf("%v failed: %v\n%s", cmdRun.Args, err, outXML)
}
wantXML := `<metadata>
<md id="go.Arch">` + runtime.GOARCH + `</md>
<md id="go.OS">` + runtime.GOOS + `</md>
<md id="go.Version">` + runtime.Version() + `</md>
<md id="` + id + `">` + value + `</md>
</metadata>
`
if got, want := string(outXML), wantXML; got != want {
t.Errorf("got %q, want %q", got, want)
}
}