github.com/google/go-github/v74@v74.0.0/github/rate_limit_test.go (about) 1 // Copyright 2023 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "testing" 13 "time" 14 15 "github.com/google/go-cmp/cmp" 16 ) 17 18 func TestRateLimits_String(t *testing.T) { 19 t.Parallel() 20 v := RateLimits{ 21 Core: &Rate{}, 22 Search: &Rate{}, 23 GraphQL: &Rate{}, 24 IntegrationManifest: &Rate{}, 25 SourceImport: &Rate{}, 26 CodeScanningUpload: &Rate{}, 27 ActionsRunnerRegistration: &Rate{}, 28 SCIM: &Rate{}, 29 DependencySnapshots: &Rate{}, 30 CodeSearch: &Rate{}, 31 AuditLog: &Rate{}, 32 } 33 want := `github.RateLimits{Core:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, Search:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, GraphQL:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, IntegrationManifest:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, SourceImport:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, CodeScanningUpload:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, ActionsRunnerRegistration:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, SCIM:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, DependencySnapshots:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, CodeSearch:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}, AuditLog:github.Rate{Limit:0, Remaining:0, Used:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, Resource:""}}` 34 if got := v.String(); got != want { 35 t.Errorf("RateLimits.String = %v, want %v", got, want) 36 } 37 } 38 39 func TestRateLimits(t *testing.T) { 40 t.Parallel() 41 client, mux, _ := setup(t) 42 43 mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, r *http.Request) { 44 testMethod(t, r, "GET") 45 fmt.Fprint(w, `{"resources":{ 46 "core": {"limit":2,"remaining":1,"used":1,"reset":1372700873}, 47 "search": {"limit":3,"remaining":2,"used":1,"reset":1372700874}, 48 "graphql": {"limit":4,"remaining":3,"used":1,"reset":1372700875}, 49 "integration_manifest": {"limit":5,"remaining":4,"used":1,"reset":1372700876}, 50 "source_import": {"limit":6,"remaining":5,"used":1,"reset":1372700877}, 51 "code_scanning_upload": {"limit":7,"remaining":6,"used":1,"reset":1372700878}, 52 "actions_runner_registration": {"limit":8,"remaining":7,"used":1,"reset":1372700879}, 53 "scim": {"limit":9,"remaining":8,"used":1,"reset":1372700880}, 54 "dependency_snapshots": {"limit":10,"remaining":9,"used":1,"reset":1372700881}, 55 "code_search": {"limit":11,"remaining":10,"used":1,"reset":1372700882}, 56 "audit_log": {"limit": 12,"remaining":11,"used":1,"reset":1372700883} 57 }}`) 58 }) 59 60 ctx := context.Background() 61 rate, _, err := client.RateLimit.Get(ctx) 62 if err != nil { 63 t.Errorf("RateLimits returned error: %v", err) 64 } 65 66 want := &RateLimits{ 67 Core: &Rate{ 68 Limit: 2, 69 Remaining: 1, 70 Used: 1, 71 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 53, 0, time.UTC).Local()}, 72 }, 73 Search: &Rate{ 74 Limit: 3, 75 Remaining: 2, 76 Used: 1, 77 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 54, 0, time.UTC).Local()}, 78 }, 79 GraphQL: &Rate{ 80 Limit: 4, 81 Remaining: 3, 82 Used: 1, 83 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 55, 0, time.UTC).Local()}, 84 }, 85 IntegrationManifest: &Rate{ 86 Limit: 5, 87 Remaining: 4, 88 Used: 1, 89 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 56, 0, time.UTC).Local()}, 90 }, 91 SourceImport: &Rate{ 92 Limit: 6, 93 Remaining: 5, 94 Used: 1, 95 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 57, 0, time.UTC).Local()}, 96 }, 97 CodeScanningUpload: &Rate{ 98 Limit: 7, 99 Remaining: 6, 100 Used: 1, 101 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 58, 0, time.UTC).Local()}, 102 }, 103 ActionsRunnerRegistration: &Rate{ 104 Limit: 8, 105 Remaining: 7, 106 Used: 1, 107 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 59, 0, time.UTC).Local()}, 108 }, 109 SCIM: &Rate{ 110 Limit: 9, 111 Remaining: 8, 112 Used: 1, 113 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 00, 0, time.UTC).Local()}, 114 }, 115 DependencySnapshots: &Rate{ 116 Limit: 10, 117 Remaining: 9, 118 Used: 1, 119 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 1, 0, time.UTC).Local()}, 120 }, 121 CodeSearch: &Rate{ 122 Limit: 11, 123 Remaining: 10, 124 Used: 1, 125 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 2, 0, time.UTC).Local()}, 126 }, 127 AuditLog: &Rate{ 128 Limit: 12, 129 Remaining: 11, 130 Used: 1, 131 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 3, 0, time.UTC).Local()}, 132 }, 133 } 134 if !cmp.Equal(rate, want) { 135 t.Errorf("RateLimits returned %+v, want %+v", rate, want) 136 } 137 tests := []struct { 138 category RateLimitCategory 139 rate *Rate 140 }{ 141 { 142 category: CoreCategory, 143 rate: want.Core, 144 }, 145 { 146 category: SearchCategory, 147 rate: want.Search, 148 }, 149 { 150 category: GraphqlCategory, 151 rate: want.GraphQL, 152 }, 153 { 154 category: IntegrationManifestCategory, 155 rate: want.IntegrationManifest, 156 }, 157 { 158 category: SourceImportCategory, 159 rate: want.SourceImport, 160 }, 161 { 162 category: CodeScanningUploadCategory, 163 rate: want.CodeScanningUpload, 164 }, 165 { 166 category: ActionsRunnerRegistrationCategory, 167 rate: want.ActionsRunnerRegistration, 168 }, 169 { 170 category: ScimCategory, 171 rate: want.SCIM, 172 }, 173 { 174 category: DependencySnapshotsCategory, 175 rate: want.DependencySnapshots, 176 }, 177 { 178 category: CodeSearchCategory, 179 rate: want.CodeSearch, 180 }, 181 { 182 category: AuditLogCategory, 183 rate: want.AuditLog, 184 }, 185 } 186 187 for _, tt := range tests { 188 if got, want := client.rateLimits[tt.category], *tt.rate; got != want { 189 t.Errorf("client.rateLimits[%v] is %+v, want %+v", tt.category, got, want) 190 } 191 } 192 } 193 194 func TestRateLimits_coverage(t *testing.T) { 195 t.Parallel() 196 client, _, _ := setup(t) 197 198 ctx := context.Background() 199 200 const methodName = "RateLimits" 201 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 202 _, resp, err := client.RateLimit.Get(ctx) 203 return resp, err 204 }) 205 } 206 207 func TestRateLimits_overQuota(t *testing.T) { 208 t.Parallel() 209 client, mux, _ := setup(t) 210 211 client.rateLimits[CoreCategory] = Rate{ 212 Limit: 1, 213 Remaining: 0, 214 Used: 1, 215 Reset: Timestamp{time.Now().Add(time.Hour).Local()}, 216 } 217 mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, _ *http.Request) { 218 fmt.Fprint(w, `{"resources":{ 219 "core": {"limit":2,"remaining":1,"used":1,"reset":1372700873}, 220 "search": {"limit":3,"remaining":2,"used":1,"reset":1372700874}, 221 "graphql": {"limit":4,"remaining":3,"used":1,"reset":1372700875}, 222 "integration_manifest": {"limit":5,"remaining":4,"used":1,"reset":1372700876}, 223 "source_import": {"limit":6,"remaining":5,"used":1,"reset":1372700877}, 224 "code_scanning_upload": {"limit":7,"remaining":6,"used":1,"reset":1372700878}, 225 "actions_runner_registration": {"limit":8,"remaining":7,"used":1,"reset":1372700879}, 226 "scim": {"limit":9,"remaining":8,"used":1,"reset":1372700880}, 227 "dependency_snapshots": {"limit":10,"remaining":9,"used":1,"reset":1372700881}, 228 "code_search": {"limit":11,"remaining":10,"used":1,"reset":1372700882}, 229 "audit_log": {"limit":12,"remaining":11,"used":1,"reset":1372700883} 230 }}`) 231 }) 232 233 ctx := context.Background() 234 rate, _, err := client.RateLimit.Get(ctx) 235 if err != nil { 236 t.Errorf("RateLimits returned error: %v", err) 237 } 238 239 want := &RateLimits{ 240 Core: &Rate{ 241 Limit: 2, 242 Remaining: 1, 243 Used: 1, 244 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 53, 0, time.UTC).Local()}, 245 }, 246 Search: &Rate{ 247 Limit: 3, 248 Remaining: 2, 249 Used: 1, 250 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 54, 0, time.UTC).Local()}, 251 }, 252 GraphQL: &Rate{ 253 Limit: 4, 254 Remaining: 3, 255 Used: 1, 256 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 55, 0, time.UTC).Local()}, 257 }, 258 IntegrationManifest: &Rate{ 259 Limit: 5, 260 Remaining: 4, 261 Used: 1, 262 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 56, 0, time.UTC).Local()}, 263 }, 264 SourceImport: &Rate{ 265 Limit: 6, 266 Remaining: 5, 267 Used: 1, 268 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 57, 0, time.UTC).Local()}, 269 }, 270 CodeScanningUpload: &Rate{ 271 Limit: 7, 272 Remaining: 6, 273 Used: 1, 274 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 58, 0, time.UTC).Local()}, 275 }, 276 ActionsRunnerRegistration: &Rate{ 277 Limit: 8, 278 Remaining: 7, 279 Used: 1, 280 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 47, 59, 0, time.UTC).Local()}, 281 }, 282 SCIM: &Rate{ 283 Limit: 9, 284 Remaining: 8, 285 Used: 1, 286 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 00, 0, time.UTC).Local()}, 287 }, 288 DependencySnapshots: &Rate{ 289 Limit: 10, 290 Remaining: 9, 291 Used: 1, 292 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 1, 0, time.UTC).Local()}, 293 }, 294 CodeSearch: &Rate{ 295 Limit: 11, 296 Remaining: 10, 297 Used: 1, 298 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 2, 0, time.UTC).Local()}, 299 }, 300 AuditLog: &Rate{ 301 Limit: 12, 302 Remaining: 11, 303 Used: 1, 304 Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 3, 0, time.UTC).Local()}, 305 }, 306 } 307 if !cmp.Equal(rate, want) { 308 t.Errorf("RateLimits returned %+v, want %+v", rate, want) 309 } 310 311 tests := []struct { 312 category RateLimitCategory 313 rate *Rate 314 }{ 315 { 316 category: CoreCategory, 317 rate: want.Core, 318 }, 319 { 320 category: SearchCategory, 321 rate: want.Search, 322 }, 323 { 324 category: GraphqlCategory, 325 rate: want.GraphQL, 326 }, 327 { 328 category: IntegrationManifestCategory, 329 rate: want.IntegrationManifest, 330 }, 331 { 332 category: SourceImportCategory, 333 rate: want.SourceImport, 334 }, 335 { 336 category: CodeScanningUploadCategory, 337 rate: want.CodeScanningUpload, 338 }, 339 { 340 category: ActionsRunnerRegistrationCategory, 341 rate: want.ActionsRunnerRegistration, 342 }, 343 { 344 category: ScimCategory, 345 rate: want.SCIM, 346 }, 347 { 348 category: DependencySnapshotsCategory, 349 rate: want.DependencySnapshots, 350 }, 351 { 352 category: CodeSearchCategory, 353 rate: want.CodeSearch, 354 }, 355 { 356 category: AuditLogCategory, 357 rate: want.AuditLog, 358 }, 359 } 360 for _, tt := range tests { 361 if got, want := client.rateLimits[tt.category], *tt.rate; got != want { 362 t.Errorf("client.rateLimits[%v] is %+v, want %+v", tt.category, got, want) 363 } 364 } 365 } 366 367 func TestRateLimits_Marshal(t *testing.T) { 368 t.Parallel() 369 testJSONMarshal(t, &RateLimits{}, "{}") 370 371 u := &RateLimits{ 372 Core: &Rate{ 373 Limit: 1, 374 Remaining: 1, 375 Used: 0, 376 Reset: Timestamp{referenceTime}, 377 }, 378 Search: &Rate{ 379 Limit: 1, 380 Remaining: 1, 381 Used: 0, 382 Reset: Timestamp{referenceTime}, 383 }, 384 GraphQL: &Rate{ 385 Limit: 1, 386 Remaining: 1, 387 Used: 0, 388 Reset: Timestamp{referenceTime}, 389 }, 390 IntegrationManifest: &Rate{ 391 Limit: 1, 392 Remaining: 1, 393 Used: 0, 394 Reset: Timestamp{referenceTime}, 395 }, 396 SourceImport: &Rate{ 397 Limit: 1, 398 Remaining: 1, 399 Used: 0, 400 Reset: Timestamp{referenceTime}, 401 }, 402 CodeScanningUpload: &Rate{ 403 Limit: 1, 404 Remaining: 1, 405 Used: 0, 406 Reset: Timestamp{referenceTime}, 407 }, 408 ActionsRunnerRegistration: &Rate{ 409 Limit: 1, 410 Remaining: 1, 411 Used: 0, 412 Reset: Timestamp{referenceTime}, 413 }, 414 SCIM: &Rate{ 415 Limit: 1, 416 Remaining: 1, 417 Used: 0, 418 Reset: Timestamp{referenceTime}, 419 }, 420 DependencySnapshots: &Rate{ 421 Limit: 1, 422 Remaining: 1, 423 Used: 0, 424 Reset: Timestamp{referenceTime}, 425 }, 426 CodeSearch: &Rate{ 427 Limit: 1, 428 Remaining: 1, 429 Used: 0, 430 Reset: Timestamp{referenceTime}, 431 }, 432 AuditLog: &Rate{ 433 Limit: 1, 434 Remaining: 1, 435 Used: 0, 436 Reset: Timestamp{referenceTime}, 437 }, 438 } 439 440 want := `{ 441 "core": { 442 "limit": 1, 443 "remaining": 1, 444 "used": 0, 445 "reset": ` + referenceTimeStr + ` 446 }, 447 "search": { 448 "limit": 1, 449 "remaining": 1, 450 "used": 0, 451 "reset": ` + referenceTimeStr + ` 452 }, 453 "graphql": { 454 "limit": 1, 455 "remaining": 1, 456 "used": 0, 457 "reset": ` + referenceTimeStr + ` 458 }, 459 "integration_manifest": { 460 "limit": 1, 461 "remaining": 1, 462 "used": 0, 463 "reset": ` + referenceTimeStr + ` 464 }, 465 "source_import": { 466 "limit": 1, 467 "remaining": 1, 468 "used": 0, 469 "reset": ` + referenceTimeStr + ` 470 }, 471 "code_scanning_upload": { 472 "limit": 1, 473 "remaining": 1, 474 "used": 0, 475 "reset": ` + referenceTimeStr + ` 476 }, 477 "actions_runner_registration": { 478 "limit": 1, 479 "remaining": 1, 480 "used": 0, 481 "reset": ` + referenceTimeStr + ` 482 }, 483 "scim": { 484 "limit": 1, 485 "remaining": 1, 486 "used": 0, 487 "reset": ` + referenceTimeStr + ` 488 }, 489 "dependency_snapshots": { 490 "limit": 1, 491 "remaining": 1, 492 "used": 0, 493 "reset": ` + referenceTimeStr + ` 494 }, 495 "code_search": { 496 "limit": 1, 497 "remaining": 1, 498 "used": 0, 499 "reset": ` + referenceTimeStr + ` 500 }, 501 "audit_log": { 502 "limit": 1, 503 "remaining": 1, 504 "used": 0, 505 "reset": ` + referenceTimeStr + ` 506 } 507 }` 508 509 testJSONMarshal(t, u, want) 510 } 511 512 func TestRate_Marshal(t *testing.T) { 513 t.Parallel() 514 testJSONMarshal(t, &Rate{}, "{}") 515 516 u := &Rate{ 517 Limit: 1, 518 Remaining: 1, 519 Used: 0, 520 Reset: Timestamp{referenceTime}, 521 Resource: "core", 522 } 523 524 want := `{ 525 "limit": 1, 526 "remaining": 1, 527 "used": 0, 528 "reset": ` + referenceTimeStr + `, 529 "resource": "core" 530 }` 531 532 testJSONMarshal(t, u, want) 533 }