go.fuchsia.dev/jiri@v0.0.0-20240502161911-b66513b29486/cmd/jiri/override_test.go (about) 1 // Copyright 2018 The Fuchsia 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 "fmt" 9 "os" 10 "strings" 11 "testing" 12 13 "go.fuchsia.dev/jiri/jiritest/xtest" 14 "go.fuchsia.dev/jiri/project" 15 ) 16 17 type overrideTestCase struct { 18 Args []string 19 Filename string 20 OutputFileName string 21 Exist, Want string 22 Stdout, Stderr string 23 SetFlags func() 24 runOnce bool 25 } 26 27 func setDefaultOverrideFlags() { 28 overrideFlags.importManifest = "" 29 overrideFlags.path = "" 30 overrideFlags.revision = "" 31 overrideFlags.gerritHost = "" 32 overrideFlags.delete = false 33 overrideFlags.list = false 34 overrideFlags.JSONOutput = "" 35 } 36 37 func TestOverride(t *testing.T) { 38 tests := []overrideTestCase{ 39 { 40 Stderr: `wrong number of arguments`, 41 }, 42 { 43 Args: []string{"a"}, 44 Stderr: `wrong number of arguments`, 45 }, 46 { 47 Args: []string{"a", "b", "c"}, 48 Stderr: `wrong number of arguments`, 49 }, 50 // Remote imports, default append behavior 51 { 52 Args: []string{"foo", "https://github.com/new.git"}, 53 Want: `<manifest> 54 <imports> 55 <import manifest="manifest" name="foo" remote="https://github.com/new.git"/> 56 </imports> 57 <overrides> 58 <project name="foo" remote="https://github.com/new.git"/> 59 </overrides> 60 </manifest> 61 `, 62 }, 63 { 64 SetFlags: func() { 65 overrideFlags.path = "bar" 66 }, 67 Args: []string{"foo", "https://github.com/new.git"}, 68 Want: `<manifest> 69 <imports> 70 <import manifest="manifest" name="foo" remote="https://github.com/new.git"/> 71 </imports> 72 <overrides> 73 <project name="foo" path="bar" remote="https://github.com/new.git"/> 74 </overrides> 75 </manifest> 76 `, 77 }, 78 { 79 SetFlags: func() { 80 overrideFlags.revision = "bar" 81 }, 82 Args: []string{"foo", "https://github.com/new.git"}, 83 Want: `<manifest> 84 <imports> 85 <import manifest="manifest" name="foo" remote="https://github.com/new.git"/> 86 </imports> 87 <overrides> 88 <project name="foo" remote="https://github.com/new.git" revision="bar"/> 89 </overrides> 90 </manifest> 91 `, 92 }, 93 { 94 SetFlags: func() { 95 overrideFlags.list = true 96 overrideFlags.JSONOutput = "file" 97 }, 98 Exist: `<manifest> 99 <imports> 100 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 101 </imports> 102 <overrides> 103 <project name="foo" remote="https://github.com/new.git"/> 104 </overrides> 105 </manifest> 106 `, 107 OutputFileName: `file`, 108 Want: `[ 109 { 110 "name": "foo", 111 "remote": "https://github.com/new.git", 112 "revision": "HEAD" 113 } 114 ] 115 `, 116 }, 117 { 118 SetFlags: func() { 119 overrideFlags.list = true 120 }, 121 Exist: `<manifest> 122 <imports> 123 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 124 </imports> 125 <overrides> 126 <project name="foo" remote="https://github.com/new.git"/> 127 </overrides> 128 </manifest> 129 `, 130 Stdout: `* override foo 131 Name: foo 132 Remote: https://github.com/new.git 133 `, 134 }, 135 { 136 Args: []string{"bar", "https://github.com/bar.git"}, 137 Exist: `<manifest> 138 <imports> 139 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 140 </imports> 141 <overrides> 142 <project name="foo" remote="https://github.com/foo.git"/> 143 </overrides> 144 </manifest> 145 `, 146 Want: `<manifest> 147 <imports> 148 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 149 </imports> 150 <overrides> 151 <project name="foo" remote="https://github.com/foo.git"/> 152 <project name="bar" remote="https://github.com/bar.git"/> 153 </overrides> 154 </manifest> 155 `, 156 }, 157 // test delete flag 158 { 159 SetFlags: func() { 160 overrideFlags.delete = true 161 }, 162 Stderr: `wrong number of arguments`, 163 runOnce: true, 164 }, 165 { 166 SetFlags: func() { 167 overrideFlags.delete = true 168 }, 169 Args: []string{"a", "b", "c"}, 170 Stderr: `wrong number of arguments`, 171 runOnce: true, 172 }, 173 { 174 SetFlags: func() { 175 overrideFlags.delete = true 176 overrideFlags.list = true 177 }, 178 Args: []string{"a", "b"}, 179 Stderr: `cannot use -delete and -list together`, 180 runOnce: true, 181 }, 182 { 183 SetFlags: func() { 184 overrideFlags.delete = true 185 }, 186 Args: []string{"foo"}, 187 runOnce: true, 188 Exist: `<manifest> 189 <imports> 190 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 191 </imports> 192 <overrides> 193 <project name="foo" remote="https://github.com/foo.git"/> 194 <project name="bar" remote="https://github.com/bar.git"/> 195 </overrides> 196 </manifest> 197 `, 198 Want: `<manifest> 199 <imports> 200 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 201 </imports> 202 <overrides> 203 <project name="bar" remote="https://github.com/bar.git"/> 204 </overrides> 205 </manifest> 206 `, 207 }, 208 { 209 SetFlags: func() { 210 overrideFlags.delete = true 211 }, 212 Args: []string{"foo"}, 213 runOnce: true, 214 Exist: `<manifest> 215 <imports> 216 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 217 </imports> 218 <overrides> 219 <project name="foo" remote="https://github.com/foo.git"/> 220 <project name="foo" remote="https://github.com/bar.git"/> 221 </overrides> 222 </manifest> 223 `, 224 Stderr: `more than one override matches`, 225 }, 226 { 227 SetFlags: func() { 228 overrideFlags.delete = true 229 }, 230 Args: []string{"foo", "https://github.com/bar.git"}, 231 runOnce: true, 232 Exist: `<manifest> 233 <imports> 234 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 235 </imports> 236 <overrides> 237 <project name="foo" remote="https://github.com/foo.git"/> 238 <project name="foo" remote="https://github.com/bar.git"/> 239 </overrides> 240 </manifest> 241 `, 242 Want: `<manifest> 243 <imports> 244 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 245 </imports> 246 <overrides> 247 <project name="foo" remote="https://github.com/foo.git"/> 248 </overrides> 249 </manifest> 250 `, 251 }, 252 { 253 SetFlags: func() { 254 overrideFlags.importManifest = "manifest" 255 overrideFlags.revision = "eabeadae97b1e7f97ba93206066411adfe93a509" 256 }, 257 Args: []string{"orig", "https://github.com/orig.git"}, 258 runOnce: true, 259 Exist: `<manifest> 260 <imports> 261 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 262 </imports> 263 </manifest> 264 `, 265 Want: `<manifest> 266 <imports> 267 <import manifest="manifest" name="orig" remote="https://github.com/orig.git"/> 268 </imports> 269 <overrides> 270 <import manifest="manifest" name="orig" remote="https://github.com/orig.git" revision="eabeadae97b1e7f97ba93206066411adfe93a509"/> 271 </overrides> 272 </manifest> 273 `, 274 }, 275 } 276 277 // Temporary directory in which our jiri binary will live. 278 binDir, err := os.MkdirTemp("", "") 279 if err != nil { 280 t.Fatal(err) 281 } 282 defer os.RemoveAll(binDir) 283 284 for _, test := range tests { 285 if err := testOverride(t, test); err != nil { 286 t.Errorf("%v: %v", test.Args, err) 287 } 288 } 289 } 290 291 func testOverride(t *testing.T, test overrideTestCase) error { 292 jirix, cleanup := xtest.NewX(t) 293 defer cleanup() 294 // Temporary directory in which to run `jiri import`. 295 tmpDir, err := os.MkdirTemp("", "") 296 if err != nil { 297 return err 298 } 299 defer os.RemoveAll(tmpDir) 300 301 // Create a .jiri_manifest file which imports the manifest created above. 302 manifest := project.Manifest{ 303 Imports: []project.Import{ 304 { 305 Manifest: "manifest", 306 Name: "foo", 307 Remote: "https://github.com/new.git", 308 }, 309 }, 310 } 311 if err := manifest.ToFile(jirix, jirix.JiriManifestFile()); err != nil { 312 t.Fatal(err) 313 } 314 315 // Return to the current working directory when done. 316 cwd, err := os.Getwd() 317 if err != nil { 318 return err 319 } 320 defer os.Chdir(cwd) 321 322 // cd into a root directory in which to do the actual import. 323 jiriRoot := jirix.Root 324 if err := os.Chdir(jiriRoot); err != nil { 325 return err 326 } 327 328 // Allow optional non-default filenames. 329 filename := test.Filename 330 if filename == "" { 331 filename = ".jiri_manifest" 332 } 333 334 // Set up an existing file if it was specified. 335 if test.Exist != "" { 336 if err := os.WriteFile(filename, []byte(test.Exist), 0644); err != nil { 337 return err 338 } 339 } 340 341 run := func() error { 342 // Run override and check the results. 343 overrideCmd := func() { 344 setDefaultOverrideFlags() 345 if test.SetFlags != nil { 346 test.SetFlags() 347 } 348 err = runOverride(jirix, test.Args) 349 } 350 stdout, _, runErr := runfunc(overrideCmd) 351 if runErr != nil { 352 return err 353 } 354 stderr := "" 355 if err != nil { 356 stderr = err.Error() 357 } 358 if got, want := stdout, test.Stdout; !strings.Contains(got, want) || (got != "" && want == "") { 359 return fmt.Errorf("stdout got %q, want substr %q", got, want) 360 } 361 if got, want := stderr, test.Stderr; !strings.Contains(got, want) || (got != "" && want == "") { 362 return fmt.Errorf("stderr got %q, want substr %q", got, want) 363 } 364 return nil 365 } 366 if err := run(); err != nil { 367 return err 368 } 369 370 // check that it is idempotent 371 if !test.runOnce { 372 if err := run(); err != nil { 373 return err 374 } 375 } 376 f := test.OutputFileName 377 if f == "" { 378 f = filename 379 } 380 381 // Make sure the right file is generated. 382 if test.Want != "" { 383 data, err := os.ReadFile(f) 384 if err != nil { 385 return err 386 } 387 if got, want := string(data), test.Want; got != want { 388 return fmt.Errorf("GOT\n%s\nWANT\n%s", got, want) 389 } 390 } 391 return nil 392 }