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