func TestList(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() dir, sh := buildInstallers(t), gosh.NewShell(t) sh.Vars["JIRI_ROOT"] = fake.X.Root sh.Vars["PATH"] = envvar.PrependUniqueToken(os.Getenv("PATH"), ":", dir) run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg") if got, want := run(sh, dir, "jiri", "profile", "list", "--target=arch-os"), "i1:eg, i2:eg\n"; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := run(sh, dir, "jiri", "profile", "list"), "i1:eg, i2:eg\n"; got != want { t.Errorf("got %v, want %v", got, want) } for _, arg := range []string{"", "--info=SchemaVersion"} { sh.ContinueOnError = true sh.Err = nil got := run(sh, dir, "jiri", "profile", "list", "--target=no-suchtarget", arg) if sh.Err == nil { t.Errorf("expected an error for: jiri profile list --target=no-suchtarget %s", arg) } if want := "ERROR: no matching targets for no-suchtarget@\n"; got != want { t.Errorf("got %v, want %v", got, want) } } }
func TestReader(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() rd, err := profilesreader.NewReader(fake.X, profilesreader.UseProfiles, filepath.Join("testdata", "m2.xml")) if err != nil { t.Fatal(err) } rd.Vars = envvar.VarsFromOS() rd.Delete("CGO_CFLAGS") native, err := profiles.NewTarget("amd64-darwin", "") if err != nil { t.Fatal(err) } rd.MergeEnvFromProfiles(profilesreader.JiriMergePolicies(), native, "test::go", "test::syncbase") if got, want := rd.Get("CGO_CFLAGS"), "-IX -IY -IA -IB"; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := rd.DebugString(), "Root: "+fake.X.Root+` Path: testdata/m2.xml test:go: [email protected] dir: --env= envvars:[CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin GOROOT=/goroot CGO_CFLAGS=-IX -IY] test:syncbase: amd64-darwin@1 dir: --env= envvars:[CGO_CFLAGS=-IA -IB CGO_LDFLAGS=-LA -LB] `; got != want { t.Errorf("got %v, want %v", got, want) } }
// Test using a fake jiri root. func TestJiriFakeRoot(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() profilesDBDir := filepath.Join(fake.X.Root, jiri.ProfilesDBDir) pdb := profiles.NewDB() t1, err := profiles.NewTarget("cpu1-os1@1", "A=B,C=D") if err != nil { t.Fatal(err) } pdb.InstallProfile("test", "b", "") if err := pdb.AddProfileTarget("test", "b", t1); err != nil { t.Fatal(err) } if err := pdb.Write(fake.X, "test", profilesDBDir); err != nil { t.Fatal(err) } rd, err := profilesreader.NewReader(fake.X, profilesreader.UseProfiles, profilesDBDir) if err != nil { t.Fatal(err) } if got, want := rd.ProfileNames(), []string{"test:b"}; !reflect.DeepEqual(got, want) { t.Errorf("got %v, want %v", got, want) } dir, sh := buildJiri(t), gosh.NewShell(t) sh.Vars["JIRI_ROOT"] = fake.X.Root sh.Vars["PATH"] = envvar.PrependUniqueToken(sh.Vars["PATH"], ":", dir) run(sh, dir, "jiri", "profile", "list", "-v") }
func TestReadingV3AndV4(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() for i, c := range []struct { filename, prefix, variable string version profiles.Version }{ {"v3.xml", "", "", profiles.V3}, {"v4.xml", fake.X.Root, "${JIRI_ROOT}", profiles.V4}, } { pdb := profiles.NewDB() err := pdb.Read(fake.X, filepath.Join("testdata", c.filename)) if err != nil { t.Fatal(err) } if got, want := pdb.SchemaVersion(), c.version; got != want { t.Errorf("%d: got %v, want %v", i, got, want) } target, err := profiles.NewTarget("cpu1-os1@1", "") if err != nil { t.Fatal(err) } p := pdb.LookupProfile("", "a") // We need to expand the variable here for a V4 profile if we want // to get the full absolute path. if got, want := p.Root(), c.variable+"/an/absolute/root"; got != want { t.Errorf("%d: got %v, want %v", i, got, want) } lt := pdb.LookupProfileTarget("", "a", target) if got, want := lt.InstallationDir, c.variable+"/an/absolute/dir"; got != want { t.Errorf("%d: got %v, want %v", i, got, want) } } }
func TestManagerInstallUninstall(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() dir, sh := buildInstallers(t), gosh.NewShell(t) createProfilesDB(t, fake.X) sh.Vars["JIRI_ROOT"] = fake.X.Root sh.Vars["PATH"] = envvar.PrependUniqueToken(sh.Vars["PATH"], ":", dir) run(sh, dir, "jiri", "profile", "list", "-v") i1 := filepath.Join(fake.X.Root, ".jiri_root/profile_db/i1") i2 := filepath.Join(fake.X.Root, ".jiri_root/profile_db/i2") run(sh, dir, "jiri", "profile", "install", "--target=arch-os", "i1:eg", "i2:eg") for _, installer := range []string{"i1", "i2"} { tdir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir, installer, "eg", "arch_os") contains(t, filepath.Join(tdir, "version"), "3") contains(t, filepath.Join(tdir, "3"), "3") } cmpFiles(t, i1, filepath.Join("testdata", "i1a.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2a.xml")) run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg") // Installs are idempotent. run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg") for _, installer := range []string{"i1", "i2"} { tdir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir, installer, "eg", "arch_os") contains(t, filepath.Join(tdir, "version"), "2") contains(t, filepath.Join(tdir, "3"), "3") contains(t, filepath.Join(tdir, "2"), "2") } cmpFiles(t, i1, filepath.Join("testdata", "i1b.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2b.xml")) run(sh, dir, "jiri", "profile", "uninstall", "--target=arch-os@2", "i1:eg", "i2:eg") for _, installer := range []string{"i1", "i2"} { tdir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir, installer, "eg", "arch_os") contains(t, filepath.Join(tdir, "version"), "2") contains(t, filepath.Join(tdir, "3"), "3") if got, want := exists(filepath.Join(tdir, "2")), false; got != want { t.Errorf("%s: got %v, want %v", filepath.Join(tdir, "2"), got, want) } } cmpFiles(t, i1, filepath.Join("testdata", "i1c.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2c.xml")) // Put v2 back. run(sh, dir, "jiri", "profile", "list", "-v") run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg") cmpFiles(t, i1, filepath.Join("testdata", "i1b.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2b.xml")) }
func TestGetSnapshotDir(t *testing.T) { resetFlags() defer resetFlags() fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() // With all flags at default values, snapshot dir should be default. resetFlags() got, err := getSnapshotDir(fake.X) if err != nil { t.Fatalf("getSnapshotDir() failed: %v\n", err) } if want := filepath.Join(fake.X.Root, defaultSnapshotDir); got != want { t.Errorf("unexpected snapshot dir: got %v want %v", got, want) } // With dir flag set to absolute path, snapshot dir should be value of dir // flag. resetFlags() tempDir, err := fake.X.NewSeq().TempDir("", "") if err != nil { t.Fatalf("TempDir() failed: %v", err) } defer fake.X.NewSeq().RemoveAll(tempDir).Done() snapshotDirFlag = tempDir got, err = getSnapshotDir(fake.X) if err != nil { t.Fatalf("getSnapshotDir() failed: %v\n", err) } if want := snapshotDirFlag; got != want { t.Errorf("unexpected snapshot dir: got %v want %v", got, want) } // With dir flag set to relative path, snapshot dir should absolute path // rooted at current working dir. resetFlags() snapshotDirFlag = "some/relative/path" cwd, err := os.Getwd() if err != nil { t.Fatalf("os.Getwd() failed: %v", err) } defer fake.X.NewSeq().RemoveAll(filepath.Join(cwd, "some")) got, err = getSnapshotDir(fake.X) if err != nil { t.Fatalf("getSnapshotDir() failed: %v\n", err) } if want := filepath.Join(cwd, snapshotDirFlag); got != want { t.Errorf("unexpected snapshot dir: got %v want %v", got, want) } }
func TestRemoteImportCycle(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() // Set up two remote manifest projects, remote1 and remote1. if err := fake.CreateRemoteProject("remote1"); err != nil { t.Fatal(err) } if err := fake.CreateRemoteProject("remote2"); err != nil { t.Fatal(err) } remote1 := fake.Projects["remote1"] remote2 := fake.Projects["remote2"] fileA, fileB := filepath.Join(remote1, "A"), filepath.Join(remote2, "B") // Set up the cycle .jiri_manifest -> remote1+A -> remote2+B -> remote1+A jiriManifest := project.Manifest{ Imports: []project.Import{ {Manifest: "A", Name: "n1", Remote: remote1}, }, } manifestA := project.Manifest{ Imports: []project.Import{ {Manifest: "B", Name: "n2", Remote: remote2}, }, } manifestB := project.Manifest{ Imports: []project.Import{ {Manifest: "A", Name: "n3", Remote: remote1}, }, } if err := jiriManifest.ToFile(fake.X, fake.X.JiriManifestFile()); err != nil { t.Fatal(err) } if err := manifestA.ToFile(fake.X, fileA); err != nil { t.Fatal(err) } if err := manifestB.ToFile(fake.X, fileB); err != nil { t.Fatal(err) } commitFile(t, fake.X, remote1, fileA, "commit A") commitFile(t, fake.X, remote2, fileB, "commit B") // The update should complain about the cycle. err := project.UpdateUniverse(fake.X, false) if got, want := fmt.Sprint(err), "import cycle detected in remote manifest imports"; !strings.Contains(got, want) { t.Errorf("got error %v, want substr %v", got, want) } }
func TestManagerUpdate(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() dir, sh := buildInstallers(t), gosh.NewShell(t) createProfilesDB(t, fake.X) sh.Vars["JIRI_ROOT"] = fake.X.Root sh.Vars["PATH"] = envvar.PrependUniqueToken(sh.Vars["PATH"], ":", dir) i1 := filepath.Join(fake.X.ProfilesDBDir(), "i1") i2 := filepath.Join(fake.X.ProfilesDBDir(), "i2") run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg", "i2:eg") cmpFiles(t, i1, filepath.Join("testdata", "i1d.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2d.xml")) run(sh, dir, "jiri", "profile", "update") cmpFiles(t, i1, filepath.Join("testdata", "i1e.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2e.xml")) run(sh, dir, "jiri", "profile", "cleanup", "-gc") cmpFiles(t, i1, filepath.Join("testdata", "i1f.xml")) cmpFiles(t, i2, filepath.Join("testdata", "i2f.xml")) run(sh, dir, "jiri", "profile", "cleanup", "-rm-all") profiledir := filepath.Join(fake.X.Root, jiri.ProfilesRootDir) for _, dir := range []string{ fake.X.ProfilesDBDir(), filepath.Join(profiledir, "i1"), filepath.Join(profiledir, "i2"), } { _, err := os.Stat(dir) if !os.IsNotExist(err) { t.Errorf("%v still exists: %v", dir, err) } } // Start over, make sure update is idempotent. createProfilesDB(t, fake.X) run(sh, dir, "jiri", "profile", "install", "--target=arch-os@2", "i1:eg") run(sh, dir, "jiri", "profile", "update") run(sh, dir, "jiri", "profile", "update") cmpFiles(t, i1, filepath.Join("testdata", "i1g.xml")) run(sh, dir, "jiri", "profile", "install", "--target=arch-os@4", "i1:eg") run(sh, dir, "jiri", "profile", "update") cmpFiles(t, i1, filepath.Join("testdata", "i1h.xml")) }
func TestManagerAvailable(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() dir, sh := buildInstallers(t), gosh.NewShell(t) createProfilesDB(t, fake.X) sh.Vars["JIRI_ROOT"] = fake.X.Root sh.Vars["PATH"] = envvar.PrependUniqueToken(sh.Vars["PATH"], ":", dir) stdout := run(sh, dir, "jiri", "profile", "available", "-v") for _, installer := range []string{"i1", "i2"} { re := regexp.MustCompile("Available Subcommands:.*profile-" + installer + ".*\n") if got := stdout; !re.MatchString(got) { t.Errorf("%v does not match %v\n", got, re.String()) } if got, want := stdout, installer+":eg"; !strings.Contains(got, want) { t.Errorf("%v does not contain %v\n", got, want) } } }
func TestEnvFromTarget(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() pdb := profiles.NewDB() pdb.InstallProfile("test", "a", "root") pdb.InstallProfile("test", "b", "root") t1, t2 := &profiles.Target{}, &profiles.Target{} t1.Set("cpu1-os1@1") t1.Env.Set("A=B C=D,B=C Z=Z") t2.Set("cpu1-os1@1") t2.Env.Set("A=Z,B=Z,Z=Z1") pdb.AddProfileTarget("test", "a", *t1) pdb.AddProfileTarget("test", "b", *t2) pdb.Write(fake.X, "test", "profile-manifest") filename := filepath.Join(fake.X.Root, "profile-manifest") if err := pdb.Write(fake.X, "test", filename); err != nil { t.Fatal(err) } rd, err := profilesreader.NewReader(fake.X, profilesreader.UseProfiles, filename) if err != nil { t.Fatal(err) } rd.Vars = envvar.VarsFromSlice([]string{}) t1Target, err := profiles.NewTarget("cpu1-os1@1", "") if err != nil { t.Fatal(err) } rd.MergeEnvFromProfiles(map[string]profilesreader.MergePolicy{ "A": profilesreader.AppendFlag, "B": profilesreader.UseLast, "Z": profilesreader.IgnoreBaseUseLast}, t1Target, "test::a", "test::b") vars := rd.ToMap() if got, want := len(vars), 3; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := rd.Get("A"), "B C=D Z"; got != want { t.Errorf("got %v, want %v", got, want) } if got, want := rd.Get("B"), "Z"; got != want { t.Errorf("got %v, want %v", got, want) } }
// TestCreatePushRemote checks that creating a snapshot with the -push-remote // flag causes the snapshot to be committed and pushed upstream. func TestCreatePushRemote(t *testing.T) { resetFlags() defer resetFlags() fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() fake.EnableRemoteManifestPush() defer fake.DisableRemoteManifestPush() manifestDir := filepath.Join(fake.X.Root, "manifest") snapshotDir := filepath.Join(manifestDir, "snapshot") label := "test" git := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(manifestDir)) commitCount, err := git.CountCommits("master", "") if err != nil { t.Fatalf("git.CountCommits(\"master\", \"\") failed: %v", err) } // Create snapshot with -push-remote flag set to true. snapshotDirFlag = snapshotDir pushRemoteFlag = true if err := runSnapshotCreate(fake.X, []string{label}); err != nil { t.Fatalf("%v", err) } // Check that repo has one new commit. newCommitCount, err := git.CountCommits("master", "") if err != nil { t.Fatalf("git.CountCommits(\"master\", \"\") failed: %v", err) } if got, want := newCommitCount, commitCount+1; got != want { t.Errorf("unexpected commit count: got %v want %v", got, want) } // Check that new label is commited. labelFile := filepath.Join(snapshotDir, "labels", label) if !git.IsFileCommitted(labelFile) { t.Errorf("expected file %v to be committed but it was not", labelFile) } }
// setupTest creates a setup for testing the review tool. func setupTest(t *testing.T, installHook bool) (fake *jiritest.FakeJiriRoot, repoPath, originPath, gerritPath string, cleanup func()) { oldWD, err := os.Getwd() if err != nil { t.Fatalf("Getwd() failed: %v", err) } var cleanupFake func() if fake, cleanupFake = jiritest.NewFakeJiriRoot(t); err != nil { t.Fatalf("%v", err) } repoPath, originPath, gerritPath = createTestRepos(t, fake.X) if installHook == true { for _, path := range []string{repoPath, originPath, gerritPath} { installCommitMsgHook(t, fake.X, path) } } chdir(t, fake.X, repoPath) cleanup = func() { chdir(t, fake.X, oldWD) cleanupFake() } return }
// setupUniverse creates a fake jiri root with 3 remote projects. Each project // has a README with text "initial readme". func setupUniverse(t *testing.T) ([]project.Project, *jiritest.FakeJiriRoot, func()) { fake, cleanup := jiritest.NewFakeJiriRoot(t) success := false defer func() { if !success { cleanup() } }() // Create some projects and add them to the remote manifest. numProjects := 3 localProjects := []project.Project{} for i := 0; i < numProjects; i++ { name := projectName(i) path := fmt.Sprintf("path-%d", i) if err := fake.CreateRemoteProject(name); err != nil { t.Fatal(err) } p := project.Project{ Name: name, Path: filepath.Join(fake.X.Root, path), Remote: fake.Projects[name], } localProjects = append(localProjects, p) if err := fake.AddProject(p); err != nil { t.Fatal(err) } } // Create initial commit in each repo. for _, remoteProjectDir := range fake.Projects { writeReadme(t, fake.X, remoteProjectDir, "initial readme") } success = true return localProjects, fake, cleanup }
func TestRunP(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() projects := addProjects(t, fake) dir, sh := buildJiri(t), gosh.NewShell(t) if got, want := len(projects), 5; got != want { t.Errorf("got %v, want %v", got, want) } cwd, err := os.Getwd() if err != nil { t.Fatal(err) } defer os.Chdir(cwd) chdir := func(dir string) { if err := os.Chdir(dir); err != nil { t.Fatal(err) } } manifestKey := strings.Replace(string(projects[0].Key()), "r.a", "manifest", -1) keys := []string{manifestKey} for _, p := range projects { keys = append(keys, string(p.Key())) } chdir(projects[0].Path) got := run(sh, dir, "jiri", "runp", "--show-name-prefix", "-v", "echo") hdr := "Project Names: manifest r.a r.b r.c r.t1 r.t2\n" hdr += "Project Keys: " + strings.Join(keys, " ") + "\n" if want := hdr + "manifest: \nr.a: \nr.b: \nr.c: \nr.t1: \nr.t2:"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "-v", "--interactive=false", "basename", "$(", "jiri", "project", "info", "-f", "{{.Project.Path}}", ")") if want := hdr + "manifest\nr.a\nr.b\nr.c\nr.t1\nr.t2"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--interactive=false", "git", "rev-parse", "--abbrev-ref", "HEAD") if want := "master\nmaster\nmaster\nmaster\nmaster\nmaster"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "-interactive=false", "--show-name-prefix=true", "git", "rev-parse", "--abbrev-ref", "HEAD") if want := "manifest: master\nr.a: master\nr.b: master\nr.c: master\nr.t1: master\nr.t2: master"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--interactive=false", "--show-key-prefix=true", "git", "rev-parse", "--abbrev-ref", "HEAD") if want := strings.Join(keys, ": master\n") + ": master"; got != want { t.Errorf("got %v, want %v", got, want) } uncollated := run(sh, dir, "jiri", "runp", "--interactive=false", "--collate-stdout=false", "--show-name-prefix=true", "git", "rev-parse", "--abbrev-ref", "HEAD") split := strings.Split(uncollated, "\n") sort.Strings(split) got = strings.TrimSpace(strings.Join(split, "\n")) if want := "manifest: master\nr.a: master\nr.b: master\nr.c: master\nr.t1: master\nr.t2: master"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--show-name-prefix", "--projects=r.t[12]", "echo") if want := "r.t1: \nr.t2:"; got != want { t.Errorf("got %v, want %v", got, want) } rb := projects[1].Path rc := projects[2].Path t1 := projects[3].Path s := fake.X.NewSeq() newfile := func(dir, file string) { testfile := filepath.Join(dir, file) _, err := s.Create(testfile) if err != nil { t.Errorf("failed to create %s: %v", testfile, err) } } git := func(dir string) *gitutil.Git { return gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir)) } newfile(rb, "untracked.go") got = run(sh, dir, "jiri", "runp", "--has-untracked", "--show-name-prefix", "echo") if want := "r.b:"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--has-untracked=false", "--show-name-prefix", "echo") if want := "manifest: \nr.a: \nr.c: \nr.t1: \nr.t2:"; got != want { t.Errorf("got %v, want %v", got, want) } newfile(rc, "uncommitted.go") if err := git(rc).Add("uncommitted.go"); err != nil { t.Error(err) } got = run(sh, dir, "jiri", "runp", "--has-uncommitted", "--show-name-prefix", "echo") if want := "r.c:"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--has-uncommitted=false", "--show-name-prefix", "echo") if want := "manifest: \nr.a: \nr.b: \nr.t1: \nr.t2:"; got != want { t.Errorf("got %v, want %v", got, want) } // test ordering of has-<x> flags newfile(rc, "untracked.go") got = run(sh, dir, "jiri", "runp", "--has-untracked", "--has-uncommitted", "--show-name-prefix", "echo") if want := "r.c:"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--has-uncommitted", "--has-untracked", "--show-name-prefix", "echo") if want := "r.c:"; got != want { t.Errorf("got %v, want %v", got, want) } git(rb).CreateAndCheckoutBranch("a1") git(rb).CreateAndCheckoutBranch("b2") git(rc).CreateAndCheckoutBranch("b2") git(t1).CreateAndCheckoutBranch("a1") chdir(rc) // Just the projects with branch b2. got = run(sh, dir, "jiri", "runp", "--show-name-prefix", "echo") if want := "r.b: \nr.c:"; got != want { t.Errorf("got %v, want %v", got, want) } // All projects since --projects takes precendence over branches. got = run(sh, dir, "jiri", "runp", "--projects=.*", "--show-name-prefix", "echo") if want := "manifest: \nr.a: \nr.b: \nr.c: \nr.t1: \nr.t2:"; got != want { t.Errorf("got %v, want %v", got, want) } if err := s.MkdirAll(filepath.Join(rb, ".jiri", "a1"), os.FileMode(0755)).Done(); err != nil { t.Fatal(err) } newfile(rb, filepath.Join(".jiri", "a1", ".gerrit_commit_message")) git(rb).CheckoutBranch("a1") git(t1).CheckoutBranch("a1") chdir(t1) got = run(sh, dir, "jiri", "runp", "--has-gerrit-message", "--show-name-prefix", "echo") if want := "r.b:"; got != want { t.Errorf("got %v, want %v", got, want) } got = run(sh, dir, "jiri", "runp", "--has-gerrit-message=false", "--show-name-prefix", "echo") if want := "r.t1:"; got != want { t.Errorf("got %v, want %v", got, want) } }
// TestCreate tests creating and checking out a snapshot. func TestCreate(t *testing.T) { resetFlags() defer resetFlags() 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 snapshot. var stdout bytes.Buffer fake.X.Context = tool.NewContext(tool.ContextOpts{Stdout: &stdout}) 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 snapshot restores the // local repositories. snapshotDir := filepath.Join(fake.X.Root, defaultSnapshotDir) 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") } }
func TestList(t *testing.T) { resetFlags() fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() snapshotDir1 := "" // Should use default dir. snapshotDir2 := filepath.Join(fake.X.Root, "some/other/dir") // Create a test suite. tests := []config{ config{ dir: snapshotDir1, }, config{ dir: snapshotDir2, }, } 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 { snapshotDirFlag = test.dir // 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 TestMultiPart(t *testing.T) { fake, cleanup := jiritest.NewFakeJiriRoot(t) defer cleanup() projects := addProjects(t, fake) origCleanupFlag, origCurrentProjectFlag := cleanupMultiPartFlag, currentProjectFlag defer func() { cleanupMultiPartFlag, currentProjectFlag = origCleanupFlag, origCurrentProjectFlag }() cleanupMultiPartFlag, currentProjectFlag = false, false name, err := gitutil.New(fake.X.NewSeq()).CurrentBranchName() if err != nil { t.Fatal(err) } if name == "master" { // The test cases below assume that they are run on a feature-branch, // but this is not necessarily always the case when running under // jenkins, so if it's run on a master branch it will create // a feature branch. if err := gitutil.New(fake.X.NewSeq()).CreateAndCheckoutBranch("feature-branch"); err != nil { t.Fatal(err) } defer func() { git := gitutil.New(fake.X.NewSeq()) git.CheckoutBranch("master", gitutil.ForceOpt(true)) git.DeleteBranch("feature-branch", gitutil.ForceOpt(true)) }() } cwd, err := os.Getwd() if err != nil { t.Fatal(err) } defer os.Chdir(cwd) relchdir := func(dir string) { chdir(t, fake.X, dir) } initMP := func() *multiPart { mp, err := initForMultiPart(fake.X) if err != nil { _, file, line, _ := runtime.Caller(1) t.Fatalf("%s:%d: %v", filepath.Base(file), line, err) } return mp } wr := func(mp *multiPart) *multiPart { return mp } git := func(dir string) *gitutil.Git { return gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir)) } cleanupMultiPartFlag = true if got, want := initMP(), wr(&multiPart{clean: true}); !reflect.DeepEqual(got, want) { t.Errorf("got %#v, want %#v", got, want) } currentProjectFlag = true if got, want := initMP(), wr(&multiPart{clean: true, current: true}); !reflect.DeepEqual(got, want) { t.Errorf("got %#v, want %#v", got, want) } cleanupMultiPartFlag, currentProjectFlag = false, false // Test metadata generation. ra := projects[0].Path rb := projects[1].Path rc := projects[2].Path t1 := projects[3].Path git(ra).CreateAndCheckoutBranch("a1") relchdir(ra) if got, want := initMP(), wr(&multiPart{current: true, currentKey: projects[0].Key(), currentBranch: "a1"}); !reflect.DeepEqual(got, want) { t.Errorf("got %#v, want %#v", got, want) } git(rb).CreateAndCheckoutBranch("a1") mp := initMP() if mp.current != false || mp.clean != false { t.Errorf("current or clean not false: %v, %v", mp.current, mp.clean) } if got, want := len(mp.keys), 2; got != want { t.Errorf("got %v, want %v", got, want) } tmp := &multiPart{ keys: project.ProjectKeys{projects[0].Key(), projects[1].Key()}, } for i, k := range mp.keys { if got, want := k, tmp.keys[i]; got != want { t.Errorf("got %v, want %v", got, want) } } if got, want := len(mp.states), 2; got != want { t.Errorf("got %v, want %v", got, want) } git(rc).CreateAndCheckoutBranch("a1") git(t1).CreateAndCheckoutBranch("a2") mp = initMP() if got, want := len(mp.keys), 3; got != want { t.Errorf("got %v, want %v", got, want) } if err := mp.writeMultiPartMetadata(fake.X); err != nil { t.Fatal(err) } hasMetaData := func(total int, branch string, projectPaths ...string) { _, file, line, _ := runtime.Caller(1) loc := fmt.Sprintf("%s:%d", filepath.Base(file), line) for i, dir := range projectPaths { filename := filepath.Join(dir, jiri.ProjectMetaDir, branch, multiPartMetaDataFileName) msg, err := ioutil.ReadFile(filename) if err != nil { t.Fatalf("%s: %v", loc, err) } if got, want := string(msg), fmt.Sprintf("MultiPart: %d/%d\n", i+1, total); got != want { t.Errorf("%v: got %v, want %v", dir, got, want) } } } hasNoMetaData := func(branch string, projectPaths ...string) { _, file, line, _ := runtime.Caller(1) loc := fmt.Sprintf("%s:%d", filepath.Base(file), line) for _, dir := range projectPaths { filename := filepath.Join(fake.X.Root, dir, jiri.ProjectMetaDir, branch, multiPartMetaDataFileName) _, err := os.Stat(filename) if !os.IsNotExist(err) { t.Fatalf("%s: %s should not exist", loc, filename) } } } newFile := func(dir, file string) { testfile := filepath.Join(dir, file) _, err := fake.X.NewSeq().Create(testfile) if err != nil { t.Errorf("failed to create %s: %v", testfile, err) } } hasMetaData(len(mp.keys), "a1", ra, rb, rc) hasNoMetaData(t1, "a2") if err := mp.cleanMultiPartMetadata(fake.X); err != nil { t.Fatal(err) } hasNoMetaData(ra, "a1", rb, rc, t1) // Test CL messages. for _, p := range projects { // Install commit hook so that Change-Id is written. installCommitMsgHook(t, fake.X, p.Path) } // Create a fake jiri root for the fake gerrit repos. gerritFake, gerritCleanup := jiritest.NewFakeJiriRoot(t) defer gerritCleanup() relchdir(ra) if err := mp.writeMultiPartMetadata(fake.X); err != nil { t.Fatal(err) } hasMetaData(len(mp.keys), "a1", ra, rb, rc) gitAddFiles := func(name string, repos ...string) { for _, dir := range repos { newFile(dir, name) if err := git(dir).Add(name); err != nil { t.Error(err) } } } gitCommit := func(msg string, repos ...string) { for _, dir := range repos { committer := git(dir).NewCommitter(false) if err := committer.Commit(msg); err != nil { t.Error(err) } } } gitAddFiles("new-file", ra, rb, rc) _, err = initForMultiPart(fake.X) if err == nil || !strings.Contains(err.Error(), "uncommitted changes:") { t.Fatalf("expected an error about uncommitted changes: got %v", err) } gitCommit("oh multipart test\n", ra, rb, rc) bodyMessage := "xyz\n\na simple message\n" messageFile := filepath.Join(fake.X.Root, jiri.RootMetaDir, "message-body") if err := ioutil.WriteFile(messageFile, []byte(bodyMessage), 0666); err != nil { t.Fatal(err) } mp = initMP() setTopicFlag = false commitMessageBodyFlag = messageFile testCommitMsgs := func(branch string, cls ...*project.Project) { _, file, line, _ := runtime.Caller(1) loc := fmt.Sprintf("%s:%d", filepath.Base(file), line) total := len(cls) for index, p := range cls { // Create a new gerrit repo each time we commit, since we can't // push more than once to the fake gerrit repo without actually // running gerrit. gp := createRepoFromOrigin(t, gerritFake.X, "gerrit", p.Remote) defer os.Remove(gp) relchdir(p.Path) review, err := newReview(fake.X, *p, gerrit.CLOpts{ Presubmit: gerrit.PresubmitTestTypeNone, Remote: gp, }) if err != nil { t.Fatalf("%v: %v: %v", loc, p.Path, err) } // use the default commit message if err := review.run(); err != nil { t.Fatalf("%v: %v, %v", loc, p.Path, err) } filename, err := getCommitMessageFileName(fake.X, branch) if err != nil { t.Fatalf("%v: %v", loc, err) } msg, err := ioutil.ReadFile(filename) if err != nil { t.Fatalf("%v: %v", loc, err) } if total < 2 { if strings.Contains(string(msg), "MultiPart") { t.Errorf("%v: commit message contains MultiPart when it should not: %v", loc, string(msg)) } continue } expected := fmt.Sprintf("\nMultiPart: %d/%d\n", index+1, total) if !strings.Contains(string(msg), expected) { t.Errorf("%v: commit message for %v does not contain %v: %v", loc, p.Path, expected, string(msg)) } if got, want := string(msg), bodyMessage+"PresubmitTest: none"+expected+"Change-Id: I0000000000000000000000000000000000000000"; got != want { t.Errorf("got %v, want %v", got, want) } } } testCommitMsgs("a1", projects[0], projects[1], projects[2]) cl := mp.commandline("", []string{"-r=alice"}) expected := []string{ "runp", "--interactive", "--projects=" + string(projects[0].Key()) + "," + string(projects[1].Key()) + "," + string(projects[2].Key()), "jiri", "cl", "mail", "--current-project-only=true", "-r=alice", } if got, want := strings.Join(cl, " "), strings.Join(expected, " "); got != want { t.Errorf("got %v, want %v", got, want) } cl = mp.commandline(projects[0].Key(), []string{"-r=bob"}) expected[2] = "--projects=" + string(projects[1].Key()) + "," + string(projects[2].Key()) expected[len(expected)-1] = "-r=bob" if got, want := strings.Join(cl, " "), strings.Join(expected, " "); got != want { t.Errorf("got %v, want %v", got, want) } git(rb).CreateAndCheckoutBranch("a2") gitAddFiles("new-file1", ra, rc) gitCommit("oh multipart test: 2\n", ra, rc) mp = initMP() if err := mp.writeMultiPartMetadata(fake.X); err != nil { t.Fatal(err) } hasMetaData(len(mp.keys), "a1", ra, rc) testCommitMsgs("a1", projects[0], projects[2]) git(ra).CreateAndCheckoutBranch("a2") mp = initMP() if err := mp.writeMultiPartMetadata(fake.X); err != nil { t.Fatal(err) } hasNoMetaData(rc) testCommitMsgs("a1", projects[2]) }