diff --git a/util/src/main/java/io/kubernetes/client/PodLogs.java b/util/src/main/java/io/kubernetes/client/PodLogs.java index 765d8462dc..90ef089137 100644 --- a/util/src/main/java/io/kubernetes/client/PodLogs.java +++ b/util/src/main/java/io/kubernetes/client/PodLogs.java @@ -95,6 +95,9 @@ public InputStream streamNamespacedPodLog( null); Response response = call.execute(); if (!response.isSuccessful()) { + if (response.body() != null) { + response.close(); + } throw new ApiException(response.code(), "Logs request failed: " + response.code()); } return response.body().byteStream(); diff --git a/util/src/test/java/io/kubernetes/client/PodLogsTest.java b/util/src/test/java/io/kubernetes/client/PodLogsTest.java index 1ffa82839f..143e0d30a9 100644 --- a/util/src/test/java/io/kubernetes/client/PodLogsTest.java +++ b/util/src/test/java/io/kubernetes/client/PodLogsTest.java @@ -19,6 +19,11 @@ import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.github.tomakehurst.wiremock.junit.WireMockRule; import io.kubernetes.client.openapi.ApiClient; @@ -33,6 +38,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; +import okhttp3.Call; +import okhttp3.Response; +import okhttp3.ResponseBody; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -127,4 +135,38 @@ public void testStream() throws ApiException, IOException { Streams.copy(is, bos); assertEquals(content, bos.toString()); } + + @Test + public void testResponseClosedOnError() throws ApiException, IOException { + V1Pod pod = + new V1Pod() + .metadata(new V1ObjectMeta().name(podName).namespace(namespace)) + .spec( + new V1PodSpec() + .containers(Arrays.asList(new V1Container().name(container).image("nginx")))); + + ApiClient mockClient = mock(ApiClient.class); + Call mockCall = mock(Call.class); + Response mockResponse = mock(Response.class); + + when(mockClient.escapeString(any())).thenReturn("foo"); + when(mockClient.buildCall(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn(mockCall); + when(mockCall.execute()).thenReturn(mockResponse); + when(mockResponse.isSuccessful()).thenReturn(false); + when(mockResponse.code()).thenReturn(404); + when(mockResponse.body()).thenReturn(mock(ResponseBody.class)); + + PodLogs logs = new PodLogs(mockClient); + boolean thrown; + try (InputStream ignored = logs.streamNamespacedPodLog(pod)) { + thrown = false; + } catch (ApiException ex) { + assertEquals(404, ex.getCode()); + thrown = true; + } + + assertTrue(thrown); + verify(mockResponse).close(); + } } diff --git a/util/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/util/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..ca6ee9cea8 --- /dev/null +++ b/util/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file