github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/pkg/ghclient/core_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package ghclient 18 19 import ( 20 "fmt" 21 "testing" 22 "time" 23 24 "github.com/google/go-github/github" 25 ) 26 27 func setForTest(client *Client) { 28 client.retries = 5 29 client.retryInitialBackoff = time.Nanosecond 30 client.tokenReserve = 50 31 } 32 33 // fakeGithub is a fake go-github client that doubles as a test instance representation. This fake 34 // client keeps track of the number of API calls made in order to test retry behavior and also allows 35 // the number of pages of results to be configured. 36 type fakeGithub struct { 37 // name is a string representation of this fakeGithub instance. 38 name string 39 // hits is a count of the number of API calls made to fakeGithub. 40 hits int 41 // hitsBeforeResponse is the number of hits that should be received before fakeGithub responds without error. 42 hitsBeforeResponse int 43 // shouldSucceed indicates if the githubutil client should get a valid response. 44 shouldSucceed bool 45 // pages is the number of pages to return for paginated data. (Should be 1 for non-paginated data) 46 pages int 47 // listOpts is the ListOptions that would be used in the call if the call were real. 48 listOpts github.ListOptions 49 } 50 51 // checkHits verifies that the githubutil client made the correct number of retries before returning. 52 func (f *fakeGithub) checkHits() bool { 53 if f.shouldSucceed { 54 return f.hits-f.pages+1 == f.hitsBeforeResponse 55 } 56 return f.hitsBeforeResponse > f.hits 57 } 58 59 func (f *fakeGithub) call() ([]interface{}, *github.Response, error) { 60 f.hits++ 61 if f.hits >= f.hitsBeforeResponse { 62 return []interface{}{f.listOpts.Page}, 63 &github.Response{Rate: github.Rate{Limit: 5000, Remaining: 1000, Reset: github.Timestamp{Time: time.Now()}}, LastPage: f.pages}, 64 nil 65 } 66 return nil, nil, fmt.Errorf("some error that forces a retry") 67 } 68 69 func TestRetryAndPagination(t *testing.T) { 70 tests := []*fakeGithub{ 71 {name: "no retries", hitsBeforeResponse: 1, shouldSucceed: true, pages: 1}, 72 {name: "max retries", hitsBeforeResponse: 6, shouldSucceed: true, pages: 1}, 73 {name: "1 too many retries needed", hitsBeforeResponse: 7, shouldSucceed: false, pages: 1}, 74 {name: "3 too many retries needed", hitsBeforeResponse: 10, shouldSucceed: false, pages: 1}, 75 {name: "2 pages", hitsBeforeResponse: 1, shouldSucceed: true, pages: 2}, 76 {name: "10 pages", hitsBeforeResponse: 1, shouldSucceed: true, pages: 10}, 77 {name: "2 pages 2 retries", hitsBeforeResponse: 3, shouldSucceed: true, pages: 2}, 78 {name: "10 pages max retries", hitsBeforeResponse: 6, shouldSucceed: true, pages: 10}, 79 {name: "10 pages one too many retries", hitsBeforeResponse: 7, shouldSucceed: false, pages: 10}, 80 } 81 for _, test := range tests { 82 client := &Client{} 83 setForTest(client) 84 pages, err := client.depaginate("retry test", &test.listOpts, test.call) 85 if (err == nil) != test.shouldSucceed { 86 t.Errorf("Retry+Pagination test '%s' failed because the error value was unexpected: %v", test.name, err) 87 } 88 if !test.checkHits() { 89 t.Errorf("Retry+Pagination test '%s' failed with the wrong number of hits: %d", test.name, test.hits) 90 } 91 if test.shouldSucceed && len(pages) != test.pages { 92 t.Errorf("Retry+Pagination test '%s' failed because the number of pages returned was %d instead of %d. Pages returned: %#v", test.name, len(pages), test.pages, pages) 93 } 94 } 95 }