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