Search in sources :

Example 6 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpTest method test429BackoffMaxConfigured.

/**
 * Test that the configured maximum number of retries is reached and the backoff is of at least
 * the expected duration.
 *
 * @throws Exception
 */
@TestTemplate
public void test429BackoffMaxConfigured() throws Exception {
    // Always respond 429 for this test
    mockWebServer.setDispatcher(MockWebServerResources.ALL_429);
    TestTimer t = TestTimer.startTimer();
    try {
        CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).interceptors(new Replay429Interceptor(10, 1, true)).build();
        String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
        fail("There should be a TooManyRequestsException instead had response " + response);
    } catch (TooManyRequestsException e) {
        long duration = t.stopTimer(TimeUnit.MILLISECONDS);
        // 9 backoff periods for 10 attempts: 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 = 511 ms
        assertTrue(duration >= 511, "The duration should be at least 511 ms, but was " + duration);
        assertEquals(10, mockWebServer.getRequestCount(), "There should be 10 request attempts");
    }
}
Also used : Replay429Interceptor(com.cloudant.http.interceptors.Replay429Interceptor) TooManyRequestsException(com.cloudant.client.org.lightcouch.TooManyRequestsException) CloudantClient(com.cloudant.client.api.CloudantClient) TestTimer(com.cloudant.tests.util.TestTimer) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) TestTemplate(org.junit.jupiter.api.TestTemplate)

Example 7 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpTest method cookieRenewal.

/**
 * This test check that the cookie is renewed if the server presents a Set-Cookie header
 * after the cookie authentication.
 *
 * @throws Exception
 */
@TestTemplate
public void cookieRenewal() throws Exception {
    final String hello = "{\"hello\":\"world\"}\r\n";
    final String renewalCookieToken = "RenewCookie_a2ltc3RlYmVsOjUxMzRBQTUzOtiY2_IDUIdsTJEVNEjObAbyhrgz";
    // Request sequence
    // _session request to get Cookie
    // GET request -> 200 with a Set-Cookie
    // GET replay -> 200
    mockWebServer.enqueue(MockWebServerResources.OK_COOKIE);
    mockWebServer.enqueue(new MockResponse().setResponseCode(200).addHeader("Set-Cookie", MockWebServerResources.authSessionCookie(renewalCookieToken, null)).setBody(hello));
    mockWebServer.enqueue(new MockResponse());
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).username("a").password("b").build();
    String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertEquals(hello, response, "The expected response should be received");
    // assert that there were 2 calls
    assertEquals(2, mockWebServer.getRequestCount(), "The server should have received 2 requests");
    assertEquals("/_session", MockWebServerResources.takeRequestWithTimeout(mockWebServer).getPath(), "The request should have been for /_session");
    assertEquals("/", MockWebServerResources.takeRequestWithTimeout(mockWebServer).getPath(), "The request should have been for /");
    String secondResponse = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
    assertTrue(secondResponse.isEmpty(), "There should be no response body on the mock response" + secondResponse);
    // also assert that there were 3 calls
    assertEquals(3, mockWebServer.getRequestCount(), "The server should have received 3 requests");
    // this is the request that should have the new cookie.
    RecordedRequest request = MockWebServerResources.takeRequestWithTimeout(mockWebServer);
    assertEquals("/", request.getPath(), "The request should have been for path /");
    String headerValue = request.getHeader("Cookie");
    // The cookie may or may not have the session id quoted, so check both
    assertThat("The Cookie header should contain the expected session value", headerValue, anyOf(containsString(MockWebServerResources.authSession(renewalCookieToken)), containsString(MockWebServerResources.authSessionUnquoted(renewalCookieToken))));
}
Also used : RecordedRequest(okhttp3.mockwebserver.RecordedRequest) MockResponse(okhttp3.mockwebserver.MockResponse) CloudantClient(com.cloudant.client.api.CloudantClient) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) TestTemplate(org.junit.jupiter.api.TestTemplate)

Example 8 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpTest method testCookieRenewOnPost.

@TestTemplate
public void testCookieRenewOnPost() throws Exception {
    mockWebServer.enqueue(MockWebServerResources.OK_COOKIE);
    mockWebServer.enqueue(new MockResponse().setResponseCode(403).setBody("{\"error\":\"credentials_expired\", \"reason\":\"Session expired\"}\r\n"));
    mockWebServer.enqueue(MockWebServerResources.OK_COOKIE);
    mockWebServer.enqueue(new MockResponse());
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).username("a").password("b").build();
    HttpConnection request = Http.POST(mockWebServer.url("/").url(), "application/json");
    request.setRequestBody("{\"some\": \"json\"}");
    HttpConnection response = c.executeRequest(request);
    String responseStr = response.responseAsString();
    assertTrue(responseStr.isEmpty(), "There should be no response body on the mock response");
    response.getConnection().getResponseCode();
}
Also used : MockResponse(okhttp3.mockwebserver.MockResponse) CloudantClient(com.cloudant.client.api.CloudantClient) HttpConnection(com.cloudant.http.HttpConnection) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) TestTemplate(org.junit.jupiter.api.TestTemplate)

Example 9 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpTest method basic403Test.

/**
 * Method that performs a basic test for a 403 response. The sequence of requests is:
 * <OL>
 * <LI>_session request to get Cookie</LI>
 * <LI>GET request -> a 403 response</LI>
 * <LI>_session for new cookie*</LI>
 * <LI>GET replay -> a 200 response*</LI>
 * </OL>
 * The requests annotated * should only happen in the credentials_expired 403 case
 *
 * @param error  the response JSON error content for the 403
 * @param reason the response JSON reason content for the 403
 */
private void basic403Test(String error, String reason, int expectedRequests) throws Exception {
    mockWebServer.enqueue(MockWebServerResources.OK_COOKIE);
    JsonObject responseBody = new JsonObject();
    responseBody.add("error", new JsonPrimitive(error));
    JsonElement jsonReason;
    if (reason != null) {
        if ("null".equals(reason)) {
            jsonReason = JsonNull.INSTANCE;
            // For the assertion we need a real null, not a JsonNull
            reason = null;
        } else {
            jsonReason = new JsonPrimitive(reason);
        }
        responseBody.add("reason", jsonReason);
    }
    mockWebServer.enqueue(new MockResponse().setResponseCode(403).setBody(responseBody.toString()));
    mockWebServer.enqueue(MockWebServerResources.OK_COOKIE);
    mockWebServer.enqueue(new MockResponse());
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).username("a").password("b").build();
    // _session followed by a replay of GET
    try {
        String response = c.executeRequest(Http.GET(c.getBaseUri())).responseAsString();
        assertTrue(response.isEmpty(), "There should be no response body on the mock response");
        if (!error.equals("credentials_expired")) {
            fail("A 403 not due to cookie expiry should result in a CouchDbException");
        }
    } catch (CouchDbException e) {
        assertEquals(error, e.getError(), "The exception error should be the expected message");
        assertEquals(reason, e.getReason(), "The exception reason should be the expected message");
    }
    // also assert that there were the correct number of calls
    assertEquals(expectedRequests, mockWebServer.getRequestCount(), "The server should receive the expected number of " + "requests");
}
Also used : MockResponse(okhttp3.mockwebserver.MockResponse) CouchDbException(com.cloudant.client.org.lightcouch.CouchDbException) CloudantClient(com.cloudant.client.api.CloudantClient) JsonPrimitive(com.google.gson.JsonPrimitive) JsonElement(com.google.gson.JsonElement) JsonObject(com.google.gson.JsonObject) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString)

Example 10 with CloudantClient

use of com.cloudant.client.api.CloudantClient in project java-cloudant by cloudant.

the class HttpTest method testHttpConnectionRetries.

/**
 * Test the global number of retries
 *
 * @throws Exception
 */
@TestTemplate
public void testHttpConnectionRetries() throws Exception {
    // Just return 200 OK
    mockWebServer.setDispatcher(new MockWebServerResources.ConstantResponseDispatcher(200));
    CloudantClient c = CloudantClientHelper.newMockWebServerClientBuilder(mockWebServer).interceptors(new HttpConnectionResponseInterceptor() {

        @Override
        public HttpConnectionInterceptorContext interceptResponse(HttpConnectionInterceptorContext context) {
            // At least do something with the connection, otherwise we risk breaking it
            try {
                context.connection.getConnection().getResponseCode();
            } catch (IOException e) {
                fail("IOException getting response code");
            }
            // Set to always replay
            context.replayRequest = true;
            return context;
        }
    }).build();
    String response = c.executeRequest(Http.GET(c.getBaseUri()).setNumberOfRetries(5)).responseAsString();
    assertTrue(response.isEmpty(), "There should be no response body on the mock response");
    assertEquals(5, mockWebServer.getRequestCount(), "There should be 5 request attempts");
}
Also used : CloudantClient(com.cloudant.client.api.CloudantClient) HttpConnectionResponseInterceptor(com.cloudant.http.HttpConnectionResponseInterceptor) IOException(java.io.IOException) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) MockWebServerResources(com.cloudant.tests.util.MockWebServerResources) HttpConnectionInterceptorContext(com.cloudant.http.HttpConnectionInterceptorContext) TestTemplate(org.junit.jupiter.api.TestTemplate)

Aggregations

CloudantClient (com.cloudant.client.api.CloudantClient)47 MockResponse (okhttp3.mockwebserver.MockResponse)32 TestTemplate (org.junit.jupiter.api.TestTemplate)23 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)21 Test (org.junit.jupiter.api.Test)20 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)19 Database (com.cloudant.client.api.Database)8 CouchDbException (com.cloudant.client.org.lightcouch.CouchDbException)7 TestTimer (com.cloudant.tests.util.TestTimer)4 URL (java.net.URL)4 TooManyRequestsException (com.cloudant.client.org.lightcouch.TooManyRequestsException)3 HttpConnection (com.cloudant.http.HttpConnection)3 HttpConnectionInterceptorContext (com.cloudant.http.HttpConnectionInterceptorContext)3 Replay429Interceptor (com.cloudant.http.interceptors.Replay429Interceptor)3 Dispatcher (okhttp3.mockwebserver.Dispatcher)3 HttpConnectionRequestInterceptor (com.cloudant.http.HttpConnectionRequestInterceptor)2 BasicAuthInterceptor (com.cloudant.http.interceptors.BasicAuthInterceptor)2 RequiresCloudant (com.cloudant.test.main.RequiresCloudant)2 RequiresCloudantService (com.cloudant.test.main.RequiresCloudantService)2 TestWithDbPerTest (com.cloudant.tests.base.TestWithDbPerTest)2