blob: 8bbcf1a19cb677402d3dd9c56f85dd49e0d43af4 [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 main
import (
"bytes"
"fmt"
"os"
"path/filepath"
"testing"
"v.io/jiri/jiri"
"v.io/jiri/jiritest"
"v.io/jiri/project"
"v.io/jiri/tool"
)
func createLabelDir(t *testing.T, jirix *jiri.X, snapshotDir, name string, snapshots []string) {
s := jirix.NewSeq()
labelDir, perm := filepath.Join(snapshotDir, "labels", name), os.FileMode(0700)
if err := s.MkdirAll(labelDir, perm).Done(); err != nil {
t.Fatalf("MkdirAll(%v, %v) failed: %v", labelDir, perm, err)
}
for i, snapshot := range snapshots {
path := filepath.Join(labelDir, snapshot)
_, err := os.Create(path)
if err != nil {
t.Fatalf("%v", err)
}
if i == 0 {
symlinkPath := filepath.Join(snapshotDir, name)
if err := s.Symlink(path, symlinkPath).Done(); err != nil {
t.Fatalf("Symlink(%v, %v) failed: %v", path, symlinkPath, err)
}
}
}
}
func generateOutput(labels []label) string {
output := ""
for _, label := range labels {
output += fmt.Sprintf("snapshots of label %q:\n", label.name)
for _, snapshot := range label.snapshots {
output += fmt.Sprintf(" %v\n", snapshot)
}
}
return output
}
type config struct {
remote bool
dir string
}
type label struct {
name string
snapshots []string
}
func TestList(t *testing.T) {
fake, cleanup := jiritest.NewFakeJiriRoot(t)
defer cleanup()
remoteSnapshotDir := fake.X.RemoteSnapshotDir()
localSnapshotDir := fake.X.LocalSnapshotDir()
// Create a test suite.
tests := []config{
config{
remote: false,
dir: localSnapshotDir,
},
config{
remote: true,
dir: remoteSnapshotDir,
},
}
labels := []label{
label{
name: "beta",
snapshots: []string{"beta-1", "beta-2", "beta-3"},
},
label{
name: "stable",
snapshots: []string{"stable-1", "stable-2", "stable-3"},
},
}
for _, test := range tests {
remoteFlag = test.remote
// Create the snapshots directory and populate it with the
// data specified by the test suite.
for _, label := range labels {
createLabelDir(t, fake.X, test.dir, label.name, label.snapshots)
}
// Check that running "jiri snapshot list" with no arguments
// returns the expected output.
var stdout bytes.Buffer
fake.X.Context = tool.NewContext(tool.ContextOpts{Stdout: &stdout})
if err := runSnapshotList(fake.X, nil); err != nil {
t.Fatalf("%v", err)
}
got, want := stdout.String(), generateOutput(labels)
if got != want {
t.Fatalf("unexpected output:\ngot\n%v\nwant\n%v\n", got, want)
}
// Check that running "jiri snapshot list" with one argument
// returns the expected output.
stdout.Reset()
if err := runSnapshotList(fake.X, []string{"stable"}); err != nil {
t.Fatalf("%v", err)
}
got, want = stdout.String(), generateOutput(labels[1:])
if got != want {
t.Fatalf("unexpected output:\ngot\n%v\nwant\n%v\n", got, want)
}
// Check that running "jiri snapshot list" with
// multiple arguments returns the expected output.
stdout.Reset()
if err := runSnapshotList(fake.X, []string{"beta", "stable"}); err != nil {
t.Fatalf("%v", err)
}
got, want = stdout.String(), generateOutput(labels)
if got != want {
t.Fatalf("unexpected output:\ngot\n%v\nwant\n%v\n", got, want)
}
}
}
func checkReadme(t *testing.T, jirix *jiri.X, project, message string) {
s := jirix.NewSeq()
if _, err := s.Stat(project); err != nil {
t.Fatalf("%v", err)
}
readmeFile := filepath.Join(project, "README")
data, err := s.ReadFile(readmeFile)
if err != nil {
t.Fatalf("%v", err)
}
if got, want := data, []byte(message); bytes.Compare(got, want) != 0 {
t.Fatalf("unexpected content %v:\ngot\n%s\nwant\n%s\n", project, got, want)
}
}
func localProjectName(i int) string {
return "test-local-project-" + fmt.Sprintf("%d", i+1)
}
func remoteProjectName(i int) string {
return "test-remote-project-" + fmt.Sprintf("%d", i+1)
}
func writeReadme(t *testing.T, jirix *jiri.X, projectDir, message string) {
s := jirix.NewSeq()
path, perm := filepath.Join(projectDir, "README"), os.FileMode(0644)
if err := s.WriteFile(path, []byte(message), perm).Done(); err != nil {
t.Fatalf("%v", err)
}
cwd, err := os.Getwd()
if err != nil {
t.Fatalf("%v", err)
}
defer jirix.NewSeq().Chdir(cwd)
if err := s.Chdir(projectDir).Done(); err != nil {
t.Fatalf("%v", err)
}
if err := jirix.Git().CommitFile(path, "creating README"); err != nil {
t.Fatalf("%v", err)
}
}
func TestCreate(t *testing.T) {
fake, cleanup := jiritest.NewFakeJiriRoot(t)
defer cleanup()
s := fake.X.NewSeq()
// Setup the initial remote and local projects.
numProjects, remoteProjects := 2, []string{}
for i := 0; i < numProjects; i++ {
if err := fake.CreateRemoteProject(remoteProjectName(i)); err != nil {
t.Fatalf("%v", err)
}
if err := fake.AddProject(project.Project{
Name: remoteProjectName(i),
Path: localProjectName(i),
Remote: fake.Projects[remoteProjectName(i)],
}); err != nil {
t.Fatalf("%v", err)
}
}
// Create initial commits in the remote projects and use
// UpdateUniverse() to mirror them locally.
for i := 0; i < numProjects; i++ {
writeReadme(t, fake.X, fake.Projects[remoteProjectName(i)], "revision 1")
}
if err := project.UpdateUniverse(fake.X, true); err != nil {
t.Fatalf("%v", err)
}
// Create a local snapshot.
var stdout bytes.Buffer
fake.X.Context = tool.NewContext(tool.ContextOpts{Stdout: &stdout})
remoteFlag = false
if err := runSnapshotCreate(fake.X, []string{"test-local"}); err != nil {
t.Fatalf("%v", err)
}
// Remove the local project repositories.
for i, _ := range remoteProjects {
localProject := filepath.Join(fake.X.Root, localProjectName(i))
if err := s.RemoveAll(localProject).Done(); err != nil {
t.Fatalf("%v", err)
}
}
// Check that invoking the UpdateUniverse() with the local
// snapshot restores the local repositories.
snapshotDir := fake.X.LocalSnapshotDir()
snapshotFile := filepath.Join(snapshotDir, "test-local")
localX := fake.X.Clone(tool.ContextOpts{
Manifest: &snapshotFile,
})
if err := project.UpdateUniverse(localX, true); err != nil {
t.Fatalf("%v", err)
}
for i, _ := range remoteProjects {
localProject := filepath.Join(fake.X.Root, localProjectName(i))
checkReadme(t, fake.X, localProject, "revision 1")
}
// Create a remote snapshot.
remoteFlag = true
fake.EnableRemoteManifestPush()
if err := runSnapshotCreate(fake.X, []string{"test-remote"}); err != nil {
t.Fatalf("%v", err)
}
// Remove the local project repositories.
for i, _ := range remoteProjects {
localProject := filepath.Join(fake.X.Root, localProjectName(i))
if err := s.RemoveAll(localProject).Done(); err != nil {
t.Fatalf("%v", err)
}
}
// Check that invoking the UpdateUniverse() with the remote snapshot
// restores the local repositories.
manifest := "snapshot/test-remote"
remoteX := fake.X.Clone(tool.ContextOpts{
Manifest: &manifest,
})
if err := project.UpdateUniverse(remoteX, true); err != nil {
t.Fatalf("%v", err)
}
for i, _ := range remoteProjects {
localProject := filepath.Join(fake.X.Root, localProjectName(i))
checkReadme(t, fake.X, localProject, "revision 1")
}
}