diff --git a/spring-web/src/test/java/org/springframework/http/client/observation/DefaultClientRequestObservationConventionTests.java b/spring-web/src/test/java/org/springframework/http/client/observation/DefaultClientRequestObservationConventionTests.java index 6bed961f9a55..3984b3ab9927 100644 --- a/spring-web/src/test/java/org/springframework/http/client/observation/DefaultClientRequestObservationConventionTests.java +++ b/spring-web/src/test/java/org/springframework/http/client/observation/DefaultClientRequestObservationConventionTests.java @@ -20,10 +20,12 @@ import java.io.IOException; import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; import io.micrometer.observation.Observation; import org.junit.jupiter.api.Test; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatusCode; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.testfixture.http.client.MockClientHttpRequest; @@ -42,6 +44,8 @@ class DefaultClientRequestObservationConventionTests { private final MockClientHttpRequest request = new MockClientHttpRequest(HttpMethod.GET, "/test"); + private final static MockClientHttpResponse response = new MockClientHttpResponse(); + private final DefaultClientRequestObservationConvention observationConvention = new DefaultClientRequestObservationConvention(); @Test @@ -65,7 +69,7 @@ void supportsOnlyClientHttpObservationContext() { @Test void addsKeyValuesForRequestWithUriTemplate() { ClientRequestObservationContext context = createContext( - new MockClientHttpRequest(HttpMethod.GET, "/resource/{id}", 42), new MockClientHttpResponse()); + new MockClientHttpRequest(HttpMethod.GET, "/resource/{id}", 42), response); context.setUriTemplate("/resource/{id}"); assertThat(this.observationConvention.getLowCardinalityKeyValues(context)) .contains(KeyValue.of("exception", "none"), KeyValue.of("method", "GET"), KeyValue.of("uri", "/resource/{id}"), @@ -76,7 +80,7 @@ void addsKeyValuesForRequestWithUriTemplate() { @Test void addsKeyValuesForRequestWithUriTemplateWithHost() { ClientRequestObservationContext context = createContext( - new MockClientHttpRequest(HttpMethod.GET, "https://example.org/resource/{id}", 42), new MockClientHttpResponse()); + new MockClientHttpRequest(HttpMethod.GET, "https://example.org/resource/{id}", 42), response); context.setUriTemplate("https://example.org/resource/{id}"); assertThat(this.observationConvention.getLowCardinalityKeyValues(context)) .contains(KeyValue.of("exception", "none"), KeyValue.of("method", "GET"), KeyValue.of("uri", "/resource/{id}"), @@ -88,7 +92,7 @@ void addsKeyValuesForRequestWithUriTemplateWithHost() { @Test void addsKeyValuesForRequestWithoutUriTemplate() { ClientRequestObservationContext context = createContext( - new MockClientHttpRequest(HttpMethod.GET, "/resource/42"), new MockClientHttpResponse()); + new MockClientHttpRequest(HttpMethod.GET, "/resource/42"), response); assertThat(this.observationConvention.getLowCardinalityKeyValues(context)) .contains(KeyValue.of("method", "GET"), KeyValue.of("client.name", "none"), KeyValue.of("uri", "none")); assertThat(this.observationConvention.getHighCardinalityKeyValues(context)).contains(KeyValue.of("http.url", "/resource/42")); @@ -98,19 +102,60 @@ void addsKeyValuesForRequestWithoutUriTemplate() { void addsClientNameForRequestWithHost() { ClientRequestObservationContext context = createContext( new MockClientHttpRequest(HttpMethod.GET, "https://localhost:8080/resource/42"), - new MockClientHttpResponse()); + response); assertThat(this.observationConvention.getLowCardinalityKeyValues(context)).contains(KeyValue.of("client.name", "localhost")); } @Test void addsKeyValueForNonResolvableStatus() throws Exception { - ClientRequestObservationContext context = new ClientRequestObservationContext(this.request); ClientHttpResponse response = mock(); - context.setResponse(response); + ClientRequestObservationContext context = createContext(this.request, response); given(response.getStatusCode()).willThrow(new IOException("test error")); assertThat(this.observationConvention.getLowCardinalityKeyValues(context)).contains(KeyValue.of("status", "IO_ERROR")); } + @Test + void addKeyValueForNon200Response() { + MockClientHttpResponse response = new MockClientHttpResponse(new byte[0], HttpStatusCode.valueOf(400)); + ClientRequestObservationContext context = createContext(request, response); + KeyValues lowCardinality = this.observationConvention.getLowCardinalityKeyValues(context); + assertThat(lowCardinality).contains(KeyValue.of("status", "400")); + } + + @Test + void addKeyValuesForUnknownStatusResponse() { + MockClientHttpResponse response = new MockClientHttpResponse(new byte[0], 512); + ClientRequestObservationContext context = createContext(request, response); + KeyValues lowCardinalityKeyValues = this.observationConvention.getLowCardinalityKeyValues(context); + assertThat(lowCardinalityKeyValues).contains(KeyValue.of("status", "512"), KeyValue.of("outcome", "UNKNOWN")); + } + + @Test + void addKeyValuesForRequestNull() { + ClientRequestObservationContext context = createContext(null, response); + KeyValues highCardinality = this.observationConvention.getHighCardinalityKeyValues(context); + assertThat(highCardinality).contains(KeyValue.of("http.url", "none")); + KeyValues lowCardinality = this.observationConvention.getLowCardinalityKeyValues(context); + assertThat(lowCardinality).contains(KeyValue.of("method", "none"), KeyValue.of("exception", "none"), + KeyValue.of("client.name", "none"), KeyValue.of("uri", "none") + ); + } + + @Test + void addKeyValueForResponseNull() { + ClientRequestObservationContext context = createContext(this.request, null); + KeyValues lowCardinality = this.observationConvention.getLowCardinalityKeyValues(context); + assertThat(lowCardinality).contains(KeyValue.of("status", "CLIENT_ERROR")); + } + + @Test + void addKeyValueForContextError() { + ClientRequestObservationContext context = createContext(this.request, response); + context.setError(new RuntimeException("error")); + KeyValues lowCardinality = this.observationConvention.getLowCardinalityKeyValues(context); + assertThat(lowCardinality).contains(KeyValue.of("exception", "RuntimeException")); + } + private ClientRequestObservationContext createContext(ClientHttpRequest request, ClientHttpResponse response) { ClientRequestObservationContext context = new ClientRequestObservationContext(request); context.setResponse(response);