diff --git a/src/main/java/org/kohsuke/github/GHRateLimit.java b/src/main/java/org/kohsuke/github/GHRateLimit.java index bc41a9a03..917fa3024 100644 --- a/src/main/java/org/kohsuke/github/GHRateLimit.java +++ b/src/main/java/org/kohsuke/github/GHRateLimit.java @@ -219,6 +219,20 @@ public class GHRateLimit { return Objects.hash(getCore(), getSearch(), getGraphQL(), getIntegrationManifest()); } + Record selectRateLimitRecord(String urlPath) { + if (urlPath.equals("/rate_limit")) { + return new UnknownLimitRecord(); + } else if (urlPath.startsWith("/search")) { + return getSearch(); + } else if (urlPath.startsWith("/graphql")) { + return getGraphQL(); + } else if (urlPath.startsWith("/app-manifests")) { + return getIntegrationManifest(); + } else { + return getCore(); + } + } + /** * A limit record used as a placeholder when the the actual limit is not known. *

diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index afbe43e9a..c1bf0d97e 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -108,7 +108,8 @@ public class GitHub { String password, HttpConnector connector, RateLimitHandler rateLimitHandler, - AbuseLimitHandler abuseLimitHandler) throws IOException { + AbuseLimitHandler abuseLimitHandler, + GitHubRateLimitChecker rateLimitChecker) throws IOException { this.client = new GitHubHttpUrlConnectionClient(apiUrl, login, oauthAccessToken, @@ -117,6 +118,7 @@ public class GitHub { connector, rateLimitHandler, abuseLimitHandler, + rateLimitChecker, (myself) -> setMyself(myself)); users = new ConcurrentHashMap<>(); orgs = new ConcurrentHashMap<>(); diff --git a/src/main/java/org/kohsuke/github/GitHubBuilder.java b/src/main/java/org/kohsuke/github/GitHubBuilder.java index 8905a0689..9bfb55218 100644 --- a/src/main/java/org/kohsuke/github/GitHubBuilder.java +++ b/src/main/java/org/kohsuke/github/GitHubBuilder.java @@ -14,6 +14,8 @@ import java.util.Locale; import java.util.Map.Entry; import java.util.Properties; +import javax.annotation.Nonnull; + /** * Configures connection details and produces {@link GitHub}. * @@ -32,6 +34,7 @@ public class GitHubBuilder implements Cloneable { private RateLimitHandler rateLimitHandler = RateLimitHandler.WAIT; private AbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT; + private GitHubRateLimitChecker rateLimitChecker = new GitHubRateLimitChecker(); /** * Instantiates a new Git hub builder. @@ -311,11 +314,22 @@ public class GitHubBuilder implements Cloneable { } /** - * With rate limit handler git hub builder. + * GitHub allots a certain number of requests to each user or application per period of time (usually per hour). The + * number of requests remaining is returned in the response header and can also be requested using + * {@link GitHub#getRateLimit()}. This request per interval is referred to as the "rate limit". When the remaining + * number of requests reaches zero, the next request will return a error. If this happens, the + * {@link RateLimitHandler#onError(IOException, HttpURLConnection)} will be called. + *

+ * NOTE: GitHub treats clients that exceed their rate limit very harshly. If possible, clients should avoid + * exceeding their rate limit. Consider add a {@link RateLimitChecker} to automatically check the rate limit for + * each request and wait if needed. + *

+ * * * @param handler * the handler * @return the git hub builder + * @see #withRateLimitChecker(RateLimitChecker) */ public GitHubBuilder withRateLimitHandler(RateLimitHandler handler) { this.rateLimitHandler = handler; @@ -323,7 +337,9 @@ public class GitHubBuilder implements Cloneable { } /** - * With abuse limit handler git hub builder. + * When a client sends too many requests in a short time span, GitHub may return an error and set a header telling + * the client to not make any more request for some period of time. If this happens, the + * {@link AbuseLimitHandler#onError(IOException, HttpURLConnection)} will be called. * * @param handler * the handler @@ -334,6 +350,27 @@ public class GitHubBuilder implements Cloneable { return this; } + /** + * The {@link RateLimitChecker} is called before each request to check the rate limit and wait if the guard criteria + * are met. This allows for more complex throttling strategies. Also, GitHub prefers that client throttle before + * exceeding their rate limit rather than stopping after they exceed it. + *

+ * Checking your rate limit {@link GitHub#getRateLimit()} does not effect your rate limit, but {@link GitHub} + * instance will attempt to cache and reuse the last see rate limit rather than making a new request. + *

+ * + * @param coreRateLimitChecker + * the {@link RateLimitChecker} for core GitHub API requests + * @return the git hub builder + */ + public GitHubBuilder withRateLimitChecker(@Nonnull RateLimitChecker coreRateLimitChecker) { + this.rateLimitChecker = new GitHubRateLimitChecker(coreRateLimitChecker, + RateLimitChecker.NONE, + RateLimitChecker.NONE, + RateLimitChecker.NONE); + return this; + } + /** * Configures {@linkplain #withConnector(HttpConnector) connector} that uses HTTP library in JRE but use a specific * proxy, instead of the system default one. @@ -365,7 +402,8 @@ public class GitHubBuilder implements Cloneable { password, connector, rateLimitHandler, - abuseLimitHandler); + abuseLimitHandler, + rateLimitChecker); } @Override diff --git a/src/main/java/org/kohsuke/github/GitHubClient.java b/src/main/java/org/kohsuke/github/GitHubClient.java index 155c3e6f7..bb4889933 100644 --- a/src/main/java/org/kohsuke/github/GitHubClient.java +++ b/src/main/java/org/kohsuke/github/GitHubClient.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.introspect.VisibilityChecker; import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.NotNull; import java.io.FileNotFoundException; import java.io.IOException; @@ -64,6 +63,7 @@ abstract class GitHubClient { protected final RateLimitHandler rateLimitHandler; protected final AbuseLimitHandler abuseLimitHandler; + private final GitHubRateLimitChecker rateLimitChecker; private HttpConnector connector; @@ -95,6 +95,7 @@ abstract class GitHubClient { HttpConnector connector, RateLimitHandler rateLimitHandler, AbuseLimitHandler abuseLimitHandler, + GitHubRateLimitChecker rateLimitChecker, Consumer myselfConsumer) throws IOException { if (apiUrl.endsWith("/")) { @@ -124,6 +125,7 @@ abstract class GitHubClient { this.rateLimitHandler = rateLimitHandler; this.abuseLimitHandler = abuseLimitHandler; + this.rateLimitChecker = rateLimitChecker; if (login == null && encodedAuthorization != null && jwtToken == null) { GHMyself myself = fetch(GHMyself.class, "/user"); @@ -336,6 +338,8 @@ abstract class GitHubClient { + " " + request.url().toString()); } + rateLimitChecker.checkRateLimit(this, request); + responseInfo = getResponseInfo(request); noteRateLimit(responseInfo); detectOTPRequired(responseInfo); @@ -366,7 +370,7 @@ abstract class GitHubClient { throw new GHIOException("Ran out of retries for URL: " + request.url().toString()); } - @NotNull + @Nonnull protected abstract GitHubResponse.ResponseInfo getResponseInfo(GitHubRequest request) throws IOException; protected abstract void handleLimitingErrors(@Nonnull GitHubResponse.ResponseInfo responseInfo) throws IOException; @@ -442,7 +446,7 @@ abstract class GitHubClient { /** * Sets the response headers on objects that need it. Ideally this would be handled by the objects themselves, but * currently they do not have access to {@link GitHubResponse.ResponseInfo} after the - * + * * @param responseInfo * the response info * @param readValue diff --git a/src/main/java/org/kohsuke/github/GitHubHttpUrlConnectionClient.java b/src/main/java/org/kohsuke/github/GitHubHttpUrlConnectionClient.java index 80145aa92..f6dfca2f3 100644 --- a/src/main/java/org/kohsuke/github/GitHubHttpUrlConnectionClient.java +++ b/src/main/java/org/kohsuke/github/GitHubHttpUrlConnectionClient.java @@ -1,7 +1,6 @@ package org.kohsuke.github; import org.apache.commons.io.IOUtils; -import org.jetbrains.annotations.NotNull; import java.io.IOException; import java.io.InputStream; @@ -41,6 +40,7 @@ class GitHubHttpUrlConnectionClient extends GitHubClient { HttpConnector connector, RateLimitHandler rateLimitHandler, AbuseLimitHandler abuseLimitHandler, + GitHubRateLimitChecker rateLimitChecker, Consumer myselfConsumer) throws IOException { super(apiUrl, login, @@ -50,10 +50,11 @@ class GitHubHttpUrlConnectionClient extends GitHubClient { connector, rateLimitHandler, abuseLimitHandler, + rateLimitChecker, myselfConsumer); } - @NotNull + @Nonnull protected GitHubResponse.ResponseInfo getResponseInfo(GitHubRequest request) throws IOException { HttpURLConnection connection; try { diff --git a/src/main/java/org/kohsuke/github/GitHubRateLimitChecker.java b/src/main/java/org/kohsuke/github/GitHubRateLimitChecker.java new file mode 100644 index 000000000..82e48a5a7 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GitHubRateLimitChecker.java @@ -0,0 +1,86 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.util.Objects; + +import javax.annotation.Nonnull; + +class GitHubRateLimitChecker { + + @Nonnull + private final RateLimitChecker core; + + @Nonnull + private final RateLimitChecker search; + + @Nonnull + private final RateLimitChecker graphql; + + @Nonnull + private final RateLimitChecker integrationManifest; + + GitHubRateLimitChecker() { + this(RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE, RateLimitChecker.NONE); + } + + GitHubRateLimitChecker(@Nonnull RateLimitChecker core, + @Nonnull RateLimitChecker search, + @Nonnull RateLimitChecker graphql, + @Nonnull RateLimitChecker integrationManifest) { + this.core = Objects.requireNonNull(core); + + // for now only support rate limiting on core + // remove these asserts when that changes + assert search == RateLimitChecker.NONE; + assert graphql == RateLimitChecker.NONE; + assert integrationManifest == RateLimitChecker.NONE; + + this.search = Objects.requireNonNull(search); + this.graphql = Objects.requireNonNull(graphql); + this.integrationManifest = Objects.requireNonNull(integrationManifest); + } + + void checkRateLimit(GitHubClient client, GitHubRequest request) throws IOException { + RateLimitChecker guard = selectChecker(request); + if (guard == RateLimitChecker.NONE) { + return; + } + + // For the first rate limit, accept the current limit if a valid one is already present. + GHRateLimit rateLimit = client.rateLimit(); + GHRateLimit.Record rateLimitRecord = rateLimit.selectRateLimitRecord(request.urlPath()); + long waitCount = 0; + try { + while (guard.checkRateLimit(rateLimitRecord, waitCount)) { + waitCount++; + + // When rate limit is exceeded, sleep for one additional second beyond when the + // called {@link RateLimitChecker} sleeps. + // Reset time is only accurate to the second, so adding a one second buffer for safety is a good idea. + // This also keeps polling clients from querying too often. + Thread.sleep(1000); + + // After the first wait, always request a new rate limit from the server. + rateLimit = client.getRateLimit(); + rateLimitRecord = rateLimit.selectRateLimitRecord(request.urlPath()); + } + } catch (InterruptedException e) { + throw (IOException) new InterruptedIOException(e.getMessage()).initCause(e); + } + } + + private RateLimitChecker selectChecker(GitHubRequest request) { + if (request.urlPath().equals("/rate_limit")) { + return RateLimitChecker.NONE; + } else if (request.urlPath().startsWith("/search")) { + return search; + } else if (request.urlPath().startsWith("/graphql")) { + return graphql; + } else if (request.urlPath().startsWith("/app-manifests")) { + return integrationManifest; + } else { + return core; + } + } +} diff --git a/src/main/java/org/kohsuke/github/RateLimitChecker.java b/src/main/java/org/kohsuke/github/RateLimitChecker.java new file mode 100644 index 000000000..a292fb666 --- /dev/null +++ b/src/main/java/org/kohsuke/github/RateLimitChecker.java @@ -0,0 +1,76 @@ +package org.kohsuke.github; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * A GitHub API Rate Limit Guard + *

+ *

+ */ +public abstract class RateLimitChecker { + + private static final Logger LOGGER = Logger.getLogger(RateLimitChecker.class.getName()); + + public static final RateLimitChecker NONE = new RateLimitChecker() { + @Override + protected boolean checkRateLimit(GHRateLimit.Record record, long count) { + return false; + } + }; + + /** + * Decides what action to take given a rate limit record. Generally this will be to sleep or not. + * + * The caller of this method figures out which {@link GHRateLimit.Record} applies for the current request. + * + * @param rateLimitRecord + * the current {@link GHRateLimit.Record} to check against. + * @param count + * the number of times in a row this wait method has been called. + */ + protected abstract boolean checkRateLimit(GHRateLimit.Record rateLimitRecord, long count) + throws InterruptedException; + + protected final boolean sleepUntilReset(GHRateLimit.Record record) throws InterruptedException { + // Sleep until reset + long sleepMilliseconds = record.getResetDate().getTime() - System.currentTimeMillis(); + if (sleepMilliseconds > 0) { + String message = String.format( + "GitHub API - Current quota has %d remaining of %d. Waiting for quota to reset at %tT.", + record.getRemaining(), + record.getLimit(), + record.getResetDate()); + + LOGGER.log(Level.INFO, message); + + Thread.sleep(sleepMilliseconds); + return true; + } + return false; + } + + /** + * A {@link RateLimitChecker} with a simple number as the limit. + */ + public static class LiteralValue extends RateLimitChecker { + private final int sleepAtOrBelow; + + public LiteralValue(int sleepAtOrBelow) { + if (sleepAtOrBelow < 0) { + throw new IllegalArgumentException("sleepAtOrBelow must >= 0"); + } + this.sleepAtOrBelow = sleepAtOrBelow; + } + + @Override + protected boolean checkRateLimit(GHRateLimit.Record record, long count) throws InterruptedException { + if (record.getRemaining() <= sleepAtOrBelow) { + return sleepUntilReset(record); + } + return false; + } + + } + +} diff --git a/src/test/java/org/kohsuke/github/RateLimitCheckerTest.java b/src/test/java/org/kohsuke/github/RateLimitCheckerTest.java new file mode 100644 index 000000000..5128f58a4 --- /dev/null +++ b/src/test/java/org/kohsuke/github/RateLimitCheckerTest.java @@ -0,0 +1,129 @@ +package org.kohsuke.github; + +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; +import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.HandlebarsCurrentDateHelper; +import org.junit.Test; +import wiremock.com.github.jknack.handlebars.Helper; +import wiremock.com.github.jknack.handlebars.Options; + +import java.io.IOException; +import java.util.Date; + +import static org.hamcrest.CoreMatchers.*; + +/** + * Test showing the behavior of OkHttpConnector with and without cache. + *

+ * Key take aways: + * + *

+ * + * @author Liam Newman + */ +public class RateLimitCheckerTest extends AbstractGitHubWireMockTest { + + GHRateLimit rateLimit = null; + GHRateLimit previousLimit = null; + Date testStartDate = new Date(); + + public RateLimitCheckerTest() { + useDefaultGitHub = false; + } + + @Override + protected WireMockConfiguration getWireMockOptions() { + + return super.getWireMockOptions().extensions(ResponseTemplateTransformer.builder() + .global(true) + .maxCacheEntries(0L) + .helper("testStartDate", new Helper() { + private HandlebarsCurrentDateHelper helper = new HandlebarsCurrentDateHelper(); + @Override + public Object apply(final Object context, final Options options) throws IOException { + return this.helper.apply(RateLimitCheckerTest.this.testStartDate, options); + } + }) + .build()); + } + + @Test + public void testGitHubRateLimit() throws Exception { + // Customized response that templates the date to keep things working + // snapshotNotAllowed(); + + assertThat(mockGitHub.getRequestCount(), equalTo(0)); + + // // 4897 is just the what the limit was when the snapshot was taken + // previousLimit = GHRateLimit + // .fromHeaderRecord(new GHRateLimit.Record(5000, 4897, System.currentTimeMillis() / 1000L)); + + // Give this a moment + Thread.sleep(1000); + + testStartDate = new Date(); + // ------------------------------------------------------------- + // /user gets response with rate limit information + gitHub = getGitHubBuilder().withRateLimitChecker(new RateLimitChecker.LiteralValue(4500)) + .withEndpoint(mockGitHub.apiServer().baseUrl()) + .build(); + + assertThat(gitHub.lastRateLimit(), nullValue()); + + // Checks the rate limit before getting myself + gitHub.getMyself(); + updateTestRateLimit(); + assertThat(mockGitHub.getRequestCount(), equalTo(2)); + assertThat(rateLimit.getCore().getRemaining(), equalTo(4501)); + + // Should succeed without querying rate limit + // Also due to earlier reset date, new value is ignored. + GHOrganization org = gitHub.getOrganization("github-api-test-org"); + updateTestRateLimit(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); + assertThat(rateLimit.getCore().getRemaining(), equalTo(4501)); + assertThat(rateLimit, sameInstance(previousLimit)); + + // uses the existing header rate limit + // This request's header sets the limit at quota + org.getRepository("github-api"); + updateTestRateLimit(); + assertThat(mockGitHub.getRequestCount(), equalTo(4)); + assertThat(rateLimit.getCore().getRemaining(), equalTo(4500)); + + // Due to previous request header, this request has to wait for reset + // results in an additional request + org.getRepository("github-api"); + updateTestRateLimit(); + assertThat(mockGitHub.getRequestCount(), equalTo(6)); + assertThat(rateLimit.getCore().getRemaining(), equalTo(4400)); + + // Due to previous request header, this request has to wait for reset + // results in two additional requests because even after first reset we're still outside quota + org.getRepository("github-api"); + updateTestRateLimit(); + assertThat(mockGitHub.getRequestCount(), equalTo(9)); + assertThat(rateLimit.getCore().getRemaining(), equalTo(4601)); + } + + protected void updateTestRateLimit() { + previousLimit = rateLimit; + rateLimit = gitHub.lastRateLimit(); + } + + private static GHRepository getRepository(GitHub gitHub) throws IOException { + return gitHub.getOrganization("github-api-test-org").getRepository("github-api"); + } + +} diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/orgs_github-api-test-org-4c3594ea-179b-418f-b590-72e9a9a48494.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/orgs_github-api-test-org-4c3594ea-179b-418f-b590-72e9a9a48494.json new file mode 100644 index 000000000..8f7c61093 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/orgs_github-api-test-org-4c3594ea-179b-418f-b590-72e9a9a48494.json @@ -0,0 +1,41 @@ +{ + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "url": "https://api.github.com/orgs/github-api-test-org", + "repos_url": "https://api.github.com/orgs/github-api-test-org/repos", + "events_url": "https://api.github.com/orgs/github-api-test-org/events", + "hooks_url": "https://api.github.com/orgs/github-api-test-org/hooks", + "issues_url": "https://api.github.com/orgs/github-api-test-org/issues", + "members_url": "https://api.github.com/orgs/github-api-test-org/members{/member}", + "public_members_url": "https://api.github.com/orgs/github-api-test-org/public_members{/member}", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "description": null, + "is_verified": false, + "has_organization_projects": true, + "has_repository_projects": true, + "public_repos": 11, + "public_gists": 0, + "followers": 0, + "following": 0, + "html_url": "https://github.com/github-api-test-org", + "created_at": "2014-05-10T19:39:11Z", + "updated_at": "2015-04-20T00:42:30Z", + "type": "Organization", + "total_private_repos": 0, + "owned_private_repos": 0, + "private_gists": 0, + "disk_usage": 147, + "collaborators": 0, + "billing_email": "kk@kohsuke.org", + "default_repository_permission": "none", + "members_can_create_repositories": false, + "two_factor_requirement_enabled": false, + "plan": { + "name": "free", + "space": 976562499, + "private_repos": 0, + "filled_seats": 12, + "seats": 0 + } +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-12f5b993-ee6d-470b-bd7a-016bbdbe42e8.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-12f5b993-ee6d-470b-bd7a-016bbdbe42e8.json new file mode 100644 index 000000000..9532d26a0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-12f5b993-ee6d-470b-bd7a-016bbdbe42e8.json @@ -0,0 +1,332 @@ +{ + "id": 206888201, + "node_id": "MDEwOlJlcG9zaXRvcnkyMDY4ODgyMDE=", + "name": "github-api", + "full_name": "github-api-test-org/github-api", + "private": false, + "owner": { + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api-test-org", + "html_url": "https://github.com/github-api-test-org", + "followers_url": "https://api.github.com/users/github-api-test-org/followers", + "following_url": "https://api.github.com/users/github-api-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/github-api-test-org/orgs", + "repos_url": "https://api.github.com/users/github-api-test-org/repos", + "events_url": "https://api.github.com/users/github-api-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api-test-org/github-api", + "description": "Tricky", + "fork": true, + "url": "https://api.github.com/repos/github-api-test-org/github-api", + "forks_url": "https://api.github.com/repos/github-api-test-org/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/github-api/deployments", + "created_at": "2019-09-06T23:26:04Z", + "updated_at": "2020-01-16T21:22:56Z", + "pushed_at": "2020-01-18T00:47:43Z", + "git_url": "git://github.com/github-api-test-org/github-api.git", + "ssh_url": "git@github.com:github-api-test-org/github-api.git", + "clone_url": "https://github.com/github-api-test-org/github-api.git", + "svn_url": "https://github.com/github-api-test-org/github-api", + "homepage": "http://github-api.kohsuke.org/", + "size": 11414, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 3, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 0, + "open_issues": 3, + "watchers": 0, + "default_branch": "master", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "temp_clone_token": "", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "delete_branch_on_merge": false, + "organization": { + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api-test-org", + "html_url": "https://github.com/github-api-test-org", + "followers_url": "https://api.github.com/users/github-api-test-org/followers", + "following_url": "https://api.github.com/users/github-api-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/github-api-test-org/orgs", + "repos_url": "https://api.github.com/users/github-api-test-org/repos", + "events_url": "https://api.github.com/users/github-api-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "parent": { + "id": 617210, + "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=", + "name": "github-api", + "full_name": "github-api/github-api", + "private": false, + "owner": { + "login": "github-api", + "id": 54909825, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1", + "avatar_url": "https://avatars3.githubusercontent.com/u/54909825?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api", + "html_url": "https://github.com/github-api", + "followers_url": "https://api.github.com/users/github-api/followers", + "following_url": "https://api.github.com/users/github-api/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api/subscriptions", + "organizations_url": "https://api.github.com/users/github-api/orgs", + "repos_url": "https://api.github.com/users/github-api/repos", + "events_url": "https://api.github.com/users/github-api/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api/github-api", + "description": "Java API for GitHub", + "fork": false, + "url": "https://api.github.com/repos/github-api/github-api", + "forks_url": "https://api.github.com/repos/github-api/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api/github-api/deployments", + "created_at": "2010-04-19T04:13:03Z", + "updated_at": "2020-02-20T00:01:44Z", + "pushed_at": "2020-02-20T00:01:51Z", + "git_url": "git://github.com/github-api/github-api.git", + "ssh_url": "git@github.com:github-api/github-api.git", + "clone_url": "https://github.com/github-api/github-api.git", + "svn_url": "https://github.com/github-api/github-api", + "homepage": "https://github-api.kohsuke.org/", + "size": 19361, + "stargazers_count": 613, + "watchers_count": 613, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 454, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 454, + "open_issues": 56, + "watchers": 613, + "default_branch": "master" + }, + "source": { + "id": 617210, + "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=", + "name": "github-api", + "full_name": "github-api/github-api", + "private": false, + "owner": { + "login": "github-api", + "id": 54909825, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1", + "avatar_url": "https://avatars3.githubusercontent.com/u/54909825?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api", + "html_url": "https://github.com/github-api", + "followers_url": "https://api.github.com/users/github-api/followers", + "following_url": "https://api.github.com/users/github-api/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api/subscriptions", + "organizations_url": "https://api.github.com/users/github-api/orgs", + "repos_url": "https://api.github.com/users/github-api/repos", + "events_url": "https://api.github.com/users/github-api/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api/github-api", + "description": "Java API for GitHub", + "fork": false, + "url": "https://api.github.com/repos/github-api/github-api", + "forks_url": "https://api.github.com/repos/github-api/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api/github-api/deployments", + "created_at": "2010-04-19T04:13:03Z", + "updated_at": "2020-02-20T00:01:44Z", + "pushed_at": "2020-02-20T00:01:51Z", + "git_url": "git://github.com/github-api/github-api.git", + "ssh_url": "git@github.com:github-api/github-api.git", + "clone_url": "https://github.com/github-api/github-api.git", + "svn_url": "https://github.com/github-api/github-api", + "homepage": "https://github-api.kohsuke.org/", + "size": 19361, + "stargazers_count": 613, + "watchers_count": 613, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 454, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 454, + "open_issues": 56, + "watchers": 613, + "default_branch": "master" + }, + "network_count": 454, + "subscribers_count": 0 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-1b4d33fb-f043-4d57-ac9a-0e2aa6d72c49.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-1b4d33fb-f043-4d57-ac9a-0e2aa6d72c49.json new file mode 100644 index 000000000..9532d26a0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-1b4d33fb-f043-4d57-ac9a-0e2aa6d72c49.json @@ -0,0 +1,332 @@ +{ + "id": 206888201, + "node_id": "MDEwOlJlcG9zaXRvcnkyMDY4ODgyMDE=", + "name": "github-api", + "full_name": "github-api-test-org/github-api", + "private": false, + "owner": { + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api-test-org", + "html_url": "https://github.com/github-api-test-org", + "followers_url": "https://api.github.com/users/github-api-test-org/followers", + "following_url": "https://api.github.com/users/github-api-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/github-api-test-org/orgs", + "repos_url": "https://api.github.com/users/github-api-test-org/repos", + "events_url": "https://api.github.com/users/github-api-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api-test-org/github-api", + "description": "Tricky", + "fork": true, + "url": "https://api.github.com/repos/github-api-test-org/github-api", + "forks_url": "https://api.github.com/repos/github-api-test-org/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/github-api/deployments", + "created_at": "2019-09-06T23:26:04Z", + "updated_at": "2020-01-16T21:22:56Z", + "pushed_at": "2020-01-18T00:47:43Z", + "git_url": "git://github.com/github-api-test-org/github-api.git", + "ssh_url": "git@github.com:github-api-test-org/github-api.git", + "clone_url": "https://github.com/github-api-test-org/github-api.git", + "svn_url": "https://github.com/github-api-test-org/github-api", + "homepage": "http://github-api.kohsuke.org/", + "size": 11414, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 3, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 0, + "open_issues": 3, + "watchers": 0, + "default_branch": "master", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "temp_clone_token": "", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "delete_branch_on_merge": false, + "organization": { + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api-test-org", + "html_url": "https://github.com/github-api-test-org", + "followers_url": "https://api.github.com/users/github-api-test-org/followers", + "following_url": "https://api.github.com/users/github-api-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/github-api-test-org/orgs", + "repos_url": "https://api.github.com/users/github-api-test-org/repos", + "events_url": "https://api.github.com/users/github-api-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "parent": { + "id": 617210, + "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=", + "name": "github-api", + "full_name": "github-api/github-api", + "private": false, + "owner": { + "login": "github-api", + "id": 54909825, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1", + "avatar_url": "https://avatars3.githubusercontent.com/u/54909825?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api", + "html_url": "https://github.com/github-api", + "followers_url": "https://api.github.com/users/github-api/followers", + "following_url": "https://api.github.com/users/github-api/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api/subscriptions", + "organizations_url": "https://api.github.com/users/github-api/orgs", + "repos_url": "https://api.github.com/users/github-api/repos", + "events_url": "https://api.github.com/users/github-api/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api/github-api", + "description": "Java API for GitHub", + "fork": false, + "url": "https://api.github.com/repos/github-api/github-api", + "forks_url": "https://api.github.com/repos/github-api/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api/github-api/deployments", + "created_at": "2010-04-19T04:13:03Z", + "updated_at": "2020-02-20T00:01:44Z", + "pushed_at": "2020-02-20T00:01:51Z", + "git_url": "git://github.com/github-api/github-api.git", + "ssh_url": "git@github.com:github-api/github-api.git", + "clone_url": "https://github.com/github-api/github-api.git", + "svn_url": "https://github.com/github-api/github-api", + "homepage": "https://github-api.kohsuke.org/", + "size": 19361, + "stargazers_count": 613, + "watchers_count": 613, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 454, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 454, + "open_issues": 56, + "watchers": 613, + "default_branch": "master" + }, + "source": { + "id": 617210, + "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=", + "name": "github-api", + "full_name": "github-api/github-api", + "private": false, + "owner": { + "login": "github-api", + "id": 54909825, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1", + "avatar_url": "https://avatars3.githubusercontent.com/u/54909825?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api", + "html_url": "https://github.com/github-api", + "followers_url": "https://api.github.com/users/github-api/followers", + "following_url": "https://api.github.com/users/github-api/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api/subscriptions", + "organizations_url": "https://api.github.com/users/github-api/orgs", + "repos_url": "https://api.github.com/users/github-api/repos", + "events_url": "https://api.github.com/users/github-api/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api/github-api", + "description": "Java API for GitHub", + "fork": false, + "url": "https://api.github.com/repos/github-api/github-api", + "forks_url": "https://api.github.com/repos/github-api/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api/github-api/deployments", + "created_at": "2010-04-19T04:13:03Z", + "updated_at": "2020-02-20T00:01:44Z", + "pushed_at": "2020-02-20T00:01:51Z", + "git_url": "git://github.com/github-api/github-api.git", + "ssh_url": "git@github.com:github-api/github-api.git", + "clone_url": "https://github.com/github-api/github-api.git", + "svn_url": "https://github.com/github-api/github-api", + "homepage": "https://github-api.kohsuke.org/", + "size": 19361, + "stargazers_count": 613, + "watchers_count": 613, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 454, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 454, + "open_issues": 56, + "watchers": 613, + "default_branch": "master" + }, + "network_count": 454, + "subscribers_count": 0 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-7c83f0f2-98d8-4cea-b681-56f37210c2dc.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-7c83f0f2-98d8-4cea-b681-56f37210c2dc.json new file mode 100644 index 000000000..9532d26a0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/repos_github-api-test-org_github-api-7c83f0f2-98d8-4cea-b681-56f37210c2dc.json @@ -0,0 +1,332 @@ +{ + "id": 206888201, + "node_id": "MDEwOlJlcG9zaXRvcnkyMDY4ODgyMDE=", + "name": "github-api", + "full_name": "github-api-test-org/github-api", + "private": false, + "owner": { + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api-test-org", + "html_url": "https://github.com/github-api-test-org", + "followers_url": "https://api.github.com/users/github-api-test-org/followers", + "following_url": "https://api.github.com/users/github-api-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/github-api-test-org/orgs", + "repos_url": "https://api.github.com/users/github-api-test-org/repos", + "events_url": "https://api.github.com/users/github-api-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api-test-org/github-api", + "description": "Tricky", + "fork": true, + "url": "https://api.github.com/repos/github-api-test-org/github-api", + "forks_url": "https://api.github.com/repos/github-api-test-org/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/github-api/deployments", + "created_at": "2019-09-06T23:26:04Z", + "updated_at": "2020-01-16T21:22:56Z", + "pushed_at": "2020-01-18T00:47:43Z", + "git_url": "git://github.com/github-api-test-org/github-api.git", + "ssh_url": "git@github.com:github-api-test-org/github-api.git", + "clone_url": "https://github.com/github-api-test-org/github-api.git", + "svn_url": "https://github.com/github-api-test-org/github-api", + "homepage": "http://github-api.kohsuke.org/", + "size": 11414, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 3, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 0, + "open_issues": 3, + "watchers": 0, + "default_branch": "master", + "permissions": { + "admin": true, + "push": true, + "pull": true + }, + "temp_clone_token": "", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "delete_branch_on_merge": false, + "organization": { + "login": "github-api-test-org", + "id": 7544739, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=", + "avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api-test-org", + "html_url": "https://github.com/github-api-test-org", + "followers_url": "https://api.github.com/users/github-api-test-org/followers", + "following_url": "https://api.github.com/users/github-api-test-org/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api-test-org/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api-test-org/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api-test-org/subscriptions", + "organizations_url": "https://api.github.com/users/github-api-test-org/orgs", + "repos_url": "https://api.github.com/users/github-api-test-org/repos", + "events_url": "https://api.github.com/users/github-api-test-org/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api-test-org/received_events", + "type": "Organization", + "site_admin": false + }, + "parent": { + "id": 617210, + "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=", + "name": "github-api", + "full_name": "github-api/github-api", + "private": false, + "owner": { + "login": "github-api", + "id": 54909825, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1", + "avatar_url": "https://avatars3.githubusercontent.com/u/54909825?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api", + "html_url": "https://github.com/github-api", + "followers_url": "https://api.github.com/users/github-api/followers", + "following_url": "https://api.github.com/users/github-api/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api/subscriptions", + "organizations_url": "https://api.github.com/users/github-api/orgs", + "repos_url": "https://api.github.com/users/github-api/repos", + "events_url": "https://api.github.com/users/github-api/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api/github-api", + "description": "Java API for GitHub", + "fork": false, + "url": "https://api.github.com/repos/github-api/github-api", + "forks_url": "https://api.github.com/repos/github-api/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api/github-api/deployments", + "created_at": "2010-04-19T04:13:03Z", + "updated_at": "2020-02-20T00:01:44Z", + "pushed_at": "2020-02-20T00:01:51Z", + "git_url": "git://github.com/github-api/github-api.git", + "ssh_url": "git@github.com:github-api/github-api.git", + "clone_url": "https://github.com/github-api/github-api.git", + "svn_url": "https://github.com/github-api/github-api", + "homepage": "https://github-api.kohsuke.org/", + "size": 19361, + "stargazers_count": 613, + "watchers_count": 613, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 454, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 454, + "open_issues": 56, + "watchers": 613, + "default_branch": "master" + }, + "source": { + "id": 617210, + "node_id": "MDEwOlJlcG9zaXRvcnk2MTcyMTA=", + "name": "github-api", + "full_name": "github-api/github-api", + "private": false, + "owner": { + "login": "github-api", + "id": 54909825, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjU0OTA5ODI1", + "avatar_url": "https://avatars3.githubusercontent.com/u/54909825?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-api", + "html_url": "https://github.com/github-api", + "followers_url": "https://api.github.com/users/github-api/followers", + "following_url": "https://api.github.com/users/github-api/following{/other_user}", + "gists_url": "https://api.github.com/users/github-api/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-api/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-api/subscriptions", + "organizations_url": "https://api.github.com/users/github-api/orgs", + "repos_url": "https://api.github.com/users/github-api/repos", + "events_url": "https://api.github.com/users/github-api/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-api/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/github-api/github-api", + "description": "Java API for GitHub", + "fork": false, + "url": "https://api.github.com/repos/github-api/github-api", + "forks_url": "https://api.github.com/repos/github-api/github-api/forks", + "keys_url": "https://api.github.com/repos/github-api/github-api/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api/github-api/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api/github-api/teams", + "hooks_url": "https://api.github.com/repos/github-api/github-api/hooks", + "issue_events_url": "https://api.github.com/repos/github-api/github-api/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api/github-api/events", + "assignees_url": "https://api.github.com/repos/github-api/github-api/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api/github-api/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api/github-api/tags", + "blobs_url": "https://api.github.com/repos/github-api/github-api/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api/github-api/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api/github-api/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api/github-api/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api/github-api/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api/github-api/languages", + "stargazers_url": "https://api.github.com/repos/github-api/github-api/stargazers", + "contributors_url": "https://api.github.com/repos/github-api/github-api/contributors", + "subscribers_url": "https://api.github.com/repos/github-api/github-api/subscribers", + "subscription_url": "https://api.github.com/repos/github-api/github-api/subscription", + "commits_url": "https://api.github.com/repos/github-api/github-api/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api/github-api/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api/github-api/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api/github-api/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api/github-api/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api/github-api/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api/github-api/merges", + "archive_url": "https://api.github.com/repos/github-api/github-api/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api/github-api/downloads", + "issues_url": "https://api.github.com/repos/github-api/github-api/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api/github-api/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api/github-api/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api/github-api/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api/github-api/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api/github-api/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api/github-api/deployments", + "created_at": "2010-04-19T04:13:03Z", + "updated_at": "2020-02-20T00:01:44Z", + "pushed_at": "2020-02-20T00:01:51Z", + "git_url": "git://github.com/github-api/github-api.git", + "ssh_url": "git@github.com:github-api/github-api.git", + "clone_url": "https://github.com/github-api/github-api.git", + "svn_url": "https://github.com/github-api/github-api", + "homepage": "https://github-api.kohsuke.org/", + "size": 19361, + "stargazers_count": 613, + "watchers_count": 613, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 454, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 56, + "license": { + "key": "mit", + "name": "MIT License", + "spdx_id": "MIT", + "url": "https://api.github.com/licenses/mit", + "node_id": "MDc6TGljZW5zZTEz" + }, + "forks": 454, + "open_issues": 56, + "watchers": 613, + "default_branch": "master" + }, + "network_count": 454, + "subscribers_count": 0 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/user-9a879079-539d-4629-b873-8d92967da94c.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/user-9a879079-539d-4629-b873-8d92967da94c.json new file mode 100644 index 000000000..46abb40cc --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/__files/user-9a879079-539d-4629-b873-8d92967da94c.json @@ -0,0 +1,45 @@ +{ + "login": "bitwiseman", + "id": 1958953, + "node_id": "MDQ6VXNlcjE5NTg5NTM=", + "avatar_url": "https://avatars3.githubusercontent.com/u/1958953?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bitwiseman", + "html_url": "https://github.com/bitwiseman", + "followers_url": "https://api.github.com/users/bitwiseman/followers", + "following_url": "https://api.github.com/users/bitwiseman/following{/other_user}", + "gists_url": "https://api.github.com/users/bitwiseman/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bitwiseman/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bitwiseman/subscriptions", + "organizations_url": "https://api.github.com/users/bitwiseman/orgs", + "repos_url": "https://api.github.com/users/bitwiseman/repos", + "events_url": "https://api.github.com/users/bitwiseman/events{/privacy}", + "received_events_url": "https://api.github.com/users/bitwiseman/received_events", + "type": "User", + "site_admin": false, + "name": "Liam Newman", + "company": "Cloudbees, Inc.", + "blog": "", + "location": "Seattle, WA, USA", + "email": "bitwiseman@gmail.com", + "hireable": null, + "bio": "https://twitter.com/bitwiseman", + "public_repos": 181, + "public_gists": 7, + "followers": 147, + "following": 9, + "created_at": "2012-07-11T20:38:33Z", + "updated_at": "2020-02-06T17:29:39Z", + "private_gists": 8, + "total_private_repos": 10, + "owned_private_repos": 0, + "disk_usage": 33697, + "collaborators": 0, + "two_factor_authentication": true, + "plan": { + "name": "free", + "space": 976562499, + "collaborators": 0, + "private_repos": 10000 + } +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/orgs_github-api-test-org-3-4c3594.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/orgs_github-api-test-org-3-4c3594.json new file mode 100644 index 000000000..dced1a1f7 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/orgs_github-api-test-org-3-4c3594.json @@ -0,0 +1,51 @@ +{ + "metadata": { + "comment": "This header rate limit will be ignored because the reset is sooner than existing" + }, + "id": "4c3594ea-179b-418f-b590-72e9a9a48494", + "name": "orgs_github-api-test-org", + "request": { + "url": "/orgs/github-api-test-org", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "orgs_github-api-test-org-4c3594ea-179b-418f-b590-72e9a9a48494.json", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4400", + "X-RateLimit-Reset": "{{testStartDate offset='4 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"75d6d979ad0098ece26e54f88ea58d8c\"", + "Last-Modified": "Mon, 20 Apr 2015 00:42:30 GMT", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F8AD:9836:A3F7D9:C516A2:5E4DF170" + } + }, + "uuid": "4c3594ea-179b-418f-b590-72e9a9a48494", + "persistent": true, + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-1-1d5336.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-1-1d5336.json new file mode 100644 index 000000000..7224f87f6 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-1-1d5336.json @@ -0,0 +1,49 @@ +{ + "metadata": { + "comment": "4502" + }, + "id": "1d53365c-bbfd-409e-a07a-3dbf9ac73cb0", + "name": "rate_limit", + "request": { + "url": "/rate_limit", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "body": "{\"resources\": {\"core\": {\"limit\": 5000,\"remaining\": 4502,\"reset\": {{testStartDate offset='5 seconds' format='unix'}} },\"search\": {\"limit\": 30,\"remaining\": 30,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"graphql\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"integration_manifest\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} } },\"rate\": {\"limit\": 5000,\"remaining\": 0,\"reset\": 1570478899}}", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4502", + "X-RateLimit-Reset": "{{testStartDate offset='5 seconds' format='unix'}}", + "Cache-Control": "no-cache", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "Vary": "Accept-Encoding, Accept, X-Requested-With", + "X-GitHub-Request-Id": "F8AD:9836:A3F7BC:C51684:5E4DF16F" + } + }, + "uuid": "1d53365c-bbfd-409e-a07a-3dbf9ac73cb0", + "persistent": true, + "scenarioName": "scenario-1-rate_limit", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-rate_limit-2", + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-5-9ad306.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-5-9ad306.json new file mode 100644 index 000000000..a3893a14d --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-5-9ad306.json @@ -0,0 +1,49 @@ +{ + "metadata": { + "comment": "" + }, + "id": "9ad3064d-ae78-4fc6-a6bc-20386f446f5e", + "name": "rate_limit", + "request": { + "url": "/rate_limit", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "body": "{\"resources\": {\"core\": {\"limit\": 5000,\"remaining\": 4600,\"reset\": {{testStartDate offset='10 seconds' format='unix'}} },\"search\": {\"limit\": 30,\"remaining\": 30,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"graphql\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"integration_manifest\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} } },\"rate\": {\"limit\": 5000,\"remaining\": 0,\"reset\": 1570478899}}", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4600", + "X-RateLimit-Reset": "{{testStartDate offset='10 seconds' format='unix'}}", + "Cache-Control": "no-cache", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "Vary": "Accept-Encoding, Accept, X-Requested-With", + "X-GitHub-Request-Id": "F8AD:9836:A3F7EB:C516B7:5E4DF170" + } + }, + "uuid": "9ad3064d-ae78-4fc6-a6bc-20386f446f5e", + "persistent": true, + "scenarioName": "scenario-1-rate_limit", + "requiredScenarioState": "scenario-1-rate_limit-2", + "newScenarioState": "scenario-1-rate_limit-3", + "insertionIndex": 5 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-7-594da3.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-7-594da3.json new file mode 100644 index 000000000..3cdde831b --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-7-594da3.json @@ -0,0 +1,49 @@ +{ + "metadata": { + "comment": "The checker should loop again. reset date passed but we're still below limit." + }, + "id": "594da3ac-e1d8-4276-8fbd-844c1ec9087d", + "name": "rate_limit", + "request": { + "url": "/rate_limit", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "body": "{\"resources\": {\"core\": {\"limit\": 5000,\"remaining\": 4450,\"reset\": {{testStartDate offset='12 seconds' format='unix'}} },\"search\": {\"limit\": 30,\"remaining\": 30,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"graphql\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"integration_manifest\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} } },\"rate\": {\"limit\": 5000,\"remaining\": 0,\"reset\": 1570478899}}", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4450", + "X-RateLimit-Reset": "{{testStartDate offset='12 seconds' format='unix'}}", + "Cache-Control": "no-cache", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "Vary": "Accept-Encoding, Accept, X-Requested-With", + "X-GitHub-Request-Id": "F8AD:9836:A3F800:C516CE:5E4DF171" + } + }, + "uuid": "594da3ac-e1d8-4276-8fbd-844c1ec9087d", + "persistent": true, + "scenarioName": "scenario-1-rate_limit", + "requiredScenarioState": "scenario-1-rate_limit-3", + "newScenarioState": "scenario-1-rate_limit-4", + "insertionIndex": 7 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-8-e5ec63.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-8-e5ec63.json new file mode 100644 index 000000000..9bd1b7f80 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/rate_limit-8-e5ec63.json @@ -0,0 +1,48 @@ +{ + "metadata": { + "comment": "" + }, + "id": "e5ec63c2-6a61-4259-bb08-524f3b4050e5", + "name": "rate_limit", + "request": { + "url": "/rate_limit", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "body": "{\"resources\": {\"core\": {\"limit\": 5000,\"remaining\": 4550,\"reset\": {{testStartDate offset='16 seconds' format='unix'}} },\"search\": {\"limit\": 30,\"remaining\": 30,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"graphql\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} },\"integration_manifest\": {\"limit\": 5000,\"remaining\": 5000,\"reset\": {{testStartDate offset='1 hours' format='unix'}} } },\"rate\": {\"limit\": 5000,\"remaining\": 0,\"reset\": 1570478899}}", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4550", + "X-RateLimit-Reset": "{{testStartDate offset='16 seconds' format='unix'}}", + "Cache-Control": "no-cache", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "Vary": "Accept-Encoding, Accept, X-Requested-With", + "X-GitHub-Request-Id": "F8AD:9836:A3F81A:C516E6:5E4DF171" + } + }, + "uuid": "e5ec63c2-6a61-4259-bb08-524f3b4050e5", + "persistent": true, + "scenarioName": "scenario-1-rate_limit", + "requiredScenarioState": "scenario-1-rate_limit-4", + "insertionIndex": 9 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-4-1b4d33.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-4-1b4d33.json new file mode 100644 index 000000000..574af6274 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-4-1b4d33.json @@ -0,0 +1,54 @@ +{ + "metadata": { + "comment": "" + }, + "id": "1b4d33fb-f043-4d57-ac9a-0e2aa6d72c49", + "name": "repos_github-api-test-org_github-api", + "request": { + "url": "/repos/github-api-test-org/github-api", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_github-api-1b4d33fb-f043-4d57-ac9a-0e2aa6d72c49.json", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4500", + "X-RateLimit-Reset": "{{testStartDate offset='5 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"eefece3fddefad3b444f380f2ddca84a\"", + "Last-Modified": "Thu, 16 Jan 2020 21:22:56 GMT", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "repo", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F8AD:9836:A3F7DF:C516AA:5E4DF170" + } + }, + "uuid": "1b4d33fb-f043-4d57-ac9a-0e2aa6d72c49", + "persistent": true, + "scenarioName": "scenario-2-repos-github-api-test-org-github-api", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-2-repos-github-api-test-org-github-api-2", + "insertionIndex": 4 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-6-7c83f0.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-6-7c83f0.json new file mode 100644 index 000000000..cdd9a147f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-6-7c83f0.json @@ -0,0 +1,54 @@ +{ + "metadata": { + "comment": "This header rate limit will be used because the limit is lower than previous" + }, + "id": "7c83f0f2-98d8-4cea-b681-56f37210c2dc", + "name": "repos_github-api-test-org_github-api", + "request": { + "url": "/repos/github-api-test-org/github-api", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_github-api-7c83f0f2-98d8-4cea-b681-56f37210c2dc.json", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4400", + "X-RateLimit-Reset": "{{testStartDate offset='10 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"eefece3fddefad3b444f380f2ddca84a\"", + "Last-Modified": "Thu, 16 Jan 2020 21:22:56 GMT", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "repo", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F8AD:9836:A3F7F4:C516C3:5E4DF170" + } + }, + "uuid": "7c83f0f2-98d8-4cea-b681-56f37210c2dc", + "persistent": true, + "scenarioName": "scenario-2-repos-github-api-test-org-github-api", + "requiredScenarioState": "scenario-2-repos-github-api-test-org-github-api-2", + "newScenarioState": "scenario-2-repos-github-api-test-org-github-api-3", + "insertionIndex": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-9-12f5b9.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-9-12f5b9.json new file mode 100644 index 000000000..5692794c0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/repos_github-api-test-org_github-api-9-12f5b9.json @@ -0,0 +1,53 @@ +{ + "metadata": { + "comment": "This header limit will override the existing record because this is later" + }, + "id": "12f5b993-ee6d-470b-bd7a-016bbdbe42e8", + "name": "repos_github-api-test-org_github-api", + "request": { + "url": "/repos/github-api-test-org/github-api", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_github-api-12f5b993-ee6d-470b-bd7a-016bbdbe42e8.json", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4601", + "X-RateLimit-Reset": "{{testStartDate offset='20 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"eefece3fddefad3b444f380f2ddca84a\"", + "Last-Modified": "Thu, 16 Jan 2020 21:22:56 GMT", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "repo", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F8AD:9836:A3F807:C516D6:5E4DF171" + } + }, + "uuid": "12f5b993-ee6d-470b-bd7a-016bbdbe42e8", + "persistent": true, + "scenarioName": "scenario-2-repos-github-api-test-org-github-api", + "requiredScenarioState": "scenario-2-repos-github-api-test-org-github-api-3", + "insertionIndex": 8 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/user-2-9a8790.json b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/user-2-9a8790.json new file mode 100644 index 000000000..b24ff332e --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitCheckerTest/wiremock/testGitHubRateLimit/mappings/user-2-9a8790.json @@ -0,0 +1,48 @@ +{ + "id": "9a879079-539d-4629-b873-8d92967da94c", + "name": "user", + "request": { + "url": "/user", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "user-9a879079-539d-4629-b873-8d92967da94c.json", + "headers": { + "Date": "{{now timezone='GMT' format='EEE, dd MMM yyyy HH:mm:ss z'}}", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4501", + "X-RateLimit-Reset": "{{testStartDate offset='5 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding, Accept, X-Requested-With" + ], + "ETag": "W/\"e87e4a976abe11bf6f62d5a01a679780\"", + "Last-Modified": "Thu, 06 Feb 2020 17:29:39 GMT", + "X-OAuth-Scopes": "admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user, write:discussion", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "unknown, github.v3", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "1; mode=block", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "X-GitHub-Request-Id": "F8AD:9836:A3F7D1:C5168A:5E4DF16F" + } + }, + "uuid": "9a879079-539d-4629-b873-8d92967da94c", + "persistent": true, + "insertionIndex": 2 +}, \ No newline at end of file