blob: e9cf79c40ed9b336c1064e073c6ee860588dd9ef [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 build
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"testing"
)
func makeTestManifestFile(t *testing.T) (string, map[string]string) {
f, err := ioutil.TempFile("", t.Name())
if err != nil {
t.Fatal(err)
}
defer f.Close()
wantPaths := map[string]string{
"a": "/somepath/a",
"1": "/somepath/b",
}
for k, v := range wantPaths {
_, err := fmt.Fprintf(f, "%s=%s\n", k, v)
if err != nil {
f.Close()
os.Remove(f.Name())
t.Fatal(err)
}
}
// write some junk
fmt.Fprint(f, "\na\n")
return f.Name(), wantPaths
}
func validateMapping(t *testing.T, m *Manifest, f map[string]string) {
if len(m.Paths) != len(f) {
t.Errorf("lengths differ: got %d, want %d", len(m.Paths), len(f))
}
for wantDest, wantSource := range f {
source, ok := m.Paths[wantDest]
if !ok {
t.Errorf("manifest is missing file %q", wantDest)
}
if source != wantSource {
t.Errorf("source: got %q, want %q", source, wantSource)
}
}
}
func makeTestFileDir(t *testing.T) (string, []string) {
d, err := ioutil.TempDir("", t.Name())
if err != nil {
t.Fatal(err)
}
files := []string{"a", "b", "dir/c"}
for _, f := range files {
path := filepath.Join(d, f)
os.MkdirAll(filepath.Dir(path), os.ModePerm)
f, err := os.Create(path)
if err != nil {
os.RemoveAll(d)
t.Fatal(err)
}
f.Close()
}
return d, files
}
func TestNewManifest_withManifestAndDirectory(t *testing.T) {
dir, wantFiles := makeTestFileDir(t)
defer os.RemoveAll(dir)
manifestFile, wantPaths := makeTestManifestFile(t)
defer os.Remove(manifestFile)
manifest, err := NewManifest([]string{manifestFile, dir})
if err != nil {
t.Fatal(err)
}
for _, f := range wantFiles {
wantPaths[f] = filepath.Join(dir, f)
}
validateMapping(t, manifest, wantPaths)
}
func TestNewManifest_withDirectory(t *testing.T) {
d, files := makeTestFileDir(t)
defer os.RemoveAll(d)
m, err := NewManifest([]string{d})
if err != nil {
t.Fatal(err)
}
if len(m.Paths) != len(files) {
t.Errorf("lengths differ: %v vs %v", m.Paths, files)
}
for _, f := range files {
source, ok := m.Paths[f]
if !ok {
t.Errorf("manifest is missing file %q", f)
continue
}
if want := filepath.Join(d, f); source != want {
t.Errorf("source: got %q, want %q", source, want)
}
}
}
func TestNewManifest_withManifest(t *testing.T) {
f, wantPaths := makeTestManifestFile(t)
defer os.Remove(f)
m, err := NewManifest([]string{f})
if err != nil {
t.Fatal(err)
}
validateMapping(t, m, wantPaths)
}
type manifestEntry struct {
packagePath string
filePath string
contents string
}
func makeTestManifest(t *testing.T, entries []manifestEntry) (error, string, string, func()) {
tmp, err := ioutil.TempDir("", t.Name())
if err != nil {
return err, "", "", nil
}
cleanup := func() {
os.RemoveAll(tmp)
}
defer func() {
if err != nil {
cleanup()
}
}()
manifestPath := filepath.Join(tmp, "test.manifest")
manifest, err := os.Create(manifestPath)
if err != nil {
return err, "", "", nil
}
defer manifest.Close()
for _, entry := range entries {
path := filepath.Join(tmp, entry.filePath)
if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
return err, "", "", nil
}
if err := ioutil.WriteFile(path, []byte(entry.contents), 0600); err != nil {
return err, "", "", nil
}
if _, err := fmt.Fprintf(manifest, "%s=%s\n", entry.packagePath, path); err != nil {
return err, "", "", nil
}
}
return nil, tmp, manifestPath, cleanup
}
func TestNewManifest_withManifest_withDuplicates(t *testing.T) {
err, tmp, manifestPath, cleanup := makeTestManifest(t, []manifestEntry{
manifestEntry{
packagePath: "bin/app1",
filePath: "app1/bin",
contents: "app1's unique binary",
},
manifestEntry{
packagePath: "bin/app2",
filePath: "app2/bin",
contents: "app2's unique binary",
},
manifestEntry{
packagePath: "lib/shared.so",
filePath: "app1/lib",
contents: "duplicate shared library",
},
manifestEntry{
packagePath: "lib/shared.so",
filePath: "app2/lib",
contents: "duplicate shared library",
},
})
if err != nil {
t.Fatal(err)
}
defer cleanup()
manifest, err := NewManifest([]string{manifestPath})
if err != nil {
t.Fatal(err)
}
validateMapping(t, manifest, map[string]string{
"bin/app1": filepath.Join(tmp, "app1/bin"),
"bin/app2": filepath.Join(tmp, "app2/bin"),
// first duplicate entry wins
"lib/shared.so": filepath.Join(tmp, "app1/lib"),
})
}
func TestNewManifest_withManifest_withDuplicatesWithUnEqualContent(t *testing.T) {
err, _, manifestPath, cleanup := makeTestManifest(t, []manifestEntry{
manifestEntry{
packagePath: "lib/shared.so",
filePath: "app1/lib",
contents: "duplicate shared library",
},
manifestEntry{
packagePath: "lib/shared.so",
filePath: "app2/lib",
contents: "duplicate shared library with different content",
},
})
if err != nil {
t.Fatal(err)
}
defer cleanup()
if m, err := NewManifest([]string{manifestPath}); err == nil {
t.Fatalf("should have thrown error, got %v:", m)
}
}
func TestManifestMeta(t *testing.T) {
m := &Manifest{
Paths: map[string]string{
"meta/package": "",
"meta/contents": "",
"alpha": "",
"beta": "",
},
}
if got, want := len(m.Meta()), 2; got != want {
t.Errorf("got %d, want %d", got, want)
}
for k := range m.Meta() {
if !strings.HasPrefix(k, "meta/") {
t.Errorf("found non-meta file in metas: %q", k)
}
}
}
func TestManifestContent(t *testing.T) {
m := &Manifest{
Paths: map[string]string{
"meta/package": "",
"meta/contents": "",
"alpha": "",
"beta": "",
},
}
if got, want := len(m.Meta()), 2; got != want {
t.Errorf("got %d, want %d", got, want)
}
for k := range m.Content() {
if strings.HasPrefix(k, "meta/") {
t.Errorf("found meta file in contents: %q", k)
}
}
}
func TestManifestSigningfiles(t *testing.T) {
m := &Manifest{
Paths: map[string]string{
"meta/package": "",
"meta/contents": "",
"meta/signature": "",
"alpha": "",
"beta": "",
},
}
want := []string{"meta/package", "meta/contents"}
sort.Strings(want)
got := m.SigningFiles()
if len(got) != len(want) {
t.Fatalf("got %v, want %v", got, want)
}
for i, w := range want {
g := got[i]
if g != w {
t.Errorf("got %q, want %q", g, w)
}
}
}