go.fuchsia.dev/jiri@v0.0.0-20240502161911-b66513b29486/cmd/jiri/snapshot_test.go (about) 1 // Copyright 2015 The Vanadium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "bytes" 9 "fmt" 10 "os" 11 "path/filepath" 12 "testing" 13 14 "go.fuchsia.dev/jiri" 15 "go.fuchsia.dev/jiri/gitutil" 16 "go.fuchsia.dev/jiri/jiritest" 17 "go.fuchsia.dev/jiri/project" 18 "go.fuchsia.dev/jiri/tool" 19 ) 20 21 func checkReadme(t *testing.T, jirix *jiri.X, project, message string) { 22 if _, err := os.Stat(project); err != nil { 23 t.Fatalf("%v", err) 24 } 25 readmeFile := filepath.Join(project, "README") 26 data, err := os.ReadFile(readmeFile) 27 if err != nil { 28 t.Fatalf("%v", err) 29 } 30 if got, want := data, []byte(message); bytes.Compare(got, want) != 0 { 31 t.Fatalf("unexpected content %v:\ngot\n%s\nwant\n%s\n", project, got, want) 32 } 33 } 34 35 func localProjectName(i int) string { 36 return "test-local-project-" + fmt.Sprintf("%d", i+1) 37 } 38 39 func remoteProjectName(i int) string { 40 return "test-remote-project-" + fmt.Sprintf("%d", i+1) 41 } 42 43 func writeReadme(t *testing.T, jirix *jiri.X, projectDir, message string) { 44 path, perm := filepath.Join(projectDir, "README"), os.FileMode(0644) 45 if err := os.WriteFile(path, []byte(message), perm); err != nil { 46 t.Fatalf("%s", err) 47 } 48 cwd, err := os.Getwd() 49 if err != nil { 50 t.Fatalf("%s", err) 51 } 52 defer os.Chdir(cwd) 53 if err := os.Chdir(projectDir); err != nil { 54 t.Fatalf("%s", err) 55 } 56 if err := gitutil.New(jirix, gitutil.UserNameOpt("John Doe"), gitutil.UserEmailOpt("john.doe@example.com")).CommitFile(path, "creating README"); err != nil { 57 t.Fatalf("%s", err) 58 } 59 } 60 61 // TestSnapshot tests creating and checking out a snapshot. 62 func TestSnapshot(t *testing.T) { 63 fake, cleanup := jiritest.NewFakeJiriRoot(t) 64 defer cleanup() 65 66 // Setup the initial remote and local projects. 67 numProjects, remoteProjects := 2, []string{} 68 for i := 0; i < numProjects; i++ { 69 if err := fake.CreateRemoteProject(remoteProjectName(i)); err != nil { 70 t.Fatalf("%v", err) 71 } 72 if err := fake.AddProject(project.Project{ 73 Name: remoteProjectName(i), 74 Path: localProjectName(i), 75 Remote: fake.Projects[remoteProjectName(i)], 76 }); err != nil { 77 t.Fatalf("%v", err) 78 } 79 } 80 81 // Create initial commits in the remote projects and use UpdateUniverse() 82 // to mirror them locally. 83 for i := 0; i < numProjects; i++ { 84 writeReadme(t, fake.X, fake.Projects[remoteProjectName(i)], "revision 1") 85 } 86 if err := project.UpdateUniverse(fake.X, true, false, false, false, false, true /*run-hooks*/, true /*run-packages*/, false /*rebase-subdmodules*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil { 87 t.Fatalf("%v", err) 88 } 89 90 // Create a snapshot. 91 var stdout bytes.Buffer 92 fake.X.Context = tool.NewContext(tool.ContextOpts{Stdout: &stdout, Env: fake.X.Context.Env()}) 93 94 tmpfile, err := os.CreateTemp("", "jiri-snapshot-") 95 if err != nil { 96 t.Fatal(err) 97 } 98 defer os.Remove(tmpfile.Name()) 99 100 if err := runSnapshot(fake.X, []string{tmpfile.Name()}); err != nil { 101 t.Fatalf("%v", err) 102 } 103 104 // Remove the local project repositories. 105 for i := range remoteProjects { 106 localProject := filepath.Join(fake.X.Root, localProjectName(i)) 107 if err := os.RemoveAll(localProject); err != nil { 108 t.Fatalf("%v", err) 109 } 110 } 111 112 snapshotFile := tmpfile.Name() 113 if err := project.CheckoutSnapshot(fake.X, snapshotFile, false, true /*run-hooks*/, true /*run-packages*/, project.DefaultHookTimeout, project.DefaultPackageTimeout, nil); err != nil { 114 t.Fatalf("%s", err) 115 } 116 for i := range remoteProjects { 117 localProject := filepath.Join(fake.X.Root, localProjectName(i)) 118 checkReadme(t, fake.X, localProject, "revision 1") 119 } 120 } 121 122 // TestCipdSnapshot tests creating cipd snapshot files. 123 func TestCipdSnapshot(t *testing.T) { 124 fake, cleanup := jiritest.NewFakeJiriRoot(t) 125 defer cleanup() 126 127 // Setup fake packages 128 fake.AddPackage(project.Package{ 129 Name: "test_package", 130 Path: "path-to-test-package", 131 Version: "git_revision:05715c8fbbdb952ab38e50533a1b653445e74b40", 132 Attributes: "", 133 }) 134 fake.AddPackage(project.Package{ 135 Name: "test_package_internal", 136 Path: "path-to-test-package-internal", 137 Version: "git_revision:05715c8fbbdb952ab38e50533a1b653445e74b41", 138 Attributes: "", 139 Internal: true, 140 }) 141 142 // Create a snapshot. 143 var stdout bytes.Buffer 144 fake.X.Context = tool.NewContext(tool.ContextOpts{Stdout: &stdout, Env: fake.X.Context.Env()}) 145 146 tmpfile, err := os.CreateTemp("", "jiri-snapshot-") 147 if err != nil { 148 t.Fatal(err) 149 } 150 defer os.Remove(tmpfile.Name()) 151 152 if err := project.CreateSnapshot(fake.X, tmpfile.Name(), nil, nil, true, true /*cipdEnsureFlag*/); err != nil { 153 t.Fatalf("%v", err) 154 } 155 pathExists := func(pkgPath string) bool { 156 if _, err := os.Stat(pkgPath); err != nil { 157 if os.IsNotExist(err) { 158 return false 159 } 160 t.Errorf("failed to access path due to error: %v", err) 161 } 162 return true 163 } 164 assertExist := func(localPath string) { 165 if !pathExists(localPath) { 166 t.Errorf("expecting path %q exists, but it does not", localPath) 167 } 168 } 169 170 // Verify cipd snapshot files were generated. 171 ensureFilePath := tmpfile.Name() + ".ensure" 172 ensureFileIntPath := tmpfile.Name() + "_internal.ensure" 173 versionFilePath := tmpfile.Name() + ".version" 174 versionFileIntPath := tmpfile.Name() + "_internal.version" 175 assertExist(ensureFilePath) 176 assertExist(ensureFileIntPath) 177 assertExist(versionFilePath) 178 assertExist(versionFileIntPath) 179 os.Remove(ensureFilePath) 180 os.Remove(ensureFileIntPath) 181 os.Remove(versionFilePath) 182 os.Remove(versionFileIntPath) 183 }