go.fuchsia.dev/jiri@v0.0.0-20240502161911-b66513b29486/gerrit/gerrit_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 gerrit 6 7 import ( 8 "fmt" 9 "reflect" 10 "strings" 11 "testing" 12 ) 13 14 func TestParseQueryResults(t *testing.T) { 15 t.Parallel() 16 input := `)]}' 17 [ 18 { 19 "change_id": "I26f771cebd6e512b89e98bec1fadfa1cb2aad6e8", 20 "current_revision": "3654e38b2f80a5410ea94f1d7321477d89cac391", 21 "project": "vanadium", 22 "owner": { 23 "_account_id": 1234, 24 "name": "John Doe", 25 "email": "john.doe@example.com" 26 }, 27 "revisions": { 28 "3654e38b2f80a5410ea94f1d7321477d89cac391": { 29 "fetch": { 30 "http": { 31 "ref": "refs/changes/40/4440/1" 32 } 33 } 34 } 35 } 36 }, 37 { 38 "change_id": "I26f771cebd6e512b89e98bec1fadfa1cb2aad6e8", 39 "current_revision": "3654e38b2f80a5410ea94f1d7321477d89cac391", 40 "labels": { 41 "Code-Review": {}, 42 "Verified": {} 43 }, 44 "project": "vanadium", 45 "owner": { 46 "_account_id": 1234, 47 "name": "John Doe", 48 "email": "john.doe@example.com" 49 }, 50 "topic": "test", 51 "revisions": { 52 "3654e38b2f80a5410ea94f1d7321477d89cac391": { 53 "fetch": { 54 "http": { 55 "ref": "refs/changes/40/4440/1" 56 } 57 }, 58 "commit": { 59 "message": "MultiPart: 1/3\nPresubmitTest: none" 60 } 61 } 62 } 63 }, 64 { 65 "change_id": "I35d83f8adae5b7db1974062fdc744f700e456677", 66 "current_revision": "b60413712472f1b576c7be951c4de309c6edaa53", 67 "project": "tools", 68 "owner": { 69 "_account_id": 1234, 70 "name": "John Doe", 71 "email": "john.doe@example.com" 72 }, 73 "revisions": { 74 "b60413712472f1b576c7be951c4de309c6edaa53": { 75 "fetch": { 76 "http": { 77 "ref": "refs/changes/43/4443/1" 78 } 79 }, 80 "commit": { 81 "message": "this change is great.\nPresubmitTest: none" 82 } 83 } 84 } 85 } 86 ] 87 ` 88 expectedFields := []struct { 89 ref string 90 project string 91 ownerEmail string 92 multiPart *MultiPartCLInfo 93 presubmitType PresubmitTestType 94 }{ 95 { 96 ref: "refs/changes/40/4440/1", 97 project: "vanadium", 98 ownerEmail: "john.doe@example.com", 99 multiPart: nil, 100 presubmitType: PresubmitTestTypeAll, 101 }, 102 { 103 ref: "refs/changes/40/4440/1", 104 project: "vanadium", 105 ownerEmail: "john.doe@example.com", 106 multiPart: &MultiPartCLInfo{ 107 Topic: "test", 108 Index: 1, 109 Total: 3, 110 }, 111 presubmitType: PresubmitTestTypeNone, 112 }, 113 { 114 ref: "refs/changes/43/4443/1", 115 project: "tools", 116 ownerEmail: "john.doe@example.com", 117 multiPart: nil, 118 presubmitType: PresubmitTestTypeNone, 119 }, 120 } 121 122 got, err := parseQueryResults(strings.NewReader(input)) 123 if err != nil { 124 t.Fatalf("%v", err) 125 } 126 for i, curChange := range got { 127 f := expectedFields[i] 128 if want, got := f.ref, curChange.Reference(); want != got { 129 t.Fatalf("%d: want: %q, got: %q", i, want, got) 130 } 131 if want, got := f.project, curChange.Project; want != got { 132 t.Fatalf("%d: want: %q, got: %q", i, want, got) 133 } 134 if want, got := f.ownerEmail, curChange.OwnerEmail(); want != got { 135 t.Fatalf("%d: want: %q, got: %q", i, want, got) 136 } 137 if want, got := f.multiPart, curChange.MultiPart; !reflect.DeepEqual(want, got) { 138 t.Fatalf("%d: want:\n%#v\ngot:\n%#v\n", i, want, got) 139 } 140 if want, got := f.presubmitType, curChange.PresubmitTest; want != got { 141 t.Fatalf("%d: want: %q, got: %q", i, want, got) 142 } 143 } 144 } 145 146 func TestParseMultiPartMatch(t *testing.T) { 147 t.Parallel() 148 type testCase struct { 149 str string 150 expectNoMatches bool 151 expectedIndex string 152 expectedTotal string 153 } 154 testCases := []testCase{ 155 { 156 str: "message...\nMultiPart: a/3", 157 expectNoMatches: true, 158 }, 159 { 160 str: "message...\n1/3", 161 expectNoMatches: true, 162 }, 163 { 164 str: "message...\nMultiPart:1/2", 165 expectedIndex: "1", 166 expectedTotal: "2", 167 }, 168 { 169 str: "message...\nMultiPart: 1/2", 170 expectedIndex: "1", 171 expectedTotal: "2", 172 }, 173 { 174 str: "message...\nMultiPart: 1 /2", 175 expectedIndex: "1", 176 expectedTotal: "2", 177 }, 178 { 179 str: "message...\nMultiPart: 1/ 2", 180 expectedIndex: "1", 181 expectedTotal: "2", 182 }, 183 { 184 str: "message...\nMultiPart: 1 / 2", 185 expectedIndex: "1", 186 expectedTotal: "2", 187 }, 188 { 189 str: "message...\nMultiPart: 123/234", 190 expectedIndex: "123", 191 expectedTotal: "234", 192 }, 193 } 194 for _, test := range testCases { 195 multiPartCLInfo, _ := parseMultiPartMatch(test.str) 196 if test.expectNoMatches && multiPartCLInfo != nil { 197 t.Fatalf("want no matches, got %v", multiPartCLInfo) 198 } 199 if !test.expectNoMatches && multiPartCLInfo == nil { 200 t.Fatalf("want matches, got no matches") 201 } 202 if !test.expectNoMatches { 203 if want, got := test.expectedIndex, fmt.Sprintf("%d", multiPartCLInfo.Index); want != got { 204 t.Fatalf("want 'index' %q, got %q", want, got) 205 } 206 if want, got := test.expectedTotal, fmt.Sprintf("%d", multiPartCLInfo.Total); want != got { 207 t.Fatalf("want 'total' %q, got %q", want, got) 208 } 209 } 210 } 211 } 212 213 func TestParseValidGitCookieFile(t *testing.T) { 214 t.Parallel() 215 // Valid content. 216 gitCookieFileContent := ` 217 vanadium.googlesource.com FALSE / TRUE 2147483647 o git-johndoe.example.com=12345 218 vanadium-review.googlesource.com FALSE / TRUE 2147483647 o git-johndoe.example.com=54321 219 .googlesource.com FALSE / TRUE 2147483647 o git-johndoe.example.com=12321 220 ` 221 got, err := parseGitCookieFile(strings.NewReader(gitCookieFileContent)) 222 expected := map[string]*credentials{ 223 "vanadium.googlesource.com": { 224 username: "git-johndoe.example.com", 225 password: "12345", 226 }, 227 "vanadium-review.googlesource.com": { 228 username: "git-johndoe.example.com", 229 password: "54321", 230 }, 231 ".googlesource.com": { 232 username: "git-johndoe.example.com", 233 password: "12321", 234 }, 235 } 236 if err != nil { 237 t.Fatalf("want no errors, got: %v", err) 238 } 239 if !reflect.DeepEqual(expected, got) { 240 t.Fatalf("want: %#v, got: %#v", expected, got) 241 } 242 } 243 244 func TestParseInvalidGitCookieFile(t *testing.T) { 245 t.Parallel() 246 // Content with invalid entries which should be skipped. 247 gitCookieFileContentWithInvalidEntries := ` 248 vanadium.googlesource.com FALSE / TRUE 2147483647 o git-johndoe.example.com 249 vanadium-review.googlesource.com FALSE / TRUE 2147483647 o git-johndoe.example.com=54321 250 vanadium.googlesource.com FALSE / TRUE 2147483647 o git-johndoe.example.com=12345 251 vanadium-review.googlesource.com FALSE / TRUE 2147483647 o 252 ` 253 got, err := parseGitCookieFile(strings.NewReader(gitCookieFileContentWithInvalidEntries)) 254 expected := map[string]*credentials{ 255 "vanadium.googlesource.com": { 256 username: "git-johndoe.example.com", 257 password: "12345", 258 }, 259 } 260 if err != nil { 261 t.Fatalf("want no errors, got: %v", err) 262 } 263 if !reflect.DeepEqual(expected, got) { 264 t.Fatalf("want: %#v, got: %#v", expected, got) 265 } 266 } 267 268 func TestParseValidNetRcFile(t *testing.T) { 269 t.Parallel() 270 // Valid content. 271 netrcFileContent := ` 272 machine vanadium.googlesource.com login git-johndoe.example.com password 12345 273 machine vanadium-review.googlesource.com login git-johndoe.example.com password 54321 274 ` 275 got, err := parseNetrcFile(strings.NewReader(netrcFileContent)) 276 expected := map[string]*credentials{ 277 "vanadium.googlesource.com": { 278 username: "git-johndoe.example.com", 279 password: "12345", 280 }, 281 "vanadium-review.googlesource.com": { 282 username: "git-johndoe.example.com", 283 password: "54321", 284 }, 285 } 286 if err != nil { 287 t.Fatalf("want no errors, got: %v", err) 288 } 289 if !reflect.DeepEqual(expected, got) { 290 t.Fatalf("want: %#v, got: %#v", expected, got) 291 } 292 } 293 294 func TestParseInvalidNetRcFile(t *testing.T) { 295 t.Parallel() 296 // Content with invalid entries which should be skipped. 297 netRcFileContentWithInvalidEntries := ` 298 machine vanadium.googlesource.com login git-johndoe.example.com password 299 machine_blah vanadium3.googlesource.com login git-johndoe.example.com password 12345 300 machine vanadium2.googlesource.com login_blah git-johndoe.example.com password 12345 301 machine vanadium4.googlesource.com login git-johndoe.example.com password_blah 12345 302 machine vanadium-review.googlesource.com login git-johndoe.example.com password 54321 303 ` 304 got, err := parseNetrcFile(strings.NewReader(netRcFileContentWithInvalidEntries)) 305 expected := map[string]*credentials{ 306 "vanadium-review.googlesource.com": { 307 username: "git-johndoe.example.com", 308 password: "54321", 309 }, 310 } 311 if err != nil { 312 t.Fatalf("want no errors, got: %v", err) 313 } 314 if !reflect.DeepEqual(expected, got) { 315 t.Fatalf("want: %#v, got: %#v", expected, got) 316 } 317 } 318 319 func TestParseRefString(t *testing.T) { 320 t.Parallel() 321 type testCase struct { 322 ref string 323 expectErr bool 324 expectedCL int 325 expectedPatchSet int 326 } 327 testCases := []testCase{ 328 // Normal case 329 { 330 ref: "ref/changes/12/3412/2", 331 expectedCL: 3412, 332 expectedPatchSet: 2, 333 }, 334 // Error cases 335 { 336 ref: "ref/123", 337 expectErr: true, 338 }, 339 { 340 ref: "ref/changes/12/a/2", 341 expectErr: true, 342 }, 343 { 344 ref: "ref/changes/12/3412/a", 345 expectErr: true, 346 }, 347 } 348 for _, test := range testCases { 349 cl, patchset, err := ParseRefString(test.ref) 350 if test.expectErr { 351 if err == nil { 352 t.Fatalf("want errors, got: %v", err) 353 } 354 } else { 355 if err != nil { 356 t.Fatalf("want no errors, got: %v", err) 357 } 358 if cl != test.expectedCL { 359 t.Fatalf("want %v, got %v", test.expectedCL, cl) 360 } 361 if patchset != test.expectedPatchSet { 362 t.Fatalf("want %v, got %v", test.expectedPatchSet, patchset) 363 } 364 } 365 } 366 } 367 368 func TestReference(t *testing.T) { 369 t.Parallel() 370 testOpts := CLOpts{ 371 RemoteBranch: "main", 372 Labels: []string{"Commit-Queue+1"}, 373 Reviewers: []string{"a@example.com", "b@example.com"}, 374 } 375 gold := "refs/for/main%l=Commit-Queue+1,r=a@example.com,r=b@example.com" 376 ref := Reference(testOpts) 377 if gold != ref { 378 t.Errorf("expecting %q, got %q", gold, ref) 379 } 380 } 381 382 // TODO(jsimsa): Add a test for the hostCredentials function that 383 // exercises the logic that reads the .netrc and git cookie files.