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