v.io/jiri@v0.0.0-20160715023856-abfb8b131290/jiritest/fake.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 jiritest 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "v.io/jiri" 14 "v.io/jiri/gitutil" 15 "v.io/jiri/project" 16 ) 17 18 // FakeJiriRoot sets up a fake JIRI_ROOT under a tmp directory. 19 type FakeJiriRoot struct { 20 X *jiri.X 21 Projects map[string]string 22 remote string 23 } 24 25 const ( 26 defaultDataDir = "data" 27 manifestFileName = "public" 28 manifestProjectName = "manifest" 29 manifestProjectPath = "manifest" 30 ) 31 32 // NewFakeJiriRoot returns a new FakeJiriRoot and a cleanup closure. The 33 // closure must be run to cleanup temporary directories and restore the original 34 // environment; typically it is run as a defer function. 35 func NewFakeJiriRoot(t *testing.T) (*FakeJiriRoot, func()) { 36 jirix, cleanup := NewX(t) 37 fake := &FakeJiriRoot{ 38 X: jirix, 39 Projects: map[string]string{}, 40 } 41 42 s := jirix.NewSeq() 43 // Create fake remote manifest and tools projects. 44 remoteDir, err := s.TempDir("", "") 45 if err != nil { 46 t.Fatalf("TempDir() failed: %v", err) 47 } 48 fake.remote = remoteDir 49 if err := fake.CreateRemoteProject(manifestProjectPath); err != nil { 50 t.Fatal(err) 51 } 52 // Create a fake manifest. 53 manifestDir := filepath.Join(remoteDir, manifestProjectPath) 54 if err := s.MkdirAll(manifestDir, os.FileMode(0700)).Done(); err != nil { 55 t.Fatal(err) 56 } 57 if err := fake.WriteRemoteManifest(&project.Manifest{}); err != nil { 58 t.Fatal(err) 59 } 60 // Add the "manifest" project to the manifest. 61 if err := fake.AddProject(project.Project{ 62 Name: manifestProjectName, 63 Path: manifestProjectPath, 64 Remote: fake.Projects[manifestProjectName], 65 }); err != nil { 66 t.Fatal(err) 67 } 68 // Create a .jiri_manifest file which imports the manifest created above. 69 if err := fake.WriteJiriManifest(&project.Manifest{ 70 Imports: []project.Import{ 71 project.Import{ 72 Manifest: manifestFileName, 73 Name: manifestProjectName, 74 Remote: filepath.Join(fake.remote, manifestProjectPath), 75 }, 76 }, 77 }); err != nil { 78 t.Fatal(err) 79 } 80 81 // Update the contents of the fake JIRI_ROOT instance based on 82 // the information recorded in the remote manifest. 83 if err := fake.UpdateUniverse(false); err != nil { 84 t.Fatal(err) 85 } 86 87 // Create the profiles database directory. 88 profilesDB := filepath.Join(jirix.Root, ".jiri_root", "profile_db") 89 if err := s.MkdirAll(profilesDB, os.FileMode(0700)).Done(); err != nil { 90 t.Fatal(err) 91 } 92 93 return fake, func() { 94 cleanup() 95 if err := fake.X.NewSeq().RemoveAll(fake.remote).Done(); err != nil { 96 t.Fatalf("RemoveAll(%q) failed: %v", fake.remote, err) 97 } 98 } 99 } 100 101 // AddProject adds the given project to a remote manifest. 102 func (fake FakeJiriRoot) AddProject(project project.Project) error { 103 manifest, err := fake.ReadRemoteManifest() 104 if err != nil { 105 return err 106 } 107 manifest.Projects = append(manifest.Projects, project) 108 if err := fake.WriteRemoteManifest(manifest); err != nil { 109 return err 110 } 111 return nil 112 } 113 114 // AddTool adds the given tool to a remote manifest. 115 func (fake FakeJiriRoot) AddTool(tool project.Tool) error { 116 manifest, err := fake.ReadRemoteManifest() 117 if err != nil { 118 return err 119 } 120 manifest.Tools = append(manifest.Tools, tool) 121 if err := fake.WriteRemoteManifest(manifest); err != nil { 122 return err 123 } 124 return nil 125 } 126 127 // DisableRemoteManifestPush disables pushes to the remote manifest 128 // repository. 129 func (fake FakeJiriRoot) DisableRemoteManifestPush() error { 130 dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProjectPath)) 131 if err := gitutil.New(fake.X.NewSeq(), dir).CheckoutBranch("master"); err != nil { 132 return err 133 } 134 return nil 135 } 136 137 // EnableRemoteManifestPush enables pushes to the remote manifest 138 // repository. 139 func (fake FakeJiriRoot) EnableRemoteManifestPush() error { 140 dir := gitutil.RootDirOpt(filepath.Join(fake.remote, manifestProjectPath)) 141 if !gitutil.New(fake.X.NewSeq(), dir).BranchExists("non-master") { 142 if err := gitutil.New(fake.X.NewSeq(), dir).CreateBranch("non-master"); err != nil { 143 return err 144 } 145 } 146 if err := gitutil.New(fake.X.NewSeq(), dir).CheckoutBranch("non-master"); err != nil { 147 return err 148 } 149 return nil 150 } 151 152 // CreateRemoteProject creates a new remote project. 153 func (fake FakeJiriRoot) CreateRemoteProject(name string) error { 154 projectDir := filepath.Join(fake.remote, name) 155 if err := fake.X.NewSeq().MkdirAll(projectDir, os.FileMode(0700)).Done(); err != nil { 156 return err 157 } 158 if err := gitutil.New(fake.X.NewSeq()).Init(projectDir); err != nil { 159 return err 160 } 161 if err := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(projectDir)).CommitWithMessage("initial commit"); err != nil { 162 return err 163 } 164 fake.Projects[name] = projectDir 165 return nil 166 } 167 168 // ReadRemoteManifest read a manifest from the remote manifest project. 169 func (fake FakeJiriRoot) ReadRemoteManifest() (*project.Manifest, error) { 170 path := filepath.Join(fake.remote, manifestProjectPath, manifestFileName) 171 return project.ManifestFromFile(fake.X, path) 172 } 173 174 // UpdateUniverse synchronizes the content of the Vanadium fake based 175 // on the content of the remote manifest. 176 func (fake FakeJiriRoot) UpdateUniverse(gc bool) error { 177 oldRoot := os.Getenv(jiri.RootEnv) 178 if err := os.Setenv(jiri.RootEnv, fake.X.Root); err != nil { 179 return fmt.Errorf("Setenv() failed: %v", err) 180 } 181 defer os.Setenv(jiri.RootEnv, oldRoot) 182 if err := project.UpdateUniverse(fake.X, gc); err != nil { 183 return err 184 } 185 return nil 186 } 187 188 // ReadJiriManifest reads the .jiri_manifest manifest. 189 func (fake FakeJiriRoot) ReadJiriManifest() (*project.Manifest, error) { 190 return project.ManifestFromFile(fake.X, fake.X.JiriManifestFile()) 191 } 192 193 // WriteJiriManifest writes the given manifest to the .jiri_manifest file. 194 func (fake FakeJiriRoot) WriteJiriManifest(manifest *project.Manifest) error { 195 return manifest.ToFile(fake.X, fake.X.JiriManifestFile()) 196 } 197 198 // WriteRemoteManifest writes the given manifest to the remote 199 // manifest project. 200 func (fake FakeJiriRoot) WriteRemoteManifest(manifest *project.Manifest) error { 201 dir := filepath.Join(fake.remote, manifestProjectPath) 202 path := filepath.Join(dir, manifestFileName) 203 return fake.writeManifest(manifest, dir, path) 204 } 205 206 func (fake FakeJiriRoot) writeManifest(manifest *project.Manifest, dir, path string) error { 207 git := gitutil.New(fake.X.NewSeq(), gitutil.RootDirOpt(dir)) 208 if err := manifest.ToFile(fake.X, path); err != nil { 209 return err 210 } 211 if err := git.Add(path); err != nil { 212 return err 213 } 214 if err := git.Commit(); err != nil { 215 return err 216 } 217 return nil 218 }