github.com/comcast/canticle@v0.0.0-20161108184242-c53cface56e8/canticles/vcs_test.go (about) 1 package canticles 2 3 import ( 4 "errors" 5 "io/ioutil" 6 "os" 7 "path" 8 "regexp" 9 "testing" 10 11 "golang.org/x/tools/go/vcs" 12 ) 13 14 var errTest = errors.New("Test err") 15 16 func TestDefaultRepoResolver(t *testing.T) { 17 dr := &DefaultRepoResolver{os.ExpandEnv("$GOPATH")} 18 // Try a VCS resolution against someone supports go get syntax 19 importPath := "golang.org/x/tools/go/vcs" 20 vcs, err := dr.ResolveRepo(importPath, nil) 21 if err != nil { 22 t.Errorf("DefaultRepoResolver returned error for golang.org repo: %s", err.Error()) 23 } 24 if vcs == nil { 25 t.Fatalf("DefaultRepoResolver returned nil vcs for repo: %s", importPath) 26 } 27 28 v := vcs.(*PackageVCS) 29 if v.Repo.Root != "golang.org/x/tools" { 30 t.Errorf("DefaultRepoResolver did not set correct root for repo got %s expected %s", v.Repo.Root, "golang.org/x/tools") 31 } 32 if v.Repo.Repo == "" { 33 t.Errorf("DefaultRepoResolver did not set any repo for repo %s", importPath) 34 } 35 } 36 37 func TestRemoteRepoResolver(t *testing.T) { 38 rr := &RemoteRepoResolver{os.ExpandEnv("$GOPATH")} 39 40 dep := &CanticleDependency{ 41 SourcePath: "git@github.com:Comcast/Canticle.git", 42 Root: "github.com/Comcast/Canticle", 43 } 44 45 vcs, err := rr.ResolveRepo(dep.Root, dep) 46 if err != nil { 47 t.Errorf("RemoteRepoResolver returned error for our own repo: %s", err.Error()) 48 } 49 if vcs == nil { 50 t.Fatalf("RemoteRepoResolverResolveRepo returned nil vcs for repo: %+v", dep) 51 } 52 v := vcs.(*PackageVCS) 53 expectedRoot := "github.com/Comcast/Canticle" 54 if v.Repo.Root != expectedRoot { 55 t.Errorf("RemoteRepoResolver did not set correct root for repo got %s expected %s", v.Repo.Root, expectedRoot) 56 } 57 expectedURL := "git@github.com:Comcast/Canticle.git" 58 if v.Repo.Repo != expectedURL { 59 t.Errorf("ResolveRepo did not set correct repo for repo got %s expected %s", v.Repo.Repo, expectedURL) 60 } 61 62 // Try a VCS resolution that just flat fails 63 dep = &CanticleDependency{ 64 Root: "nothere.comcast.com/viper-cog/cant", 65 SourcePath: "git@nothere.comcast.com:viper-cog/cant.git", 66 } 67 vcs, err = rr.ResolveRepo(dep.Root, dep) 68 if err == nil { 69 t.Errorf("RemoteRepoResolver returned no error for a package that does not exist") 70 } 71 if vcs != nil { 72 t.Errorf("RemoteRepoResolver returned non nil vcs for repo: %+v", dep) 73 } 74 } 75 76 func TestLocalRepoResolver(t *testing.T) { 77 gopath, err := EnvGoPath() 78 if err != nil { 79 t.Fatalf("Could not get gopath: %s", err.Error()) 80 } 81 lr := &LocalRepoResolver{ 82 LocalPath: gopath, 83 } 84 85 pkg := "github.com/Comcast/Canticle" 86 vcs, err := lr.ResolveRepo(pkg, nil) 87 if err != nil { 88 t.Errorf("LocalRepoResolver returned error resolving our own package %s", err.Error()) 89 } 90 91 if vcs == nil { 92 t.Fatalf("LocalRepoResolver returned a nil VCS resolving our own package") 93 } 94 v := vcs.(*LocalVCS) 95 if v.Cmd.Cmd != "git" { 96 t.Errorf("LocalRepoResolver did not set correct vcs command %s expected %s", v.Cmd.Cmd, "git") 97 } 98 99 // Test dealing with a package whose vcs root != the importpath 100 pkg = "golang.org/x/tools/go/vcs" 101 vcs, err = lr.ResolveRepo(pkg, nil) 102 if err != nil { 103 t.Errorf("LocalRepoResolver returned error resolving our own package %s", err.Error()) 104 } 105 106 if vcs == nil { 107 t.Fatalf("LocalRepoResolver returned a nil VCS resolving our own package") 108 } 109 v = vcs.(*LocalVCS) 110 if v.Cmd.Cmd != "git" { 111 t.Errorf("LocalRepoResolver did not set correct vcs command %s expected %s", v.Cmd.Cmd, "git") 112 } 113 } 114 115 func TestResolveRootWithNoSlash(t *testing.T) { 116 gopath, err := EnvGoPath() 117 if err != nil { 118 t.Fatalf("Could not get gopath: %s", err.Error()) 119 } 120 121 dep := &CanticleDependency{ 122 Root: "camlistore.org", 123 SourcePath: "https://camlistore.googlesource.com/camlistore", 124 } 125 126 dr := &DefaultRepoResolver{gopath} 127 _, err = dr.ResolveRepo(dep.Root, dep) 128 if err != nil { 129 t.Errorf("DefaultRepoResolver could not resolve Root that does not contain a slash: %v", err) 130 } 131 132 rr := &RemoteRepoResolver{gopath} 133 _, err = rr.ResolveRepo(dep.Root, dep) 134 if err != nil { 135 t.Errorf("RemoteRepoResolver could not resolve Root that does not contain a slash: %v", err) 136 } 137 138 // Create a temp test dir for testing no slash local 139 testHome, err := ioutil.TempDir("", "cant-test-src") 140 if err != nil { 141 t.Fatalf("Error creating tempdir: %s", err.Error()) 142 } 143 defer os.RemoveAll(testHome) 144 if err := os.MkdirAll(path.Join(testHome, "src", "camlistore.org", ".git"), 0755); err != nil { 145 t.Fatalf("Error creating tempdir: %s", err.Error()) 146 } 147 148 lr := &LocalRepoResolver{testHome} 149 _, err = lr.ResolveRepo(dep.Root, dep) 150 if err != nil { 151 t.Errorf("LocalRepoResolver could not resolve Root that does not contain a slash: %v", err) 152 } 153 154 } 155 156 type TestVCS struct { 157 Updated int 158 Created int 159 Err error 160 Rev string 161 Source string 162 Root string 163 } 164 165 func (v *TestVCS) UpdateBranch(branch string) (bool, string, error) { 166 return false, "", nil 167 } 168 169 func (v *TestVCS) Create(rev string) error { 170 v.Rev = rev 171 v.Created++ 172 return v.Err 173 } 174 175 func (v *TestVCS) SetRev(rev string) error { 176 v.Rev = rev 177 v.Updated++ 178 return v.Err 179 } 180 181 func (v *TestVCS) GetRev() (string, error) { 182 return v.Rev, v.Err 183 } 184 185 func (v *TestVCS) GetSource() (string, error) { 186 return v.Source, v.Err 187 } 188 189 func (v *TestVCS) GetRoot() string { 190 return v.Root 191 } 192 193 func (v *TestVCS) GetBranch() (string, error) { 194 return v.Rev, v.Err 195 } 196 197 type testResolve struct { 198 path string 199 dep *CanticleDependency 200 } 201 202 type testResolver struct { 203 resolutions []testResolve 204 response []resolve 205 } 206 207 func (tr *testResolver) ResolveRepo(i string, d *CanticleDependency) (VCS, error) { 208 tr.resolutions = append(tr.resolutions, testResolve{i, d}) 209 resp := tr.response[0] 210 tr.response = tr.response[1:] 211 return resp.v, resp.err 212 } 213 214 func TestCompositeRepoResolver(t *testing.T) { 215 res := &TestVCS{} 216 tr1 := &testResolver{response: []resolve{{nil, errTest}}} 217 tr2 := &testResolver{response: []resolve{{res, nil}}} 218 219 cr := &CompositeRepoResolver{[]RepoResolver{tr1, tr2}} 220 221 dep := &CanticleDependency{ 222 Root: "testi", 223 } 224 v, err := cr.ResolveRepo(dep.Root, dep) 225 if err != nil { 226 t.Errorf("CompositeRepoResolver returned error with valid resolve %s", err.Error()) 227 } 228 if v != res { 229 t.Errorf("CompositeRepoResolver returned incorrect vcs") 230 } 231 if tr1.resolutions[0].path != dep.Root { 232 t.Errorf("CompositeRepoResolver tr1 bad import path") 233 } 234 if tr1.resolutions[0].dep != dep { 235 t.Errorf("CompositeRepoResolver tr1 bad dep") 236 } 237 if tr2.resolutions[0].dep != dep { 238 t.Errorf("CompositeRepoResolver tr2 bad dep") 239 } 240 241 tr1 = &testResolver{response: []resolve{{nil, errTest}}} 242 tr2 = &testResolver{response: []resolve{{nil, errTest}}} 243 cr = &CompositeRepoResolver{[]RepoResolver{tr1, tr2}} 244 v, err = cr.ResolveRepo(dep.Root, dep) 245 if re := ResolutionFailureErr(err); re == nil { 246 t.Errorf("CompositeRepoResolver did not return resolution failure") 247 } 248 } 249 250 func TestMemoizedRepoResolver(t *testing.T) { 251 res := &TestVCS{} 252 tr1 := &testResolver{response: []resolve{{res, nil}}} 253 mr := NewMemoizedRepoResolver(tr1) 254 dep := &CanticleDependency{ 255 Root: "testi", 256 } 257 v, err := mr.ResolveRepo(dep.Root, dep) 258 if err != nil { 259 t.Errorf("MemoizedRepoResolver returned error %s", err.Error()) 260 } 261 if v != res { 262 t.Errorf("MemoizedRepoResolver returned wrong vcs") 263 } 264 if len(tr1.resolutions) != 1 { 265 t.Errorf("MemoizedRepoResolver did not call tr1 only once") 266 } 267 268 v, err = mr.ResolveRepo(dep.Root, dep) 269 if err != nil { 270 t.Errorf("MemoizedRepoResolver returned error %s", err.Error()) 271 } 272 if v != res { 273 t.Errorf("MemoizedRepoResolver returned wrong vcs") 274 } 275 if len(tr1.resolutions) != 1 { 276 t.Errorf("MemoizedRepoResolver did not call tr1 only once") 277 } 278 } 279 280 var ( 281 expectedRev = "testrev" 282 TestRevCmd = &VCSCmd{ 283 Name: "Test", 284 Cmd: "echo", 285 Args: []string{expectedRev}, 286 ParseRegex: regexp.MustCompile(`^(\S+)$`), 287 } 288 ) 289 290 // TODO: Add coverage for LocalVCS and PackageVCS 291 func TestVCSCmds(t *testing.T) { 292 293 testHome, err := ioutil.TempDir("", "cant-test") 294 if err != nil { 295 t.Fatalf("Error creating tempdir: %s", err.Error()) 296 } 297 defer os.RemoveAll(testHome) 298 299 rev, err := TestRevCmd.Exec(testHome) 300 if err != nil { 301 t.Fatalf("Error running valid test exec command: %s", err.Error()) 302 } 303 if rev != expectedRev { 304 t.Errorf("Exec not %s not match expected %s", rev, expectedRev) 305 } 306 307 rev, err = TestRevCmd.Exec("someinvaliddir") 308 if err == nil { 309 t.Fatalf("No Error running invalid test exec command") 310 } 311 if rev != "" { 312 t.Errorf("Rev returned non empty string for errored command") 313 } 314 315 TestRevCmd.Args = []string{"this should be invalid"} 316 rev, err = TestRevCmd.Exec(testHome) 317 if err == nil { 318 t.Fatalf("No Error running invalid test exec command") 319 } 320 if rev != "" { 321 t.Errorf("Exec returned non empty string for regex that did not match") 322 } 323 TestRevCmd.Args = []string{expectedRev} 324 } 325 326 var ( 327 TestVCSCmd = &vcs.Cmd{ 328 Name: "Test", 329 Cmd: "echo", 330 CreateCmd: "create", 331 DownloadCmd: "download", 332 TagCmd: []vcs.TagCmd{ 333 {"show-ref", `(?:tags|origin)/(\S+)$`}, 334 }, 335 TagLookupCmd: []vcs.TagCmd{ 336 {"-n {tag}", `(\S+)$`}, 337 }, 338 TagSyncCmd: "checkout {tag}", 339 TagSyncDefault: "checkout master", 340 341 Scheme: []string{"test", "https"}, 342 PingCmd: "ping {scheme}://{repo}", 343 } 344 ) 345 346 func TestLocalVCS(t *testing.T) { 347 vcs.Verbose = true 348 testHome, err := ioutil.TempDir("", "cant-test-src") 349 if err != nil { 350 t.Fatalf("Error creating tempdir: %s", err.Error()) 351 } 352 defer os.RemoveAll(testHome) 353 354 pkgname := "test.com/test" 355 childpkg := "test.com/test/child" 356 if err := os.MkdirAll(PackageSource(testHome, childpkg), 0755); err != nil { 357 t.Fatalf("Error creating tempdir: %s", err.Error()) 358 } 359 360 v := NewLocalVCS(childpkg, pkgname, testHome, TestVCSCmd) 361 rev, err := v.GetRev() 362 if err != nil { 363 t.Fatalf("Local vcs should not return error with no rev command") 364 } 365 if rev != "" { 366 t.Errorf("Rev returned non empty string for no rev command: %s %+v", rev, v) 367 } 368 369 RevCmds[TestRevCmd.Name] = TestRevCmd 370 v = NewLocalVCS(childpkg, pkgname, testHome, TestVCSCmd) 371 v.Branches = func(path string) ([]string, error) { 372 return []string{"testrev"}, nil 373 } 374 rev, err = v.GetRev() 375 if err != nil { 376 t.Errorf("Error getting valid rev: %s", err.Error()) 377 } 378 if rev != expectedRev { 379 t.Errorf("Rev not %s not match expected %s", rev, expectedRev) 380 } 381 382 if err := v.Create(""); err != nil { 383 t.Errorf("Error running create command with no revision: %s", err.Error()) 384 } 385 if err = v.SetRev("testrev"); err != nil { 386 t.Errorf("Error setting rev to testrev: %s", err.Error()) 387 } 388 }