Home / Class/ HttpClientTransportTests Class — spring-boot Architecture

HttpClientTransportTests Class — spring-boot Architecture

Architecture documentation for the HttpClientTransportTests class in HttpClientTransportTests.java from the spring-boot codebase.

Entity Profile

Source Code

buildpack/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/transport/HttpClientTransportTests.java lines 63–378

@ExtendWith(MockitoExtension.class)
class HttpClientTransportTests {

	private static final String APPLICATION_JSON = "application/json";

	private static final String APPLICATION_X_TAR = "application/x-tar";

	@Mock
	@SuppressWarnings("NullAway.Init")
	private HttpClient client;

	@Mock
	@SuppressWarnings("NullAway.Init")
	private ClassicHttpResponse response;

	@Mock
	@SuppressWarnings("NullAway.Init")
	private HttpEntity entity;

	@Mock
	@SuppressWarnings("NullAway.Init")
	private InputStream content;

	private HttpClientTransport http;

	private URI uri;

	@BeforeEach
	void setup() throws Exception {
		this.http = new TestHttpClientTransport(this.client);
		this.uri = new URI("example");
	}

	@Test
	void getShouldExecuteHttpGet() throws Exception {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.get(this.uri);
		then(this.client).should().executeOpen(any(HttpHost.class), assertArg((request) -> {
			try {
				assertThat(request).isInstanceOf(HttpGet.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
				assertThat(response.getContent()).isSameAs(this.content);
			}
			catch (Exception ex) {
				throw new RuntimeException(ex);
			}
		}), isNull());

	}

	@Test
	void postShouldExecuteHttpPost() throws Exception {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.post(this.uri);
		then(this.client).should()
			.executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPost>) (request) -> {
				assertThat(request).isInstanceOf(HttpPost.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
				assertThat(request.getFirstHeader(HttpClientTransport.REGISTRY_AUTH_HEADER)).isNull();
				assertThat(response.getContent()).isSameAs(this.content);
			}), isNull());
	}

	@Test
	void postWithRegistryAuthShouldExecuteHttpPostWithHeader() throws Exception {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.post(this.uri, "auth token");
		then(this.client).should()
			.executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPost>) (request) -> {
				assertThat(request).isInstanceOf(HttpPost.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
				assertThat(request.getFirstHeader(HttpClientTransport.REGISTRY_AUTH_HEADER).getValue())
					.isEqualTo("auth token");
				assertThat(response.getContent()).isSameAs(this.content);
			}), isNull());
	}

	@Test
	void postWithEmptyRegistryAuthShouldExecuteHttpPostWithoutHeader() throws Exception {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.post(this.uri, "");
		then(this.client).should()
			.executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPost>) (request) -> {
				assertThat(request).isInstanceOf(HttpPost.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
				assertThat(request.getFirstHeader(HttpClientTransport.REGISTRY_AUTH_HEADER)).isNull();
				assertThat(response.getContent()).isSameAs(this.content);
			}), isNull());
	}

	@Test
	void postWithJsonContentShouldExecuteHttpPost() throws Exception {
		String content = "test";
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.post(this.uri, APPLICATION_JSON,
				(out) -> StreamUtils.copy(content, StandardCharsets.UTF_8, out));
		then(this.client).should()
			.executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPost>) (request) -> {
				HttpEntity entity = request.getEntity();
				assertThat(request).isInstanceOf(HttpPost.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(entity.isRepeatable()).isFalse();
				assertThat(entity.getContentLength()).isEqualTo(content.length());
				assertThat(entity.getContentType()).isEqualTo(APPLICATION_JSON);
				assertThat(entity.isStreaming()).isTrue();
				assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
				assertThat(writeToString(entity)).isEqualTo(content);
				assertThat(response.getContent()).isSameAs(this.content);
			}), isNull());
	}

	@Test
	void postWithArchiveContentShouldExecuteHttpPost() throws Exception {
		String content = "test";
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.post(this.uri, APPLICATION_X_TAR,
				(out) -> StreamUtils.copy(content, StandardCharsets.UTF_8, out));
		then(this.client).should()
			.executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPost>) (request) -> {
				HttpEntity entity = request.getEntity();
				assertThat(request).isInstanceOf(HttpPost.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(entity.isRepeatable()).isFalse();
				assertThat(entity.getContentLength()).isEqualTo(-1);
				assertThat(entity.getContentType()).isEqualTo(APPLICATION_X_TAR);
				assertThat(entity.isStreaming()).isTrue();
				assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
				assertThat(writeToString(entity)).isEqualTo(content);
				assertThat(response.getContent()).isSameAs(this.content);
			}), isNull());
	}

	@Test
	void putWithJsonContentShouldExecuteHttpPut() throws Exception {
		String content = "test";
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.put(this.uri, APPLICATION_JSON,
				(out) -> StreamUtils.copy(content, StandardCharsets.UTF_8, out));
		then(this.client).should().executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPut>) (request) -> {
			HttpEntity entity = request.getEntity();
			assertThat(request).isInstanceOf(HttpPut.class);
			assertThat(request.getUri()).isEqualTo(this.uri);
			assertThat(entity.isRepeatable()).isFalse();
			assertThat(entity.getContentLength()).isEqualTo(content.length());
			assertThat(entity.getContentType()).isEqualTo(APPLICATION_JSON);
			assertThat(entity.isStreaming()).isTrue();
			assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
			assertThat(writeToString(entity)).isEqualTo(content);
			assertThat(response.getContent()).isSameAs(this.content);
		}), isNull());
	}

	@Test
	void putWithArchiveContentShouldExecuteHttpPut() throws Exception {
		String content = "test";
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.put(this.uri, APPLICATION_X_TAR,
				(out) -> StreamUtils.copy(content, StandardCharsets.UTF_8, out));
		then(this.client).should().executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpPut>) (request) -> {
			HttpEntity entity = request.getEntity();
			assertThat(request).isInstanceOf(HttpPut.class);
			assertThat(request.getUri()).isEqualTo(this.uri);
			assertThat(entity.isRepeatable()).isFalse();
			assertThat(entity.getContentLength()).isEqualTo(-1);
			assertThat(entity.getContentType()).isEqualTo(APPLICATION_X_TAR);
			assertThat(entity.isStreaming()).isTrue();
			assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(entity::getContent);
			assertThat(writeToString(entity)).isEqualTo(content);
			assertThat(response.getContent()).isSameAs(this.content);
		}), isNull());
	}

	@Test
	void deleteShouldExecuteHttpDelete() throws Exception {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(200);
		Response response = this.http.delete(this.uri);

		then(this.client).should()
			.executeOpen(any(HttpHost.class), assertArg((ThrowingConsumer<HttpDelete>) (request) -> {
				assertThat(request).isInstanceOf(HttpDelete.class);
				assertThat(request.getUri()).isEqualTo(this.uri);
				assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
				assertThat(response.getContent()).isSameAs(this.content);
			}), isNull());
	}

	@Test
	void executeWhenResponseIsIn400RangeShouldThrowDockerException() throws IOException {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("errors.json"));
		given(this.response.getCode()).willReturn(404);
		assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> {
				assertThat(ex.getErrors()).hasSize(2);
				assertThat(ex.getResponseMessage()).isNull();
			});
	}

	@Test
	void executeWhenResponseIsIn500RangeWithNoContentShouldThrowDockerException() throws IOException {
		givenClientWillReturnResponse();
		given(this.response.getCode()).willReturn(500);
		assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> {
				assertThat(ex.getErrors()).isNull();
				assertThat(ex.getResponseMessage()).isNull();
			});
	}

	@Test
	void executeWhenResponseIsIn500RangeWithMessageShouldThrowDockerException() throws IOException {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("message.json"));
		given(this.response.getCode()).willReturn(500);
		assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> {
				assertThat(ex.getErrors()).isNull();
				Message responseMessage = ex.getResponseMessage();
				assertThat(responseMessage).isNotNull();
				assertThat(responseMessage.getMessage()).contains("test message");
			});
	}

	@Test
	void executeWhenResponseIsIn500RangeWithOtherContentShouldThrowDockerException() throws IOException {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(this.content);
		given(this.response.getCode()).willReturn(500);
		assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> {
				assertThat(ex.getErrors()).isNull();
				assertThat(ex.getResponseMessage()).isNull();
			});
	}

	@Test
	void shouldReturnErrorsAndMessage() throws IOException {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("message-and-errors.json"));
		given(this.response.getCode()).willReturn(404);
		assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> {
				assertThat(ex.getErrors()).hasSize(2);
				Message responseMessage = ex.getResponseMessage();
				assertThat(responseMessage).isNotNull();
				assertThat(responseMessage.getMessage()).contains("test message");
			});
	}

	@Test
	void shouldReturnContentIfProxyAuthError() throws IOException {
		givenClientWillReturnResponse();
		given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("proxy-error.txt"));
		given(this.response.getCode()).willReturn(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
		assertThatExceptionOfType(DockerEngineException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> {
				assertThat(ex.getErrors()).isNull();
				assertThat(ex.getResponseMessage()).isNull();
				assertThat(ex.getMessage()).contains("Some kind of proxy auth problem!");
			});
	}

	@Test
	void executeWhenClientThrowsIOExceptionRethrowsAsDockerException() throws IOException {
		given(this.client.executeOpen(any(HttpHost.class), any(HttpUriRequest.class), isNull()))
			.willThrow(new IOException("test IO exception"));
		assertThatExceptionOfType(DockerConnectionException.class).isThrownBy(() -> this.http.get(this.uri))
			.satisfies((ex) -> assertThat(ex.getMessage()).contains("test IO exception"));
	}

	private String writeToString(HttpEntity entity) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		entity.writeTo(out);
		return out.toString(StandardCharsets.UTF_8);
	}

	private void givenClientWillReturnResponse() throws IOException {
		given(this.client.executeOpen(any(HttpHost.class), any(HttpUriRequest.class), isNull()))
			.willReturn(this.response);
		given(this.response.getEntity()).willReturn(this.entity);
	}

	/**
	 * Test {@link HttpClientTransport} implementation.
	 */
	static class TestHttpClientTransport extends HttpClientTransport {

		protected TestHttpClientTransport(HttpClient client) throws URISyntaxException {
			super(client, HttpHost.create("docker://localhost"));
		}

	}

}

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free