From b8fae1308d67e971776afa22333e4c9b0217c43f Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Thu, 6 Feb 2020 06:50:25 -0800 Subject: [PATCH 1/4] Streamline fetch and retry process --- .../github/GHFileNotFoundException.java | 21 ++- .../org/kohsuke/github/GHIOException.java | 14 ++ .../java/org/kohsuke/github/Requester.java | 147 ++++++++---------- 3 files changed, 100 insertions(+), 82 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHFileNotFoundException.java b/src/main/java/org/kohsuke/github/GHFileNotFoundException.java index 6475515929..2ea14eb518 100644 --- a/src/main/java/org/kohsuke/github/GHFileNotFoundException.java +++ b/src/main/java/org/kohsuke/github/GHFileNotFoundException.java @@ -24,11 +24,24 @@ public GHFileNotFoundException() { /** * Instantiates a new Gh file not found exception. * - * @param s - * the s + * @param message + * the message */ - public GHFileNotFoundException(String s) { - super(s); + public GHFileNotFoundException(String message) { + super(message); + } + + /** + * Instantiates a new Gh file not found exception. + * + * @param message + * the message + * @param cause + * the cause + */ + public GHFileNotFoundException(String message, Throwable cause) { + super(message); + this.initCause(cause); } /** diff --git a/src/main/java/org/kohsuke/github/GHIOException.java b/src/main/java/org/kohsuke/github/GHIOException.java index b385968674..f05395bd02 100644 --- a/src/main/java/org/kohsuke/github/GHIOException.java +++ b/src/main/java/org/kohsuke/github/GHIOException.java @@ -31,6 +31,20 @@ public GHIOException(String message) { super(message); } + /** + * Constructs a {@code GHIOException} with the specified detail message and cause. + * + * @param message + * The detail message (which is saved for later retrieval by the {@link #getMessage()} method) + * + * @param cause + * The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public GHIOException(String message, Throwable cause) { + super(message, cause); + } + /** * Gets response header fields. * diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 3bda2288c3..e9260a24d3 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -497,73 +497,81 @@ private T _fetch(SupplierThrows supplier) throws IOException } private T _fetch(String tailApiUrl, URL url, SupplierThrows supplier) throws IOException { - while (true) {// loop while API rate limit is hit + int responseCode = -1; + String responseMessage = null; + + int retries = CONNECTION_ERROR_RETRIES; + + do { + // if we fail to create a connection we do not retry and we do not wrap + uc = null; uc = setupConnection(url); try { - return _fetchOrRetry(supplier, CONNECTION_ERROR_RETRIES); - } catch (IOException e) { - handleApiError(e); - } finally { + // This is where the request is sent and response is processing starts + responseCode = uc.getResponseCode(); + responseMessage = uc.getResponseMessage(); noteRateLimit(tailApiUrl); + if (!(isInvalidCached404Response(responseCode) || isRateLimitResponse(responseCode) + || isAbuseLimitResponse(responseCode))) { + return supplier.get(); + } + } catch (IOException e) { + handleApiError(e, responseCode, responseMessage, url, retries); + continue; } - } - } - private T _fetchOrRetry(SupplierThrows supplier, int retries) throws IOException { - int responseCode = -1; - String responseMessage = null; - // When retries equal 0 the previous call must return or throw, not retry again - if (retries < 0) { - throw new IllegalArgumentException("'retries' cannot be less than 0"); - } + handleLimitingErrors(responseCode); - try { - // This is where the request is sent and response is processing starts - responseCode = uc.getResponseCode(); - responseMessage = uc.getResponseMessage(); + } while (--retries >= 0); - // If we are caching and get an invalid cached 404, retry it. - if (!retryInvalidCached404Response(responseCode, retries)) { - return supplier.get(); - } - } catch (FileNotFoundException e) { - // java.net.URLConnection handles 404 exception as FileNotFoundException, - // don't wrap exception in HttpException to preserve backward compatibility - throw e; - } catch (IOException e) { + throw new GHIOException("Ran out of retries for URL: " + url.toString()); + } - if (!retryConnectionError(e, retries)) { - throw new HttpException(responseCode, responseMessage, uc.getURL(), e); - } - } + private boolean isRateLimitResponse(int responseCode) { + return responseCode == HttpURLConnection.HTTP_FORBIDDEN + && "0".equals(uc.getHeaderField("X-RateLimit-Remaining")); + } - // We did not fetch or throw, retry - return _fetchOrRetry(supplier, retries - 1); + private boolean isAbuseLimitResponse(int responseCode) { + return responseCode == HttpURLConnection.HTTP_FORBIDDEN && uc.getHeaderField("Retry-After") != null; + } + private void handleLimitingErrors(int responseCode) throws IOException { + if (isRateLimitResponse(responseCode)) { + HttpException e = new HttpException("Rate limit violation", + responseCode, + uc.getResponseMessage(), + uc.getURL().toString()); + root.rateLimitHandler.onError(e, uc); + } else if (isAbuseLimitResponse(responseCode)) { + HttpException e = new HttpException("Abuse limit violation", + responseCode, + uc.getResponseMessage(), + uc.getURL().toString()); + root.abuseLimitHandler.onError(e, uc); + } } - private boolean retryConnectionError(IOException e, int retries) throws IOException { + private boolean handledTransientConnectionError(IOException e, URL url, int retries) throws IOException { // There are a range of connection errors where we want to wait a moment and just automatically retry boolean connectionError = e instanceof SocketException || e instanceof SocketTimeoutException || e instanceof SSLHandshakeException; if (connectionError && retries > 0) { LOGGER.log(INFO, - e.getMessage() + " while connecting to " + uc.getURL() + ". Sleeping " - + Requester.retryTimeoutMillis + " milliseconds before retrying... ; will try " + retries - + " more time(s)"); + e.getMessage() + " while connecting to " + url + ". Sleeping " + Requester.retryTimeoutMillis + + " milliseconds before retrying... ; will try " + retries + " more time(s)"); try { Thread.sleep(Requester.retryTimeoutMillis); } catch (InterruptedException ie) { throw (IOException) new InterruptedIOException().initCause(e); } - uc = setupConnection(uc.getURL()); return true; } return false; } - private boolean retryInvalidCached404Response(int responseCode, int retries) throws IOException { + private boolean isInvalidCached404Response(int responseCode) { // WORKAROUND FOR ISSUE #669: // When the Requester detects a 404 response with an ETag (only happpens when the server's 304 // is bogus and would cause cache corruption), try the query again with new request header @@ -575,16 +583,15 @@ private boolean retryInvalidCached404Response(int responseCode, int retries) thr // their 404 responses, this will result in at worst two requests being made for each 404 // responses. However, only the second request will count against rate limit. if (responseCode == 404 && Objects.equals(uc.getRequestMethod(), "GET") && uc.getHeaderField("ETag") != null - && !Objects.equals(uc.getRequestProperty("Cache-Control"), "no-cache") && retries > 0) { + && !Objects.equals(uc.getRequestProperty("Cache-Control"), "no-cache")) { LOGGER.log(FINE, "Encountered GitHub invalid cached 404 from " + uc.getURL() + ". Retrying with \"Cache-Control\"=\"no-cache\"..."); - uc = setupConnection(uc.getURL()); // Setting "Cache-Control" to "no-cache" stops the cache from supplying // "If-Modified-Since" or "If-None-Match" values. // This makes GitHub give us current data (not incorrectly cached data) - uc.setRequestProperty("Cache-Control", "no-cache"); + setHeader("Cache-Control", "no-cache"); return true; } return false; @@ -874,7 +881,8 @@ private void findNextURL() throws MalformedURLException { } } - private HttpURLConnection setupConnection(URL url) throws IOException { + @Nonnull + private HttpURLConnection setupConnection(@Nonnull URL url) throws IOException { if (LOGGER.isLoggable(FINE)) { LOGGER.log(FINE, "GitHub API request [" + (root.login == null ? "anonymous" : root.login) + "]: " + method + " " @@ -941,10 +949,10 @@ private T parse(Class type, T instance, int timeouts) throws IOException int responseCode = -1; try { responseCode = uc.getResponseCode(); - if (responseCode == 304) { + if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) { return null; // special case handling for 304 unmodified, as the content will be "" } - if (responseCode == 204 && type != null && type.isArray()) { + if (responseCode == HttpURLConnection.HTTP_NO_CONTENT && type != null && type.isArray()) { // no content return type.cast(Array.newInstance(type.getComponentType(), 0)); } @@ -954,7 +962,7 @@ private T parse(Class type, T instance, int timeouts) throws IOException // See https://developer.github.com/v3/repos/statistics/#a-word-about-caching // And for fork creation: // See https://developer.github.com/v3/repos/forks/#create-a-fork - if (responseCode == 202) { + if (responseCode == HttpURLConnection.HTTP_ACCEPTED) { if (uc.getURL().toString().endsWith("/forks")) { LOGGER.log(INFO, "The fork is being created. Please try again in 5 seconds."); } else if (uc.getURL().toString().endsWith("/statistics")) { @@ -1023,54 +1031,37 @@ private InputStream wrapStream(InputStream in) throws IOException { /** * Handle API error by either throwing it or by returning normally to retry. */ - void handleApiError(IOException e) throws IOException { - int responseCode; - try { - responseCode = uc.getResponseCode(); - } catch (IOException e2) { - // likely to be a network exception (e.g. SSLHandshakeException), - // uc.getResponseCode() and any other getter on the response will cause an exception - if (LOGGER.isLoggable(FINE)) - LOGGER.log(FINE, - "Silently ignore exception retrieving response code for '" + uc.getURL() + "'" - + " handling exception " + e, - e); - throw e; + void handleApiError(IOException e, int responseCode, String message, URL url, int retries) throws IOException { + if (handledTransientConnectionError(e, url, retries)) { + return; } + InputStream es = wrapStream(uc.getErrorStream()); if (es != null) { try { String error = IOUtils.toString(es, StandardCharsets.UTF_8); if (e instanceof FileNotFoundException) { // pass through 404 Not Found to allow the caller to handle it intelligently - e = (IOException) new GHFileNotFoundException(error).withResponseHeaderFields(uc).initCause(e); - } else if (e instanceof HttpException) { - HttpException http = (HttpException) e; - e = new HttpException(error, http.getResponseCode(), http.getResponseMessage(), http.getUrl(), e); + e = new GHFileNotFoundException(error, e).withResponseHeaderFields(uc); + } else if (responseCode >= 0) { + e = new HttpException(error, responseCode, uc.getResponseMessage(), url.toString(), e); } else { - e = (IOException) new GHIOException(error).withResponseHeaderFields(uc).initCause(e); + e = new GHIOException(error).withResponseHeaderFields(uc); } } finally { IOUtils.closeQuietly(es); } + } else if (!(e instanceof FileNotFoundException)) { + e = new HttpException(responseCode, message, url.toString(), e); } - if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 Unauthorized == bad creds or OTP request + + // 401 Unauthorized == bad creds or OTP request + if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { // In the case of a user with 2fa enabled, a header with X-GitHub-OTP // will be returned indicating the user needs to respond with an otp - if (uc.getHeaderField("X-GitHub-OTP") != null) + if (uc.getHeaderField("X-GitHub-OTP") != null) { throw (IOException) new GHOTPRequiredException().withResponseHeaderFields(uc).initCause(e); - else - throw e; // usually org.kohsuke.github.HttpException (which extends IOException) - - if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) { - root.rateLimitHandler.onError(e, uc); - return; - } - - // Retry-After is not documented but apparently that field exists - if (responseCode == HttpURLConnection.HTTP_FORBIDDEN && uc.getHeaderField("Retry-After") != null) { - this.root.abuseLimitHandler.onError(e, uc); - return; + } } throw e; From 1234c2e99e8265e87cc22eab6476e4f1fc77f2d1 Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Thu, 6 Feb 2020 10:22:04 -0800 Subject: [PATCH 2/4] Add tests for rate limit --- .../org/kohsuke/github/AbuseLimitHandler.java | 4 + .../kohsuke/github/AbuseLimitHandlerTest.java | 138 ++++++++++++++++++ .../kohsuke/github/RateLimitHandlerTest.java | 138 ++++++++++++++++++ ...-574da117-6845-46d8-b2c1-4415546ca670.json | 126 ++++++++++++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 52 +++++++ ...mp-testratelimithandler_fail-3-574da1.json | 50 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-574da117-6845-46d8-b2c1-4415546ca670.json | 126 ++++++++++++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 52 +++++++ ...mp-testratelimithandler_fail-3-574da1.json | 50 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-574da117-6845-46d8-b2c1-4415546ca670.json | 126 ++++++++++++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 52 +++++++ ...mp-testratelimithandler_fail-3-574da1.json | 50 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 49 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-574da117-6845-46d8-b2c1-4415546ca670.json | 126 ++++++++++++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 51 +++++++ ...mp-testratelimithandler_fail-3-574da1.json | 50 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-574da117-6845-46d8-b2c1-4415546ca670.json | 126 ++++++++++++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 51 +++++++ ...mp-testratelimithandler_fail-3-574da1.json | 50 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-574da117-6845-46d8-b2c1-4415546ca670.json | 126 ++++++++++++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 51 +++++++ ...mp-testratelimithandler_fail-3-574da1.json | 50 +++++++ .../mappings/user-1-a60baf.json | 48 ++++++ ...-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json | 45 ++++++ ...mp-testratelimithandler_fail-2-79fb10.json | 48 ++++++ .../mappings/user-1-a60baf.json | 48 ++++++ 39 files changed, 2486 insertions(+) create mode 100644 src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java create mode 100644 src/test/java/org/kohsuke/github/RateLimitHandlerTest.java create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json create mode 100644 src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json diff --git a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java index 44847c3c30..aabd07c1af 100644 --- a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java +++ b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java @@ -29,6 +29,10 @@ public abstract class AbuseLimitHandler { * @throws IOException * on failure * @see API documentation from GitHub + * @see Dealing + * with abuse rate limits + * */ public abstract void onError(IOException e, HttpURLConnection uc) throws IOException; diff --git a/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java b/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java new file mode 100644 index 0000000000..8dc2aed4f5 --- /dev/null +++ b/src/test/java/org/kohsuke/github/AbuseLimitHandlerTest.java @@ -0,0 +1,138 @@ +package org.kohsuke.github; + +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; +import org.junit.Test; + +import java.io.IOException; +import java.net.HttpURLConnection; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.core.IsInstanceOf.instanceOf; + +/** + * Test showing the behavior of OkHttpConnector with and without cache. + *

+ * Key take aways: + * + *

    + *
  • These tests are artificial and intended to highlight the differences in behavior between scenarios. However, the + * differences they indicate are stark.
  • + *
  • Caching reduces rate limit consumption by at least a factor of two in even the simplest case.
  • + *
  • The OkHttp cache is pretty smart and will often connect read and write requests made on the same client and + * invalidate caches.
  • + *
  • Changes made outside the current client cause the OkHttp cache to return stale data. This is expected and correct + * behavior.
  • + *
  • "max-age=0" addresses the problem of external changes by revalidating caches for each request. This produces the + * same number of requests as OkHttp without caching, but those requests only count towards the GitHub rate limit if + * data has changes.
  • + *
+ * + * @author Liam Newman + */ +public class AbuseLimitHandlerTest extends AbstractGitHubWireMockTest { + + public AbuseLimitHandlerTest() { + useDefaultGitHub = false; + } + + @Override + protected WireMockConfiguration getWireMockOptions() { + return super.getWireMockOptions() + .extensions(ResponseTemplateTransformer.builder().global(true).maxCacheEntries(0L).build()); + } + + @Test + public void testHandler_Fail() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withAbuseLimitHandler(AbuseLimitHandler.FAIL) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + try { + getTempRepository(); + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(IOException.class)); + assertThat(e.getCause(), instanceOf(HttpException.class)); + } + + assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + } + + @Test + public void testHandler_HttpStatus_Fail() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withAbuseLimitHandler(AbuseLimitHandler.FAIL) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + try { + gitHub.createRequest() + .withUrlPath("/repos/" + GITHUB_API_TEST_ORG + "/temp-testHandler_Fail") + .fetchHttpStatusCode(); + + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(IOException.class)); + assertThat(e.getCause(), instanceOf(HttpException.class)); + } + + assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + } + + @Test + public void testHandler_Wait() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withAbuseLimitHandler(AbuseLimitHandler.WAIT) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + getTempRepository(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); + } + + @Test + public void testHandler_WaitStuck() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withRateLimitHandler(new RateLimitHandler() { + @Override + public void onError(IOException e, HttpURLConnection uc) throws IOException { + } + }) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + try { + getTempRepository(); + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(GHIOException.class)); + } + + assertThat(mockGitHub.getRequestCount(), equalTo(4)); + } + +} diff --git a/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java b/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java new file mode 100644 index 0000000000..1810ae780c --- /dev/null +++ b/src/test/java/org/kohsuke/github/RateLimitHandlerTest.java @@ -0,0 +1,138 @@ +package org.kohsuke.github; + +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer; +import org.junit.Test; + +import java.io.IOException; +import java.net.HttpURLConnection; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.core.IsInstanceOf.instanceOf; + +/** + * Test showing the behavior of OkHttpConnector with and without cache. + *

+ * Key take aways: + * + *

    + *
  • These tests are artificial and intended to highlight the differences in behavior between scenarios. However, the + * differences they indicate are stark.
  • + *
  • Caching reduces rate limit consumption by at least a factor of two in even the simplest case.
  • + *
  • The OkHttp cache is pretty smart and will often connect read and write requests made on the same client and + * invalidate caches.
  • + *
  • Changes made outside the current client cause the OkHttp cache to return stale data. This is expected and correct + * behavior.
  • + *
  • "max-age=0" addresses the problem of external changes by revalidating caches for each request. This produces the + * same number of requests as OkHttp without caching, but those requests only count towards the GitHub rate limit if + * data has changes.
  • + *
+ * + * @author Liam Newman + */ +public class RateLimitHandlerTest extends AbstractGitHubWireMockTest { + + public RateLimitHandlerTest() { + useDefaultGitHub = false; + } + + @Override + protected WireMockConfiguration getWireMockOptions() { + return super.getWireMockOptions() + .extensions(ResponseTemplateTransformer.builder().global(true).maxCacheEntries(0L).build()); + } + + @Test + public void testHandler_Fail() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withRateLimitHandler(RateLimitHandler.FAIL) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + try { + getTempRepository(); + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(IOException.class)); + assertThat(e.getCause(), instanceOf(HttpException.class)); + } + + assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + } + + @Test + public void testHandler_HttpStatus_Fail() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withRateLimitHandler(RateLimitHandler.FAIL) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + try { + gitHub.createRequest() + .withUrlPath("/repos/" + GITHUB_API_TEST_ORG + "/temp-testHandler_Fail") + .fetchHttpStatusCode(); + + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(IOException.class)); + assertThat(e.getCause(), instanceOf(HttpException.class)); + } + + assertThat(mockGitHub.getRequestCount(), equalTo(2)); + + } + + @Test + public void testHandler_Wait() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withRateLimitHandler(RateLimitHandler.WAIT) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + getTempRepository(); + assertThat(mockGitHub.getRequestCount(), equalTo(3)); + } + + @Test + public void testHandler_WaitStuck() throws Exception { + // Customized response that templates the date to keep things working + snapshotNotAllowed(); + + gitHub = getGitHubBuilder().withEndpoint(mockGitHub.apiServer().baseUrl()) + .withRateLimitHandler(new RateLimitHandler() { + @Override + public void onError(IOException e, HttpURLConnection uc) throws IOException { + } + }) + .build(); + + gitHub.getMyself(); + assertThat(mockGitHub.getRequestCount(), equalTo(1)); + + try { + getTempRepository(); + fail(); + } catch (Exception e) { + assertThat(e, instanceOf(GHIOException.class)); + } + + assertThat(mockGitHub.getRequestCount(), equalTo(4)); + } + +} diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json new file mode 100644 index 0000000000..e450d4f91f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json @@ -0,0 +1,126 @@ +{ + "id": 238757196, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzg3NTcxOTY=", + "name": "temp-testHandler_Fail", + "full_name": "github-api-test-org/temp-testHandler_Fail", + "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/temp-testHandler_Fail", + "description": "A test repository for testing the github-api project: temp-testHandler_Fail", + "fork": false, + "url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail", + "forks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/deployments", + "created_at": "2020-02-06T18:33:39Z", + "updated_at": "2020-02-06T18:33:43Z", + "pushed_at": "2020-02-06T18:33:41Z", + "git_url": "git://github.com/github-api-test-org/temp-testHandler_Fail.git", + "ssh_url": "git@github.com:github-api-test-org/temp-testHandler_Fail.git", + "clone_url": "https://github.com/github-api-test-org/temp-testHandler_Fail.git", + "svn_url": "https://github.com/github-api-test-org/temp-testHandler_Fail", + "homepage": "http://github-api.kohsuke.org/", + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "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": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "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 + }, + "network_count": 0, + "subscribers_count": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..5d27eff187 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,52 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "Retry-After": "30", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4000", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json new file mode 100644 index 0000000000..ce5bf4e38c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json @@ -0,0 +1,50 @@ +{ + "id": "574da117-6845-46d8-b2c1-4415546ca670", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.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": "4922", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 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": "CC37:2605:3FADC:4EA8C:5E3C5C02" + } + }, + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json new file mode 100644 index 0000000000..e450d4f91f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json @@ -0,0 +1,126 @@ +{ + "id": 238757196, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzg3NTcxOTY=", + "name": "temp-testHandler_Fail", + "full_name": "github-api-test-org/temp-testHandler_Fail", + "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/temp-testHandler_Fail", + "description": "A test repository for testing the github-api project: temp-testHandler_Fail", + "fork": false, + "url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail", + "forks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/deployments", + "created_at": "2020-02-06T18:33:39Z", + "updated_at": "2020-02-06T18:33:43Z", + "pushed_at": "2020-02-06T18:33:41Z", + "git_url": "git://github.com/github-api-test-org/temp-testHandler_Fail.git", + "ssh_url": "git@github.com:github-api-test-org/temp-testHandler_Fail.git", + "clone_url": "https://github.com/github-api-test-org/temp-testHandler_Fail.git", + "svn_url": "https://github.com/github-api-test-org/temp-testHandler_Fail", + "homepage": "http://github-api.kohsuke.org/", + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "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": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "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 + }, + "network_count": 0, + "subscribers_count": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..5d27eff187 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,52 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "Retry-After": "30", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4000", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json new file mode 100644 index 0000000000..ce5bf4e38c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json @@ -0,0 +1,50 @@ +{ + "id": "574da117-6845-46d8-b2c1-4415546ca670", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.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": "4922", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 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": "CC37:2605:3FADC:4EA8C:5E3C5C02" + } + }, + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json new file mode 100644 index 0000000000..636f760eb6 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json @@ -0,0 +1,126 @@ +{ + "id": 238757196, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzg3NTcxOTY=", + "name": "temp-testHandler_Wait", + "full_name": "github-api-test-org/temp-testHandler_Wait", + "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/temp-testHandler_Wait", + "description": "A test repository for testing the github-api project: temp-testHandler_Wait", + "fork": false, + "url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait", + "forks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/deployments", + "created_at": "2020-02-06T18:33:39Z", + "updated_at": "2020-02-06T18:33:43Z", + "pushed_at": "2020-02-06T18:33:41Z", + "git_url": "git://github.com/github-api-test-org/temp-testHandler_Wait.git", + "ssh_url": "git@github.com:github-api-test-org/temp-testHandler_Wait.git", + "clone_url": "https://github.com/github-api-test-org/temp-testHandler_Wait.git", + "svn_url": "https://github.com/github-api-test-org/temp-testHandler_Wait", + "homepage": "http://github-api.kohsuke.org/", + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "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": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "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 + }, + "network_count": 0, + "subscribers_count": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..b7e939c4e8 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,52 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testHandler_Wait", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Wait", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "Retry-After": "2", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4000", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json new file mode 100644 index 0000000000..53f1e99926 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json @@ -0,0 +1,50 @@ +{ + "id": "574da117-6845-46d8-b2c1-4415546ca670", + "name": "repos_github-api-test-org_temp-testHandler_Wait", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Wait", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.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": "4922", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 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": "CC37:2605:3FADC:4EA8C:5E3C5C02" + } + }, + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait", + "requiredScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait-2", + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..3455eb9b45 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,49 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testHandler_WaitStuck", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_WaitStuck", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "Retry-After": "3", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4000", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/AbuseLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json new file mode 100644 index 0000000000..e450d4f91f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json @@ -0,0 +1,126 @@ +{ + "id": 238757196, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzg3NTcxOTY=", + "name": "temp-testHandler_Fail", + "full_name": "github-api-test-org/temp-testHandler_Fail", + "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/temp-testHandler_Fail", + "description": "A test repository for testing the github-api project: temp-testHandler_Fail", + "fork": false, + "url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail", + "forks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/deployments", + "created_at": "2020-02-06T18:33:39Z", + "updated_at": "2020-02-06T18:33:43Z", + "pushed_at": "2020-02-06T18:33:41Z", + "git_url": "git://github.com/github-api-test-org/temp-testHandler_Fail.git", + "ssh_url": "git@github.com:github-api-test-org/temp-testHandler_Fail.git", + "clone_url": "https://github.com/github-api-test-org/temp-testHandler_Fail.git", + "svn_url": "https://github.com/github-api-test-org/temp-testHandler_Fail", + "homepage": "http://github-api.kohsuke.org/", + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "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": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "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 + }, + "network_count": 0, + "subscribers_count": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..9a3217193a --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,51 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "0", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json new file mode 100644 index 0000000000..ce5bf4e38c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json @@ -0,0 +1,50 @@ +{ + "id": "574da117-6845-46d8-b2c1-4415546ca670", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.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": "4922", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 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": "CC37:2605:3FADC:4EA8C:5E3C5C02" + } + }, + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Fail/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json new file mode 100644 index 0000000000..e450d4f91f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json @@ -0,0 +1,126 @@ +{ + "id": 238757196, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzg3NTcxOTY=", + "name": "temp-testHandler_Fail", + "full_name": "github-api-test-org/temp-testHandler_Fail", + "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/temp-testHandler_Fail", + "description": "A test repository for testing the github-api project: temp-testHandler_Fail", + "fork": false, + "url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail", + "forks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Fail/deployments", + "created_at": "2020-02-06T18:33:39Z", + "updated_at": "2020-02-06T18:33:43Z", + "pushed_at": "2020-02-06T18:33:41Z", + "git_url": "git://github.com/github-api-test-org/temp-testHandler_Fail.git", + "ssh_url": "git@github.com:github-api-test-org/temp-testHandler_Fail.git", + "clone_url": "https://github.com/github-api-test-org/temp-testHandler_Fail.git", + "svn_url": "https://github.com/github-api-test-org/temp-testHandler_Fail", + "homepage": "http://github-api.kohsuke.org/", + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "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": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "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 + }, + "network_count": 0, + "subscribers_count": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..9a3217193a --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,51 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "0", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json new file mode 100644 index 0000000000..ce5bf4e38c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json @@ -0,0 +1,50 @@ +{ + "id": "574da117-6845-46d8-b2c1-4415546ca670", + "name": "repos_github-api-test-org_temp-testratelimithandler_fail", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Fail", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.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": "4922", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 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": "CC37:2605:3FADC:4EA8C:5E3C5C02" + } + }, + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail", + "requiredScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Fail-2", + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_HttpStatus_Fail/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json new file mode 100644 index 0000000000..636f760eb6 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.json @@ -0,0 +1,126 @@ +{ + "id": 238757196, + "node_id": "MDEwOlJlcG9zaXRvcnkyMzg3NTcxOTY=", + "name": "temp-testHandler_Wait", + "full_name": "github-api-test-org/temp-testHandler_Wait", + "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/temp-testHandler_Wait", + "description": "A test repository for testing the github-api project: temp-testHandler_Wait", + "fork": false, + "url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait", + "forks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/forks", + "keys_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/teams", + "hooks_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/hooks", + "issue_events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/issues/events{/number}", + "events_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/events", + "assignees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/assignees{/user}", + "branches_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/branches{/branch}", + "tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/tags", + "blobs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/statuses/{sha}", + "languages_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/languages", + "stargazers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/stargazers", + "contributors_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/contributors", + "subscribers_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/subscribers", + "subscription_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/subscription", + "commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/contents/{+path}", + "compare_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/merges", + "archive_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/downloads", + "issues_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/issues{/number}", + "pulls_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/pulls{/number}", + "milestones_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/milestones{/number}", + "notifications_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/labels{/name}", + "releases_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/releases{/id}", + "deployments_url": "https://api.github.com/repos/github-api-test-org/temp-testHandler_Wait/deployments", + "created_at": "2020-02-06T18:33:39Z", + "updated_at": "2020-02-06T18:33:43Z", + "pushed_at": "2020-02-06T18:33:41Z", + "git_url": "git://github.com/github-api-test-org/temp-testHandler_Wait.git", + "ssh_url": "git@github.com:github-api-test-org/temp-testHandler_Wait.git", + "clone_url": "https://github.com/github-api-test-org/temp-testHandler_Wait.git", + "svn_url": "https://github.com/github-api-test-org/temp-testHandler_Wait", + "homepage": "http://github-api.kohsuke.org/", + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "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": 0, + "license": null, + "forks": 0, + "open_issues": 0, + "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 + }, + "network_count": 0, + "subscribers_count": 6 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..8f38ec6493 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,51 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testHandler_Wait", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Wait", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "0", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait", + "requiredScenarioState": "Started", + "newScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait-2", + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json new file mode 100644 index 0000000000..53f1e99926 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-3-574da1.json @@ -0,0 +1,50 @@ +{ + "id": "574da117-6845-46d8-b2c1-4415546ca670", + "name": "repos_github-api-test-org_temp-testHandler_Wait", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_Wait", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "repos_github-api-test-org_temp-testratelimithandler_fail-574da117-6845-46d8-b2c1-4415546ca670.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": "4922", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"858224998ac7d1fd6dcd43f73d375297\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:43 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": "CC37:2605:3FADC:4EA8C:5E3C5C02" + } + }, + "uuid": "574da117-6845-46d8-b2c1-4415546ca670", + "persistent": true, + "scenarioName": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait", + "requiredScenarioState": "scenario-1-repos-github-api-test-org-temp-testHandler_Wait-2", + "insertionIndex": 3 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_Wait/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json new file mode 100644 index 0000000000..467313f149 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/__files/user-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.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": 146, + "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/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json new file mode 100644 index 0000000000..6933894525 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/repos_github-api-test-org_temp-testratelimithandler_fail-2-79fb10.json @@ -0,0 +1,48 @@ +{ + "id": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "name": "repos_github-api-test-org_temp-testHandler_WaitStuck", + "request": { + "url": "/repos/github-api-test-org/temp-testHandler_WaitStuck", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + } + } + }, + "response": { + "status": 403, + "body": "{\"message\":\"Must have push access to repository\",\"documentation_url\":\"https://developer.github.com/\"}", + "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": "403 Forbidden", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "0", + "X-RateLimit-Reset": "{{now offset='2 seconds' format='unix'}}", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"7ff3c96399f7ddf6129622d675ca9935\"", + "Last-Modified": "Thu, 06 Feb 2020 18:33:37 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": "CC37:2605:3F982:4E949:5E3C5BFC" + } + }, + "uuid": "79fb1092-8bf3-4274-bc8e-ca126c9d9261", + "persistent": true, + "insertionIndex": 2 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json new file mode 100644 index 0000000000..65ea20d5f0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/RateLimitHandlerTest/wiremock/testHandler_WaitStuck/mappings/user-1-a60baf.json @@ -0,0 +1,48 @@ +{ + "id": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "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-a60baf84-5b5c-4f86-af3d-cab0d609c7b2.json", + "headers": { + "Date": "Thu, 06 Feb 2020 18:33:32 GMT", + "Content-Type": "application/json; charset=utf-8", + "Server": "GitHub.com", + "Status": "200 OK", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4930", + "X-RateLimit-Reset": "1581014122", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": [ + "Accept, Authorization, Cookie, X-GitHub-OTP", + "Accept-Encoding" + ], + "ETag": "W/\"1cb30f031c67c499473b3aad01c7f7a5\"", + "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": "CC37:2605:3F884:4E941:5E3C5BFC" + } + }, + "uuid": "a60baf84-5b5c-4f86-af3d-cab0d609c7b2", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file From 825c36c15eb427fb2fd4366e95da0111722bc6da Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Thu, 6 Feb 2020 14:11:16 -0800 Subject: [PATCH 3/4] Tweaks for clarity --- .../java/org/kohsuke/github/Requester.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index e9260a24d3..bb520991eb 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -512,13 +512,21 @@ private T _fetch(String tailApiUrl, URL url, SupplierThrows responseCode = uc.getResponseCode(); responseMessage = uc.getResponseMessage(); noteRateLimit(tailApiUrl); - if (!(isInvalidCached404Response(responseCode) || isRateLimitResponse(responseCode) - || isAbuseLimitResponse(responseCode))) { + + // for this workaround, we can retry now + if (isInvalidCached404Response(responseCode)) { + continue; + } + if (!(isRateLimitResponse(responseCode) || isAbuseLimitResponse(responseCode))) { return supplier.get(); } } catch (IOException e) { - handleApiError(e, responseCode, responseMessage, url, retries); - continue; + // For transient errors, retry + if (handledTransientConnectionError(e, url, retries)) { + continue; + } + + throw interpretApiError(e, responseCode, responseMessage, url, retries); } handleLimitingErrors(responseCode); @@ -1031,11 +1039,8 @@ private InputStream wrapStream(InputStream in) throws IOException { /** * Handle API error by either throwing it or by returning normally to retry. */ - void handleApiError(IOException e, int responseCode, String message, URL url, int retries) throws IOException { - if (handledTransientConnectionError(e, url, retries)) { - return; - } - + IOException interpretApiError(IOException e, int responseCode, String message, URL url, int retries) + throws IOException { InputStream es = wrapStream(uc.getErrorStream()); if (es != null) { try { @@ -1060,11 +1065,10 @@ void handleApiError(IOException e, int responseCode, String message, URL url, in // In the case of a user with 2fa enabled, a header with X-GitHub-OTP // will be returned indicating the user needs to respond with an otp if (uc.getHeaderField("X-GitHub-OTP") != null) { - throw (IOException) new GHOTPRequiredException().withResponseHeaderFields(uc).initCause(e); + e = (IOException) new GHOTPRequiredException().withResponseHeaderFields(uc).initCause(e); } } - - throw e; + return e; } /** From 289282e235997bfe24ac07bd8d77d071561450f6 Mon Sep 17 00:00:00 2001 From: Liam Newman Date: Thu, 6 Feb 2020 16:55:58 -0800 Subject: [PATCH 4/4] Move OTP detection earlier Like other errors we've been waiting until later to catch, this one is detectable so whe should do that before the downstream exception needs to be thrown. --- .../org/kohsuke/github/HttpException.java | 8 ++--- .../java/org/kohsuke/github/Requester.java | 29 ++++++++++++------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/kohsuke/github/HttpException.java b/src/main/java/org/kohsuke/github/HttpException.java index df29f269dd..c3dda8887e 100644 --- a/src/main/java/org/kohsuke/github/HttpException.java +++ b/src/main/java/org/kohsuke/github/HttpException.java @@ -12,7 +12,7 @@ * * @author Cyrille Le Clerc */ -public class HttpException extends IOException { +public class HttpException extends GHIOException { static final long serialVersionUID = 1L; private final int responseCode; @@ -58,8 +58,7 @@ public HttpException(String message, int responseCode, String responseMessage, S * @see HttpURLConnection#getResponseMessage() HttpURLConnection#getResponseMessage() */ public HttpException(String message, int responseCode, String responseMessage, String url, Throwable cause) { - super(message); - initCause(cause); + super(message, cause); this.responseCode = responseCode; this.responseMessage = responseMessage; this.url = url; @@ -82,8 +81,7 @@ public HttpException(String message, int responseCode, String responseMessage, S */ public HttpException(int responseCode, String responseMessage, String url, Throwable cause) { super("Server returned HTTP response code: " + responseCode + ", message: '" + responseMessage + "'" - + " for URL: " + url); - initCause(cause); + + " for URL: " + url, cause); this.responseCode = responseCode; this.responseMessage = responseMessage; this.url = url; diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index bb520991eb..80c8162162 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -512,6 +512,7 @@ private T _fetch(String tailApiUrl, URL url, SupplierThrows responseCode = uc.getResponseCode(); responseMessage = uc.getResponseMessage(); noteRateLimit(tailApiUrl); + detectOTPRequired(responseCode); // for this workaround, we can retry now if (isInvalidCached404Response(responseCode)) { @@ -522,7 +523,7 @@ private T _fetch(String tailApiUrl, URL url, SupplierThrows } } catch (IOException e) { // For transient errors, retry - if (handledTransientConnectionError(e, url, retries)) { + if (retryConnectionError(e, url, retries)) { continue; } @@ -536,6 +537,17 @@ private T _fetch(String tailApiUrl, URL url, SupplierThrows throw new GHIOException("Ran out of retries for URL: " + url.toString()); } + private void detectOTPRequired(int responseCode) throws GHIOException { + // 401 Unauthorized == bad creds or OTP request + if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { + // In the case of a user with 2fa enabled, a header with X-GitHub-OTP + // will be returned indicating the user needs to respond with an otp + if (uc.getHeaderField("X-GitHub-OTP") != null) { + throw new GHOTPRequiredException().withResponseHeaderFields(uc); + } + } + } + private boolean isRateLimitResponse(int responseCode) { return responseCode == HttpURLConnection.HTTP_FORBIDDEN && "0".equals(uc.getHeaderField("X-RateLimit-Remaining")); @@ -561,7 +573,7 @@ private void handleLimitingErrors(int responseCode) throws IOException { } } - private boolean handledTransientConnectionError(IOException e, URL url, int retries) throws IOException { + private boolean retryConnectionError(IOException e, URL url, int retries) throws IOException { // There are a range of connection errors where we want to wait a moment and just automatically retry boolean connectionError = e instanceof SocketException || e instanceof SocketTimeoutException || e instanceof SSLHandshakeException; @@ -1041,6 +1053,10 @@ private InputStream wrapStream(InputStream in) throws IOException { */ IOException interpretApiError(IOException e, int responseCode, String message, URL url, int retries) throws IOException { + // If we're already throwing a GHIOException, pass through + if (e instanceof GHIOException) { + return e; + } InputStream es = wrapStream(uc.getErrorStream()); if (es != null) { try { @@ -1059,15 +1075,6 @@ IOException interpretApiError(IOException e, int responseCode, String message, U } else if (!(e instanceof FileNotFoundException)) { e = new HttpException(responseCode, message, url.toString(), e); } - - // 401 Unauthorized == bad creds or OTP request - if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { - // In the case of a user with 2fa enabled, a header with X-GitHub-OTP - // will be returned indicating the user needs to respond with an otp - if (uc.getHeaderField("X-GitHub-OTP") != null) { - e = (IOException) new GHOTPRequiredException().withResponseHeaderFields(uc).initCause(e); - } - } return e; }