blob: 8182b44fe182e18f289ccfabd29fcb394534d11b [file] [log] [blame]
package packages_test
import (
"archive/tar"
"archive/zip"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"sort"
"testing"
"veyron.io/veyron/veyron2/services/mgmt/repository"
"veyron.io/veyron/veyron/services/mgmt/lib/packages"
)
func TestInstall(t *testing.T) {
workdir, err := ioutil.TempDir("", "packages-test-")
if err != nil {
t.Fatalf("ioutil.TempDir failed: %v", err)
}
defer os.RemoveAll(workdir)
srcdir := filepath.Join(workdir, "src")
dstdir := filepath.Join(workdir, "dst")
createFiles(t, srcdir)
zipfile := filepath.Join(workdir, "archivezip")
tarfile := filepath.Join(workdir, "archivetar")
tgzfile := filepath.Join(workdir, "archivetgz")
makeZip(t, zipfile, srcdir)
makeTar(t, tarfile, srcdir)
doGzip(t, tarfile, tgzfile)
binfile := filepath.Join(workdir, "binfile")
ioutil.WriteFile(binfile, []byte("This is a binary file"), os.FileMode(0644))
ioutil.WriteFile(binfile+".__info", []byte(`{"type":"application/octet-stream"}`), os.FileMode(0644))
expected := []string{
"a perm:700",
"a/b perm:700",
"a/b/xyzzy.txt perm:600",
"a/bar.txt perm:600",
"a/foo.txt perm:600",
}
for _, file := range []string{zipfile, tarfile, tgzfile} {
setupDstDir(t, dstdir)
if err := packages.Install(file, dstdir); err != nil {
t.Errorf("packages.Install failed for %q: %v", file, err)
}
files := scanDir(dstdir)
if !reflect.DeepEqual(files, expected) {
t.Errorf("unexpected result for %q: Got %q, want %q", file, files, expected)
}
}
setupDstDir(t, dstdir)
if err := packages.Install(binfile, dstdir); err == nil {
t.Errorf("expected packages.Install to fail %q", binfile)
}
}
func TestMediaInfo(t *testing.T) {
testcases := []struct {
filename string
expected repository.MediaInfo
}{
{"foo.zip", repository.MediaInfo{Type: "application/zip"}},
{"foo.ZIP", repository.MediaInfo{Type: "application/zip"}},
{"foo.tar", repository.MediaInfo{Type: "application/x-tar"}},
{"foo.TAR", repository.MediaInfo{Type: "application/x-tar"}},
{"foo.tgz", repository.MediaInfo{Type: "application/x-tar", Encoding: "gzip"}},
{"FOO.TAR.GZ", repository.MediaInfo{Type: "application/x-tar", Encoding: "gzip"}},
{"foo.tbz2", repository.MediaInfo{Type: "application/x-tar", Encoding: "bzip2"}},
{"foo.tar.bz2", repository.MediaInfo{Type: "application/x-tar", Encoding: "bzip2"}},
{"foo", repository.MediaInfo{Type: "application/octet-stream"}},
}
for _, tc := range testcases {
if got := packages.MediaInfoForFileName(tc.filename); !reflect.DeepEqual(got, tc.expected) {
t.Errorf("unexpected result for %q: Got %v, want %v", tc.filename, got, tc.expected)
}
}
}
func createFiles(t *testing.T, dir string) {
if err := os.Mkdir(dir, os.FileMode(0755)); err != nil {
t.Fatalf("os.Mkdir(%q) failed: %v", dir, err)
}
dirs := []string{"a", "a/b"}
for _, d := range dirs {
fullname := filepath.Join(dir, d)
if err := os.Mkdir(fullname, os.FileMode(0755)); err != nil {
t.Fatalf("os.Mkdir(%q) failed: %v", fullname, err)
}
}
files := []string{"a/foo.txt", "a/bar.txt", "a/b/xyzzy.txt"}
for _, f := range files {
fullname := filepath.Join(dir, f)
if err := ioutil.WriteFile(fullname, []byte(f), os.FileMode(0644)); err != nil {
t.Fatalf("ioutil.WriteFile(%q) failed: %v", fullname, err)
}
}
}
func makeZip(t *testing.T, zipfile, dir string) {
z, err := os.OpenFile(zipfile, os.O_CREATE|os.O_WRONLY, os.FileMode(0644))
if err != nil {
t.Fatalf("os.OpenFile(%q) failed: %v", zipfile, err)
}
defer z.Close()
w := zip.NewWriter(z)
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
t.Fatalf("Walk(%q) error: %v", dir, err)
}
if dir == path {
return nil
}
fh, err := zip.FileInfoHeader(info)
if err != nil {
t.Fatalf("FileInfoHeader failed: %v", err)
}
fh.Name, _ = filepath.Rel(dir, path)
hdr, err := w.CreateHeader(fh)
if err != nil {
t.Fatalf("w.CreateHeader failed: %v", err)
}
if !info.IsDir() {
content, err := ioutil.ReadFile(path)
if err != nil {
t.Fatalf("ioutil.ReadFile(%q) failed: %v", path, err)
}
if _, err = hdr.Write(content); err != nil {
t.Fatalf("hdr.Write(%q) failed: %v", content, err)
}
}
return nil
})
if err := w.Close(); err != nil {
t.Fatalf("w.Close() failed: %v", err)
}
if err := ioutil.WriteFile(zipfile+".__info", []byte(`{"type":"application/zip"}`), os.FileMode(0644)); err != nil {
t.Fatalf("ioutil.WriteFile() failed: %v", err)
}
}
func makeTar(t *testing.T, tarfile, dir string) {
tf, err := os.OpenFile(tarfile, os.O_CREATE|os.O_WRONLY, os.FileMode(0644))
if err != nil {
t.Fatalf("os.OpenFile(%q) failed: %v", tarfile, err)
}
defer tf.Close()
tw := tar.NewWriter(tf)
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
t.Fatalf("Walk(%q) error: %v", dir, err)
}
if dir == path {
return nil
}
hdr, err := tar.FileInfoHeader(info, "")
if err != nil {
t.Fatalf("tar.FileInfoHeader failed: %v", err)
}
hdr.Name, _ = filepath.Rel(dir, path)
if err := tw.WriteHeader(hdr); err != nil {
t.Fatalf("tw.WriteHeader failed: %v", err)
}
if !info.IsDir() {
content, err := ioutil.ReadFile(path)
if err != nil {
t.Fatalf("ioutil.ReadFile(%q) failed: %v", path, err)
}
if _, err := tw.Write(content); err != nil {
t.Fatalf("tw.Write failed: %v", err)
}
}
return nil
})
if err := tw.Close(); err != nil {
t.Fatalf("tw.Close failed: %v", err)
}
if err := ioutil.WriteFile(tarfile+".__info", []byte(`{"type":"application/x-tar"}`), os.FileMode(0644)); err != nil {
t.Fatalf("ioutil.WriteFile() failed: %v", err)
}
}
func doGzip(t *testing.T, infile, outfile string) {
in, err := os.Open(infile)
if err != nil {
t.Fatalf("os.Open(%q) failed: %v", infile, err)
}
defer in.Close()
out, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY, os.FileMode(0644))
if err != nil {
t.Fatalf("os.OpenFile(%q) failed: %v", outfile, err)
}
defer out.Close()
writer := gzip.NewWriter(out)
defer writer.Close()
if _, err := io.Copy(writer, in); err != nil {
t.Fatalf("io.Copy() failed: %v", err)
}
info, err := packages.LoadMediaInfo(infile)
if err != nil {
t.Fatalf("LoadMediaInfo(%q) failed: %v", infile, err)
}
info.Encoding = "gzip"
if err := packages.SaveMediaInfo(outfile, info); err != nil {
t.Fatalf("SaveMediaInfo(%v) failed: %v", outfile, err)
}
}
func scanDir(root string) []string {
files := []string{}
filepath.Walk(root, func(path string, info os.FileInfo, _ error) error {
if root == path {
return nil
}
rel, _ := filepath.Rel(root, path)
perm := info.Mode() & 0700
files = append(files, fmt.Sprintf("%s perm:%o", rel, perm))
return nil
})
sort.Strings(files)
return files
}
func setupDstDir(t *testing.T, dst string) {
if err := os.RemoveAll(dst); err != nil {
t.Fatalf("os.RemoveAll(%q) failed: %v", dst, err)
}
if err := os.Mkdir(dst, os.FileMode(0755)); err != nil {
t.Fatalf("os.Mkdir(%q) failed: %v", dst, err)
}
}