/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.docker.client; import com.google.common.io.CharStreams; import com.google.common.reflect.TypeToken; import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.eclipse.che.commons.json.JsonParseException; import org.eclipse.che.commons.lang.ws.rs.ExtMediaType; import org.eclipse.che.commons.test.mockito.answer.SelfReturningAnswer; import org.eclipse.che.dto.server.DtoFactory; import org.eclipse.che.plugin.docker.client.connection.CloseConnectionInputStream; import org.eclipse.che.plugin.docker.client.connection.DockerConnection; import org.eclipse.che.plugin.docker.client.connection.DockerConnectionFactory; import org.eclipse.che.plugin.docker.client.connection.DockerResponse; import org.eclipse.che.plugin.docker.client.dto.AuthConfig; import org.eclipse.che.plugin.docker.client.dto.AuthConfigs; import org.eclipse.che.plugin.docker.client.exception.ContainerNotFoundException; import org.eclipse.che.plugin.docker.client.exception.DockerException; import org.eclipse.che.plugin.docker.client.exception.ExecNotFoundException; import org.eclipse.che.plugin.docker.client.exception.ImageNotFoundException; import org.eclipse.che.plugin.docker.client.exception.NetworkNotFoundException; import org.eclipse.che.plugin.docker.client.json.ContainerCommitted; import org.eclipse.che.plugin.docker.client.json.ContainerConfig; import org.eclipse.che.plugin.docker.client.json.ContainerCreated; import org.eclipse.che.plugin.docker.client.json.ContainerExitStatus; import org.eclipse.che.plugin.docker.client.json.ContainerInfo; import org.eclipse.che.plugin.docker.client.json.ContainerListEntry; import org.eclipse.che.plugin.docker.client.json.ContainerProcesses; import org.eclipse.che.plugin.docker.client.json.Event; import org.eclipse.che.plugin.docker.client.json.ExecCreated; import org.eclipse.che.plugin.docker.client.json.ExecInfo; import org.eclipse.che.plugin.docker.client.json.Filters; import org.eclipse.che.plugin.docker.client.json.Image; import org.eclipse.che.plugin.docker.client.json.ImageInfo; import org.eclipse.che.plugin.docker.client.json.NetworkCreated; import org.eclipse.che.plugin.docker.client.json.SystemInfo; import org.eclipse.che.plugin.docker.client.json.Version; import org.eclipse.che.plugin.docker.client.json.network.ConnectContainer; import org.eclipse.che.plugin.docker.client.json.network.ContainerInNetwork; import org.eclipse.che.plugin.docker.client.json.network.DisconnectContainer; import org.eclipse.che.plugin.docker.client.json.network.EndpointConfig; import org.eclipse.che.plugin.docker.client.json.network.Ipam; import org.eclipse.che.plugin.docker.client.json.network.IpamConfig; import org.eclipse.che.plugin.docker.client.json.network.Network; import org.eclipse.che.plugin.docker.client.json.network.NewIpamConfig; import org.eclipse.che.plugin.docker.client.json.network.NewNetwork; import org.eclipse.che.plugin.docker.client.params.AttachContainerParams; import org.eclipse.che.plugin.docker.client.params.BuildImageParams; import org.eclipse.che.plugin.docker.client.params.CommitParams; import org.eclipse.che.plugin.docker.client.params.CreateContainerParams; import org.eclipse.che.plugin.docker.client.params.CreateExecParams; import org.eclipse.che.plugin.docker.client.params.GetContainerLogsParams; import org.eclipse.che.plugin.docker.client.params.GetEventsParams; import org.eclipse.che.plugin.docker.client.params.GetExecInfoParams; import org.eclipse.che.plugin.docker.client.params.GetResourceParams; import org.eclipse.che.plugin.docker.client.params.InspectContainerParams; import org.eclipse.che.plugin.docker.client.params.InspectImageParams; import org.eclipse.che.plugin.docker.client.params.KillContainerParams; import org.eclipse.che.plugin.docker.client.params.ListContainersParams; import org.eclipse.che.plugin.docker.client.params.ListImagesParams; import org.eclipse.che.plugin.docker.client.params.PullParams; import org.eclipse.che.plugin.docker.client.params.PushParams; import org.eclipse.che.plugin.docker.client.params.PutResourceParams; import org.eclipse.che.plugin.docker.client.params.RemoveContainerParams; import org.eclipse.che.plugin.docker.client.params.RemoveImageParams; import org.eclipse.che.plugin.docker.client.params.network.RemoveNetworkParams; import org.eclipse.che.plugin.docker.client.params.StartContainerParams; import org.eclipse.che.plugin.docker.client.params.StartExecParams; import org.eclipse.che.plugin.docker.client.params.StopContainerParams; import org.eclipse.che.plugin.docker.client.params.TagParams; import org.eclipse.che.plugin.docker.client.params.TopParams; import org.eclipse.che.plugin.docker.client.params.WaitContainerParams; import org.eclipse.che.plugin.docker.client.params.network.ConnectContainerToNetworkParams; import org.eclipse.che.plugin.docker.client.params.network.CreateNetworkParams; import org.eclipse.che.plugin.docker.client.params.network.DisconnectContainerFromNetworkParams; import org.eclipse.che.plugin.docker.client.params.network.GetNetworksParams; import org.eclipse.che.plugin.docker.client.params.network.InspectNetworkParams; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.testng.MockitoTestNGListener; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Listeners; import org.testng.annotations.Test; import javax.ws.rs.core.MediaType; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; /** * @author Anton Korneta * @author Mykola Morhun */ @Listeners(MockitoTestNGListener.class) public class DockerConnectorTest { private static final Gson GSON = new GsonBuilder().disableHtmlEscaping() .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) .create(); private static final String ERROR_MESSAGE = "some error occurs"; private static final String EXCEPTION_ERROR_MESSAGE = "Error response from docker API, status: 500, message: " + ERROR_MESSAGE; private static final int RESPONSE_ERROR_CODE = 500; private static final int RESPONSE_NOT_FOUND_CODE = 404; private static final int RESPONSE_SUCCESS_CODE = 200; private static final int RESPONSE_NO_CONTENT_CODE = 204; private static final int RESPONSE_CREATED_CODE = 201; private static final String REQUEST_METHOD_GET = "GET"; private static final String REQUEST_METHOD_POST = "POST"; private static final String REQUEST_METHOD_PUT = "PUT"; private static final String REQUEST_METHOD_DELETE = "DELETE"; private static final String IMAGE = "image"; private static final String REPOSITORY = "repository"; private static final String CONTAINER = "container"; private static final String REGISTRY = "registry"; private static final String TAG = "tag"; private static final String DIGEST = "hash:1234567890"; private static final String EXEC_ID = "exec_id"; private static final String PATH_TO_FILE = "/home/user/path/file.ext"; private static final String STREAM_DATA = "stream data"; private static final String DOCKER_RESPONSE = "stream"; private static final String API_VERSION_PREFIX = ""; private static final String[] CMD_WITH_ARGS = {"command", "arg1", "arg2"}; private static final String[] CMD_ARGS = {"arg1", "arg2"}; private static final byte[] STREAM_DATA_BYTES = STREAM_DATA.getBytes(); private static final byte[] DOCKER_RESPONSE_BYTES = DOCKER_RESPONSE.getBytes(); private static final int CONTAINER_EXIT_CODE = 0; @Mock private DockerConnectorConfiguration dockerConnectorConfiguration; @Mock private DockerConnectionFactory dockerConnectionFactory; @Mock private DockerResponse dockerResponse; @Mock private ProgressMonitor progressMonitor; @Mock private InitialAuthConfig initialAuthConfig; @Mock private AuthConfigs authConfigs; @Mock private MessageProcessor<LogMessage> logMessageProcessor; @Mock private MessageProcessor<Event> eventMessageProcessor; @Mock private File dockerfile; @Mock private DockerRegistryAuthResolver authManager; @Mock private DockerApiVersionPathPrefixProvider dockerApiVersionPathPrefixProvider; @Captor private ArgumentCaptor<Object> captor; private InputStream inputStream; private DockerConnector dockerConnector; private DockerConnection dockerConnection; @BeforeMethod public void setup() throws IOException, URISyntaxException { dockerConnection = mock(DockerConnection.class, new SelfReturningAnswer()); when(dockerConnectionFactory.openConnection(any(URI.class))).thenReturn(dockerConnection); when(dockerConnection.request()).thenReturn(dockerResponse); when(dockerConnectorConfiguration.getAuthConfigs()).thenReturn(initialAuthConfig); when(dockerResponse.getStatus()).thenReturn(RESPONSE_SUCCESS_CODE); when(initialAuthConfig.getAuthConfigs()).thenReturn(authConfigs); when(authConfigs.getConfigs()).thenReturn(new HashMap<>()); when(dockerApiVersionPathPrefixProvider.get()).thenReturn(API_VERSION_PREFIX); dockerConnector = spy(new DockerConnector(dockerConnectorConfiguration, dockerConnectionFactory, authManager, dockerApiVersionPathPrefixProvider)); inputStream = spy(new ByteArrayInputStream(ERROR_MESSAGE.getBytes())); when(dockerResponse.getInputStream()).thenReturn(inputStream); } @Test public void shouldBeAbleToGetSystemInfo() throws IOException, JsonParseException { SystemInfo systemInfo = mock(SystemInfo.class); doReturn(systemInfo).when(dockerConnector).parseResponseStreamAndClose(inputStream, SystemInfo.class); SystemInfo returnedSystemInfo = dockerConnector.getSystemInfo(); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/info"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedSystemInfo, systemInfo); } @Test public void shouldBeAbleToGetSystemInfoByUrlWithConcreteApiVersion() throws IOException, JsonParseException { String apiVersion = "/v1.18"; when(dockerApiVersionPathPrefixProvider.get()).thenReturn(apiVersion); dockerConnector = spy(new DockerConnector(dockerConnectorConfiguration, dockerConnectionFactory, authManager, dockerApiVersionPathPrefixProvider)); SystemInfo systemInfo = mock(SystemInfo.class); doReturn(systemInfo).when(dockerConnector).parseResponseStreamAndClose(inputStream, SystemInfo.class); SystemInfo returnedSystemInfo = dockerConnector.getSystemInfo(); verify(dockerConnection).path(apiVersion + "/info"); assertEquals(returnedSystemInfo, systemInfo); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileGettingSystemInfoIfResponseCodeIsNotSuccess() throws IOException { when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.getSystemInfo(); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToGetVersion() throws IOException, JsonParseException { Version version = mock(Version.class); doReturn(version).when(dockerConnector).parseResponseStreamAndClose(inputStream, Version.class); Version returnedVersion = dockerConnector.getVersion(); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/version"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedVersion, version); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileGettingVersionIfResponseCodeIsNotSuccess() throws IOException { when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.getVersion(); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToGetListImages() throws IOException, JsonParseException { ListImagesParams listImagesParams = ListImagesParams.create(); List<Image> images = new ArrayList<>(); images.add(mock(Image.class)); doReturn(images).when(dockerConnector).parseResponseStreamAndClose(eq(inputStream), Matchers.<TypeToken<List<Image>>>any()); List<Image> returnedImages = dockerConnector.listImages(listImagesParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/images/json"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedImages, images); } @Test public void shouldInvokeGetListImagesWithDefaultParamsWhenGetListImagesCalledWithoutParams() throws IOException, JsonParseException { List<Image> images = new ArrayList<>(); images.add(mock(Image.class)); doReturn(images).when(dockerConnector).parseResponseStreamAndClose(eq(inputStream), Matchers.<TypeToken<List<Image>>>any()); List<Image> returnedImages = dockerConnector.listImages(); verify(dockerConnector).listImages((ListImagesParams)captor.capture()); assertEquals(captor.getValue(), ListImagesParams.create()); assertEquals(returnedImages, images); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileListingImagesIfResponseCodeIsNotSuccess() throws IOException { when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.listImages(); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToGetListContainersWithListContainersParams() throws IOException, JsonParseException { ListContainersParams listContainersParams = ListContainersParams.create().withAll(true).withSize(true); ContainerListEntry containerListEntry = mock(ContainerListEntry.class); List<ContainerListEntry> expectedListContainers = singletonList(containerListEntry); doReturn(expectedListContainers).when(dockerConnector) .parseResponseStreamAndClose(eq(inputStream), Matchers.<TypeToken<List<ContainerListEntry>>>any()); List<ContainerListEntry> containers = dockerConnector.listContainers(listContainersParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/containers/json"); verify(dockerConnection).query("all", 1); verify(dockerConnection).query("size", 1); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); verify(dockerConnector).parseResponseStreamAndClose(eq(inputStream), Matchers.<TypeToken<List<ContainerListEntry>>>any()); assertEquals(containers, expectedListContainers); } @Test public void shouldBeAbleToGetListContainersByFiltersInTheListContainersParams() throws IOException, JsonParseException { Filters filters = new Filters().withFilter("testKey", "testValue"); ListContainersParams listContainersParams = ListContainersParams.create().withFilters(filters); ContainerListEntry containerListEntry = mock(ContainerListEntry.class); List<ContainerListEntry> expectedListContainers = singletonList(containerListEntry); doReturn(expectedListContainers).when(dockerConnector) .parseResponseStreamAndClose(eq(inputStream), Matchers.<TypeToken<List<ContainerListEntry>>>any()); List<ContainerListEntry> containers = dockerConnector.listContainers(listContainersParams); verify(dockerConnection).query(eq("filters"), anyObject()); assertEquals(containers, expectedListContainers); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileGettingListContainersByParamsObjectIfResponseCodeIsNotSuccess() throws IOException, JsonParseException { ListContainersParams listContainersParams = ListContainersParams.create(); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.listContainers(listContainersParams); verify(dockerResponse).getStatus(); } @Test public void shouldCallListContainersWithParametersObject() throws IOException { ListContainersParams listContainersParams = ListContainersParams.create().withAll(true); ContainerListEntry containerListEntry = mock(ContainerListEntry.class); List<ContainerListEntry> expectedListContainers = singletonList(containerListEntry); doReturn(expectedListContainers).when(dockerConnector).listContainers(listContainersParams); List<ContainerListEntry> result = dockerConnector.listContainers(); ArgumentCaptor<ListContainersParams> listContainersParamsArgumentCaptor = ArgumentCaptor.forClass(ListContainersParams.class); verify(dockerConnector).listContainers(listContainersParamsArgumentCaptor.capture()); assertEquals(result, expectedListContainers); assertEquals(listContainersParamsArgumentCaptor.getValue(), listContainersParams); } @Test public void shouldCallInspectImageWithParametersObject() throws IOException { InspectImageParams inspectImageParams = InspectImageParams.create(IMAGE); ImageInfo imageInfo = mock(ImageInfo.class); doReturn(imageInfo).when(dockerConnector).inspectImage(any(InspectImageParams.class)); ImageInfo returnedImageInfo = dockerConnector.inspectImage(IMAGE); verify(dockerConnector).inspectImage((InspectImageParams)captor.capture()); assertEquals(captor.getValue(), inspectImageParams); assertEquals(returnedImageInfo, imageInfo); } @Test public void shouldBeAbleToInspectImage() throws IOException, JsonParseException { InspectImageParams inspectImageParams = InspectImageParams.create(IMAGE); ImageInfo imageInfo = mock(ImageInfo.class); doReturn(imageInfo).when(dockerConnector).parseResponseStreamAndClose(inputStream, ImageInfo.class); ImageInfo returnedImageInfo = dockerConnector.inspectImage(inspectImageParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/images/" + inspectImageParams.getImage() + "/json"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedImageInfo, imageInfo); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileGettingImageInfoIfResponseCodeIsNotSuccess() throws IOException { InspectImageParams inspectImageParams = InspectImageParams.create(IMAGE); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.inspectImage(inspectImageParams); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = ImageNotFoundException.class, expectedExceptionsMessageRegExp = ERROR_MESSAGE) public void shouldThrowImageNotFoundExceptionOnGettingImageInfoIfResponseCodeIs404() throws IOException { InspectImageParams inspectImageParams = InspectImageParams.create(IMAGE); when(dockerResponse.getStatus()).thenReturn(RESPONSE_NOT_FOUND_CODE); dockerConnector.inspectImage(inspectImageParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToStopContainer() throws IOException { StopContainerParams stopContainerParams = StopContainerParams.create(CONTAINER); dockerConnector.stopContainer(stopContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/" + stopContainerParams.getContainer() + "/stop"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileStoppingContainerIfResponseCodeIsNotSuccess() throws IOException { StopContainerParams stopContainerParams = StopContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.stopContainer(stopContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldCallKillContainerWithParametersObject() throws IOException { KillContainerParams killContainerParams = KillContainerParams.create(CONTAINER); doNothing().when(dockerConnector).killContainer(killContainerParams); dockerConnector.killContainer(CONTAINER); verify(dockerConnector).killContainer((KillContainerParams)captor.capture()); assertEquals(captor.getValue(), killContainerParams); } @Test public void shouldBeAbleToKillContainer() throws IOException { KillContainerParams killContainerParams = KillContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_NO_CONTENT_CODE); dockerConnector.killContainer(killContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/" + killContainerParams.getContainer() + "/kill"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileKillingContainerIfResponseCodeIsNotSuccess() throws IOException { KillContainerParams killContainerParams = KillContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.killContainer(killContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToRemoveContainer() throws IOException { RemoveContainerParams removeContainerParams = RemoveContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_NO_CONTENT_CODE); dockerConnector.removeContainer(removeContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_DELETE); verify(dockerConnection).path("/containers/" + removeContainerParams.getContainer()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileRemovingContainerIfResponseCodeIsNotSuccess() throws IOException { RemoveContainerParams removeContainerParams = RemoveContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.removeContainer(removeContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldCallWaitContainerWithParametersObject() throws IOException { WaitContainerParams waitContainerParams = WaitContainerParams.create(CONTAINER); doReturn(CONTAINER_EXIT_CODE).when(dockerConnector).waitContainer(waitContainerParams); int returnedExitCode = dockerConnector.waitContainer(CONTAINER); verify(dockerConnector).waitContainer((WaitContainerParams)captor.capture()); assertEquals(captor.getValue(), waitContainerParams); assertEquals(returnedExitCode, CONTAINER_EXIT_CODE); } @Test public void shouldBeAbleToWaitContainer() throws IOException, JsonParseException { WaitContainerParams waitContainerParams = WaitContainerParams.create(CONTAINER); ContainerExitStatus containerExitStatus = new ContainerExitStatus(); containerExitStatus.setStatusCode(CONTAINER_EXIT_CODE); doReturn(containerExitStatus).when(dockerConnector).parseResponseStreamAndClose(inputStream, ContainerExitStatus.class); int returnedExitCode = dockerConnector.waitContainer(waitContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/" + waitContainerParams.getContainer() + "/wait"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedExitCode, containerExitStatus.getStatusCode()); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileWaitingContainerIfResponseCodeIsNotSuccess() throws IOException { WaitContainerParams waitContainerParams = WaitContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.waitContainer(waitContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldCallInspectContainerWithParametersObject() throws IOException { InspectContainerParams inspectContainerParams = InspectContainerParams.create(CONTAINER); ContainerInfo containerInfo = mock(ContainerInfo.class); doReturn(containerInfo).when(dockerConnector).inspectContainer(inspectContainerParams); ContainerInfo returnedContainerInfo = dockerConnector.inspectContainer(CONTAINER); verify(dockerConnector).inspectContainer((InspectContainerParams)captor.capture()); assertEquals(captor.getValue(), inspectContainerParams); assertEquals(returnedContainerInfo, containerInfo); } @Test public void shouldBeAbleToInspectContainer() throws IOException, JsonParseException { InspectContainerParams inspectContainerParams = InspectContainerParams.create(CONTAINER); ContainerInfo containerInfo = mock(ContainerInfo.class); doReturn(containerInfo).when(dockerConnector).parseResponseStreamAndClose(inputStream, ContainerInfo.class); ContainerInfo returnedContainerInfo = dockerConnector.inspectContainer(inspectContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/containers/" + inspectContainerParams.getContainer() + "/json"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedContainerInfo, containerInfo); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileInspectingContainerIfResponseCodeIsNotSuccess() throws IOException { InspectContainerParams inspectContainerParams = InspectContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.inspectContainer(inspectContainerParams); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = ContainerNotFoundException.class, expectedExceptionsMessageRegExp = ERROR_MESSAGE) public void shouldThrowContainerNotFoundExceptionOnInspectingContainerIfResponseCodeIs404() throws IOException { InspectContainerParams inspectContainerParams = InspectContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_NOT_FOUND_CODE); dockerConnector.inspectContainer(inspectContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToAttachContainer() throws IOException { AttachContainerParams attachContainerParams = AttachContainerParams.create(CONTAINER); when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(DOCKER_RESPONSE_BYTES)); dockerConnector.attachContainer(attachContainerParams, logMessageProcessor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/" + attachContainerParams.getContainer() + "/attach"); verify(dockerConnection).query("stdout", 1); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileAttachingContainerIfResponseCodeIsNotSuccess() throws IOException { AttachContainerParams attachContainerParams = AttachContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.attachContainer(attachContainerParams, logMessageProcessor); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToGetContainerLogs() throws IOException { GetContainerLogsParams getContainerLogsParams = GetContainerLogsParams.create(CONTAINER); when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(DOCKER_RESPONSE_BYTES)); dockerConnector.getContainerLogs(getContainerLogsParams, logMessageProcessor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/containers/" + getContainerLogsParams.getContainer() + "/logs"); verify(dockerConnection).query("stdout", 1); verify(dockerConnection).query("stderr", 1); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileGettingContainerLogsIfResponseCodeIs5xx() throws IOException { GetContainerLogsParams getContainerLogsParams = GetContainerLogsParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.getContainerLogs(getContainerLogsParams, logMessageProcessor); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = ContainerNotFoundException.class) public void shouldThrowContainerNotFoundExceptionWhileGettingContainerLogsIfResponseCodeIs404() throws IOException { GetContainerLogsParams getContainerLogsParams = GetContainerLogsParams.create(CONTAINER); when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream("container not found".getBytes())); when(dockerResponse.getStatus()).thenReturn(RESPONSE_NOT_FOUND_CODE); dockerConnector.getContainerLogs(getContainerLogsParams, logMessageProcessor); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToCreateExec() throws IOException, JsonParseException { CreateExecParams createExecParams = CreateExecParams.create(CONTAINER, CMD_WITH_ARGS); Exec exec = new Exec(CMD_WITH_ARGS, EXEC_ID); ExecCreated execCreated = mock(ExecCreated.class); doReturn(execCreated).when(dockerConnector).parseResponseStreamAndClose(inputStream, ExecCreated.class); when(execCreated.getId()).thenReturn(EXEC_ID); Exec returnedExec = dockerConnector.createExec(createExecParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/" + createExecParams.getContainer() + "/exec"); verify(dockerConnection).header("Content-Type", MediaType.APPLICATION_JSON); verify(dockerConnection).header(eq("Content-Length"), anyInt()); verify(dockerConnection).entity(any(byte[].class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedExec, exec); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileCreatingExecIfResponseCodeIsNotSuccess() throws IOException { CreateExecParams inspectContainerParams = CreateExecParams.create(CONTAINER, CMD_WITH_ARGS); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.createExec(inspectContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToStartExec() throws IOException { StartExecParams startExecParams = StartExecParams.create(EXEC_ID); doReturn(new ByteArrayInputStream(DOCKER_RESPONSE_BYTES)).when(dockerResponse).getInputStream(); dockerConnector.startExec(startExecParams, logMessageProcessor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/exec/" + startExecParams.getExecId() + "/start"); verify(dockerConnection).header("Content-Type", MediaType.APPLICATION_JSON); verify(dockerConnection).header(eq("Content-Length"), anyInt()); verify(dockerConnection).entity(any(byte[].class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = ExecNotFoundException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void execStartShouldThrowExecNotFoundIf404Received() throws IOException { StartExecParams startExecParams = StartExecParams.create(EXEC_ID); doReturn(new ByteArrayInputStream(EXCEPTION_ERROR_MESSAGE.getBytes())).when(dockerResponse).getInputStream(); when(dockerResponse.getStatus()).thenReturn(RESPONSE_NOT_FOUND_CODE); dockerConnector.startExec(startExecParams, logMessageProcessor); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileStartingExecIfResponseCodeIsNotSuccess() throws IOException { StartExecParams startExecParams = StartExecParams.create(EXEC_ID); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.startExec(startExecParams, logMessageProcessor); verify(dockerResponse).getStatus(); } @Test public void shouldCallGetExecInfoWithParametersObject() throws IOException { GetExecInfoParams getExecInfoParams = GetExecInfoParams.create(EXEC_ID); ExecInfo execInfo = mock(ExecInfo.class); doReturn(execInfo).when(dockerConnector).getExecInfo(any(GetExecInfoParams.class)); dockerConnector.getExecInfo(EXEC_ID); verify(dockerConnector).getExecInfo((GetExecInfoParams)captor.capture()); assertEquals(captor.getValue(), getExecInfoParams); } @Test public void shouldBeAbleToGetExecInfo() throws IOException, JsonParseException { GetExecInfoParams getExecInfoParams = GetExecInfoParams.create(EXEC_ID); ExecInfo execInfo = mock(ExecInfo.class); doReturn(execInfo).when(dockerConnector).parseResponseStreamAndClose(inputStream, ExecInfo.class); ExecInfo returnedExecInfo = dockerConnector.getExecInfo(getExecInfoParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/exec/" + getExecInfoParams.getExecId() + "/json"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedExecInfo, execInfo); } @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowIOExceptionWhileGettingExecInfoIfResponseCodeIsNotSuccess() throws IOException { GetExecInfoParams getExecInfoParams = GetExecInfoParams.create(EXEC_ID); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.getExecInfo(getExecInfoParams); verify(dockerResponse).getStatus(); } @Test public void topShouldBeAbleToGetProcesses() throws IOException, JsonParseException { TopParams topParams = TopParams.create(CONTAINER); ContainerProcesses containerProcesses = mock(ContainerProcesses.class); doReturn(containerProcesses).when(dockerConnector).parseResponseStreamAndClose(inputStream, ContainerProcesses.class); ContainerProcesses returnedContainerProcesses = dockerConnector.top(topParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/containers/" + topParams.getContainer() + "/top"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedContainerProcesses, containerProcesses); } @Test public void topWithPsArgsShouldBeAbleToGetProcesses() throws IOException, JsonParseException { TopParams topParams = TopParams.create(CONTAINER) .withPsArgs(CMD_ARGS); ContainerProcesses containerProcesses = mock(ContainerProcesses.class); doReturn(containerProcesses).when(dockerConnector).parseResponseStreamAndClose(inputStream, ContainerProcesses.class); ContainerProcesses returnedContainerProcesses = dockerConnector.top(topParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/containers/" + topParams.getContainer() + "/top"); verify(dockerConnection).query(eq("ps_args"), anyString()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedContainerProcesses, containerProcesses); } @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void topShouldThrowIOExceptionWhileGettingProcessesIfResponseCodeIsNotSuccess() throws IOException { TopParams topParams = TopParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.top(topParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToGetResourcesFromContainer() throws IOException { GetResourceParams getResourceParams = GetResourceParams.create(CONTAINER, PATH_TO_FILE); when(dockerResponse.getInputStream()) .thenReturn(new CloseConnectionInputStream(new ByteArrayInputStream(STREAM_DATA_BYTES), dockerConnection)); String response = CharStreams.toString(new InputStreamReader(dockerConnector.getResource(getResourceParams))); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/containers/" + getResourceParams.getContainer() + "/archive"); verify(dockerConnection).query(eq("path"), eq(PATH_TO_FILE)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(response, STREAM_DATA); } @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldProduceErrorWhenGetsResourcesFromContainerIfResponseCodeIsNotSuccess() throws IOException { GetResourceParams getResourceParams = GetResourceParams.create(CONTAINER, PATH_TO_FILE); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); when(dockerResponse.getInputStream()) .thenReturn(new CloseConnectionInputStream(new ByteArrayInputStream(ERROR_MESSAGE.getBytes()), dockerConnection)); dockerConnector.getResource(getResourceParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToPutResourcesIntoContainer() throws IOException { InputStream source = new CloseConnectionInputStream(new ByteArrayInputStream(STREAM_DATA_BYTES), dockerConnection); PutResourceParams putResourceParams = PutResourceParams.create(CONTAINER, PATH_TO_FILE, source); dockerConnector.putResource(putResourceParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_PUT); verify(dockerConnection).path("/containers/" + putResourceParams.getContainer() + "/archive"); verify(dockerConnection).query(eq("path"), eq(PATH_TO_FILE)); verify(dockerConnection).header("Content-Type", ExtMediaType.APPLICATION_X_TAR); verify(dockerConnection).header(eq("Content-Length"), anyInt()); verify(dockerConnection).entity(any(InputStream.class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldProduceErrorWhenPutsResourcesIntoContainerIfResponseCodeIsNotSuccess() throws IOException { InputStream source = new CloseConnectionInputStream(new ByteArrayInputStream(ERROR_MESSAGE.getBytes()), dockerConnection); PutResourceParams putResourceParams = PutResourceParams.create(CONTAINER, PATH_TO_FILE, source); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); when(dockerResponse.getInputStream()) .thenReturn(new ByteArrayInputStream(ERROR_MESSAGE.getBytes())); dockerConnector.putResource(putResourceParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToGetEvents() throws IOException { GetEventsParams getEventsParams = GetEventsParams.create(); doReturn(new ByteArrayInputStream(STREAM_DATA_BYTES)).when(dockerResponse).getInputStream(); dockerConnector.getEvents(getEventsParams, eventMessageProcessor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/events"); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileGettingEventsIfResponseCodeIsNotSuccess() throws IOException { GetEventsParams getExecInfoParams = GetEventsParams.create(); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.getEvents(getExecInfoParams, eventMessageProcessor); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToBuildImage() throws IOException, InterruptedException { AuthConfigs authConfigs = DtoFactory.newDto(AuthConfigs.class); AuthConfig authConfig = DtoFactory.newDto(AuthConfig.class); Map<String, AuthConfig> auth = new HashMap<>(); auth.put("auth", authConfig); authConfigs.setConfigs(auth); final String imageId = "37a7da3b7edc"; BuildImageParams buildImageParams = BuildImageParams.create(dockerfile) .withAuthConfigs(authConfigs); doReturn(new ByteArrayInputStream(("{\"stream\":\"Successfully built " + imageId + "\"}").getBytes())) .when(dockerResponse).getInputStream(); String returnedImageId = dockerConnector.buildImage(buildImageParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/build"); verify(dockerConnection).header("Content-Type", "application/x-compressed-tar"); verify(dockerConnection).header(eq("Content-Length"), anyInt()); verify(dockerConnection).entity(any(InputStream.class)); verify(dockerConnection, never()).header(eq("remote"), anyString()); verify(dockerConnection).header(eq("X-Registry-Config"), any(byte[].class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedImageId, imageId); } @Test public void shouldBeAbleToBuildImageWithRemoteContext() throws IOException, InterruptedException { AuthConfigs authConfigs = DtoFactory.newDto(AuthConfigs.class); AuthConfig authConfig = DtoFactory.newDto(AuthConfig.class); Map<String, AuthConfig> auth = new HashMap<>(); auth.put("auth", authConfig); authConfigs.setConfigs(auth); final String imageId = "37a7da3b7edc"; final String remote = "https://some.host.com/path/tarball.tar"; BuildImageParams buildImageParams = BuildImageParams.create(remote) .withAuthConfigs(authConfigs); doReturn(new ByteArrayInputStream(("{\"stream\":\"Successfully built " + imageId + "\"}").getBytes())) .when(dockerResponse).getInputStream(); String returnedImageId = dockerConnector.buildImage(buildImageParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/build"); verify(dockerConnection).query(eq("remote"), eq(remote)); verify(dockerConnection, never()).header("Content-Type", "application/x-compressed-tar"); verify(dockerConnection, never()).header(eq("Content-Length"), anyInt()); verify(dockerConnection, never()).entity(any(InputStream.class)); verify(dockerConnection).header(eq("X-Registry-Config"), any(byte[].class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedImageId, imageId); } @Test public void shouldBeAbleToBuildImageWithAdditionalQueryParameters() throws IOException, InterruptedException { AuthConfigs authConfigs = DtoFactory.newDto(AuthConfigs.class); AuthConfig authConfig = DtoFactory.newDto(AuthConfig.class); Map<String, AuthConfig> auth = new HashMap<>(); auth.put("auth", authConfig); authConfigs.setConfigs(auth); final String imageId = "37a7da3b7edc"; final String repository = "repo/name"; final String tag = "tag"; final boolean rm = true; final boolean forcerm = true; final long memory = 2147483648L; final long memswap = 3221225472L; final boolean pull = true; final String dockerfile = "path/Dockerfile"; final boolean nocache = true; final boolean q = true; final String cpusetcpus = "4-5"; final long cpuperiod = 10000L; final long cpuquota = 5000L; final Map<String, String> buildargs = new HashMap<>(); buildargs.put("constraint:label.com!", "value"); BuildImageParams buildImageParams = BuildImageParams.create(this.dockerfile) .withAuthConfigs(authConfigs) .withRepository(repository) .withTag(tag) .withRemoveIntermediateContainers(rm) .withForceRemoveIntermediateContainers(forcerm) .withMemoryLimit(memory) .withMemorySwapLimit(memswap) .withDoForcePull(pull) .withDockerfile(dockerfile) .withNoCache(nocache) .withQuiet(q) .withCpusetCpus(cpusetcpus) .withCpuPeriod(cpuperiod) .withCpuQuota(cpuquota) .withBuildArgs(buildargs); doReturn(new ByteArrayInputStream(("{\"stream\":\"Successfully built " + imageId + "\"}").getBytes())) .when(dockerResponse).getInputStream(); String returnedImageId = dockerConnector.buildImage(buildImageParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/build"); verify(dockerConnection).header("Content-Type", "application/x-compressed-tar"); verify(dockerConnection).header(eq("Content-Length"), anyInt()); verify(dockerConnection).entity(any(InputStream.class)); verify(dockerConnection).header(eq("X-Registry-Config"), any(byte[].class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); verify(dockerConnection).query(eq("rm"), eq(1)); verify(dockerConnection).query(eq("forcerm"), eq(1)); verify(dockerConnection).query(eq("memory"), eq(memory)); verify(dockerConnection).query(eq("memswap"), eq(memswap)); verify(dockerConnection).query(eq("pull"), eq(1)); verify(dockerConnection).query(eq("dockerfile"), eq(dockerfile)); verify(dockerConnection).query(eq("nocache"), eq(1)); verify(dockerConnection).query(eq("q"), eq(1)); verify(dockerConnection).query(eq("cpusetcpus"), eq(cpusetcpus)); verify(dockerConnection).query(eq("cpuperiod"), eq(cpuperiod)); verify(dockerConnection).query(eq("cpuquota"), eq(cpuquota)); verify(dockerConnection).query(eq("t"), eq(repository + ':' + tag)); verify(dockerConnection).query(eq("buildargs"), eq(URLEncoder.encode(GSON.toJson(buildargs), "UTF-8"))); assertEquals(returnedImageId, imageId); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileBuildingImageIfResponseCodeIsNotSuccess() throws IOException, InterruptedException { AuthConfigs authConfigs = DtoFactory.newDto(AuthConfigs.class); AuthConfig authConfig = DtoFactory.newDto(AuthConfig.class); Map<String, AuthConfig> auth = new HashMap<>(); auth.put("auth", authConfig); authConfigs.setConfigs(auth); BuildImageParams getExecInfoParams = BuildImageParams.create(dockerfile) .withAuthConfigs(authConfigs); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.buildImage(getExecInfoParams, progressMonitor); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = "Docker image build failed. Image id not found in build output.") public void shouldThrowIOExceptionWhenBuildImageButNoSuccessMessageInResponse() throws IOException, InterruptedException { AuthConfigs authConfigs = DtoFactory.newDto(AuthConfigs.class); AuthConfig authConfig = DtoFactory.newDto(AuthConfig.class); Map<String, AuthConfig> auth = new HashMap<>(); auth.put("auth", authConfig); authConfigs.setConfigs(auth); BuildImageParams getEventsParams = BuildImageParams.create(dockerfile) .withAuthConfigs(authConfigs); doReturn(new ByteArrayInputStream("c96d378b4911: Already exists".getBytes())).when(dockerResponse).getInputStream(); dockerConnector.buildImage(getEventsParams, progressMonitor); verify(dockerResponse).getInputStream(); } @Test public void shouldCallRemoveImageWithParametersObject() throws IOException { RemoveImageParams removeImageParams = RemoveImageParams.create(IMAGE); doNothing().when(dockerConnector).removeImage(removeImageParams); dockerConnector.removeImage(IMAGE); verify(dockerConnector).removeImage((RemoveImageParams)captor.capture()); assertEquals(captor.getValue(), removeImageParams); } @Test public void shouldBeAbleToRemoveImage() throws IOException { RemoveImageParams removeImageParams = RemoveImageParams.create(IMAGE); dockerConnector.removeImage(removeImageParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_DELETE); verify(dockerConnection).path("/images/" + removeImageParams.getImage()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileRemovingImageIfResponseCodeIsNotSuccess() throws IOException { RemoveImageParams removeImageParams = RemoveImageParams.create(IMAGE); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.removeImage(removeImageParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToTagImage() throws IOException { TagParams tagParams = TagParams.create(IMAGE, REPOSITORY); dockerConnector.tag(tagParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/images/" + tagParams.getImage() + "/tag"); verify(dockerConnection).query("repo", tagParams.getRepository()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileTaggingImageIfResponseCodeIsNotSuccess() throws IOException { TagParams tagParams = TagParams.create(IMAGE, REPOSITORY); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.tag(tagParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToPushImageToRepository() throws IOException, InterruptedException { PushParams pushParams = PushParams.create(REPOSITORY); when(dockerResponse.getInputStream()).thenReturn( new ByteArrayInputStream(("{\"status\":\"latest: digest: " + DIGEST + " size: 1234\"}").getBytes())); dockerConnector.push(pushParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/images/" + pushParams.getRepository() + "/push"); verify(dockerConnection).header(eq("X-Registry-Auth"), any(AuthConfig.class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test public void shouldBeAbleToPushImageToRegistryRepository() throws IOException, InterruptedException { PushParams pushParams = PushParams.create(REPOSITORY) .withRegistry(REGISTRY); when(dockerResponse.getInputStream()).thenReturn( new ByteArrayInputStream(("{\"status\":\"latest: digest: " + DIGEST + " size: 1234\"}").getBytes())); dockerConnector.push(pushParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/images/" + pushParams.getRegistry() + '/' + pushParams.getRepository() + "/push"); verify(dockerConnection).header(eq("X-Registry-Auth"), any(AuthConfig.class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhilePushingImageIfResponseCodeIsNotSuccess() throws IOException, InterruptedException { PushParams pushParams = PushParams.create(REPOSITORY); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.push(pushParams, progressMonitor); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Docker image pushing failed. Cause: Docker push response doesn't contain image digest") public void shouldThrowDockerExceptionWhenPushImageButDigestOutputMissing() throws IOException, InterruptedException { String dockerPushOutput = "{\"progress\":\"[=====> ] 25%\"}\n" + "{\"status\":\"Image already exists\"}\n" + "{\"progress\":\"[===============> ] 75%\"}\n"; when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(dockerPushOutput.getBytes())); PushParams pushParams = PushParams.create(REPOSITORY); dockerConnector.push(pushParams, progressMonitor); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Docker image pushing failed. Cause: .*") public void shouldThrowDockerExceptionWhenPushImageButOutputIsEmpty() throws IOException, InterruptedException { PushParams pushParams = PushParams.create(REPOSITORY); dockerConnector.push(pushParams, progressMonitor); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Docker image pushing failed. Cause: test error") public void shouldThrowDockerExceptionWhenPushFails() throws IOException, InterruptedException { String dockerPushOutput = "{\"progress\":\"[=====> ] 25%\"}\n" + "{\"progress\":\"[===============> ] 75%\"}\n" + "{\"error\":\"test error\"}\n"; when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(dockerPushOutput.getBytes())); PushParams pushParams = PushParams.create(REPOSITORY); dockerConnector.push(pushParams, progressMonitor); } @Test public void shouldBeAbleToParseDigestFromDockerPushOutput() throws IOException, InterruptedException { String dockerPushOutput = "{\"progress\":\"[=====> ] 25%\"}\n" + "{\"status\":\"Image already exists\"}\n" + "{\"progress\":\"[===============> ] 75%\"}\n" + "{\"status\":\"" + TAG + ": digest: " + DIGEST + " size: 12345\"}"; when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(dockerPushOutput.getBytes())); assertEquals(DIGEST, dockerConnector.push(PushParams.create(REPOSITORY) .withRegistry(REGISTRY) .withTag(TAG), progressMonitor)); } @Test public void shouldBeAbleToCommitImage() throws IOException, JsonParseException { CommitParams commitParams = CommitParams.create(CONTAINER).withRepository(REPOSITORY); ContainerCommitted containerCommitted = mock(ContainerCommitted.class); when(dockerResponse.getStatus()).thenReturn(RESPONSE_CREATED_CODE); when(containerCommitted.getId()).thenReturn(IMAGE); doReturn(containerCommitted).when(dockerConnector).parseResponseStreamAndClose(inputStream, ContainerCommitted.class); String returnedImage = dockerConnector.commit(commitParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/commit"); verify(dockerConnection).query("container", commitParams.getContainer()); verify(dockerConnection).query("repo", commitParams.getRepository()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedImage, IMAGE); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileCommittingImageIfResponseCodeIsNotSuccess() throws IOException { CommitParams commitParams = CommitParams.create(CONTAINER).withRepository(REPOSITORY); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.commit(commitParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToPullImageFromRepository() throws IOException, InterruptedException { PullParams pullParams = PullParams.create(IMAGE); when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(STREAM_DATA_BYTES)); dockerConnector.pull(pullParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/images/create"); verify(dockerConnection).query("fromImage", pullParams.getImage()); verify(dockerConnection).header(eq("X-Registry-Auth"), any(AuthConfig.class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test public void shouldBeAbleToPullImageCreateRegistryRepository() throws IOException, InterruptedException { PullParams pullParams = PullParams.create(IMAGE) .withRegistry(REGISTRY); when(dockerResponse.getInputStream()).thenReturn(new ByteArrayInputStream(STREAM_DATA_BYTES)); dockerConnector.pull(pullParams, progressMonitor); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/images/create"); verify(dockerConnection).query("fromImage", pullParams.getRegistry() + '/' + pullParams.getImage()); verify(dockerConnection).header(eq("X-Registry-Auth"), any(AuthConfig.class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhilePullingImageIfResponseCodeIsNotSuccess() throws IOException, InterruptedException { PullParams pullParams = PullParams.create(IMAGE); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.pull(pullParams, progressMonitor); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToCreateContainer() throws IOException, JsonParseException { CreateContainerParams createContainerParams = CreateContainerParams.create(new ContainerConfig()); ContainerCreated containerCreated = mock(ContainerCreated.class); when(dockerResponse.getStatus()).thenReturn(RESPONSE_CREATED_CODE); doReturn(containerCreated).when(dockerConnector).parseResponseStreamAndClose(inputStream, ContainerCreated.class); ContainerCreated returnedContainerCreated = dockerConnector.createContainer(createContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/create"); verify(dockerConnection).header("Content-Type", MediaType.APPLICATION_JSON); verify(dockerConnection).header(eq("Content-Length"), anyInt()); verify(dockerConnection).entity(any(byte[].class)); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); assertEquals(returnedContainerCreated, containerCreated); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileCreatingContainerIfResponseCodeIsNotSuccess() throws IOException { CreateContainerParams createContainerParams = CreateContainerParams.create(new ContainerConfig()); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.createContainer(createContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldBeAbleToStartContainer() throws IOException { StartContainerParams startContainerParams = StartContainerParams.create(CONTAINER); dockerConnector.startContainer(startContainerParams); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/containers/" + startContainerParams.getContainer() + "/start"); verify(dockerConnection).request(); verify(dockerResponse, atLeastOnce()).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = EXCEPTION_ERROR_MESSAGE) public void shouldThrowDockerExceptionWhileStartingContainerIfResponseCodeIsNotSuccess() throws IOException { StartContainerParams startContainerParams = StartContainerParams.create(CONTAINER); when(dockerResponse.getStatus()).thenReturn(RESPONSE_ERROR_CODE); dockerConnector.startContainer(startContainerParams); verify(dockerResponse).getStatus(); } @Test public void shouldUseFirstLetterLowercaseWhenParseResponseStreamAndClose() throws IOException, JsonParseException { String response = "{\n" + " \"BuildTime\": \"2016-03-10T15:54:52.312835708+00:00\",\n" + " \"KernelVersion\": \"3.16.0-53-generic\",\n" + " \"Arch\": \"amd64\",\n" + " \"Os\": \"linux\",\n" + " \"GoVersion\": \"go1.5.3\",\n" + " \"GitCommit\": \"20f81dd\",\n" + " \"ApiVersion\": \"1.22\",\n" + " \"Version\": \"1.10.3\"\n" + "}\n"; Version version = new Version(); version.setVersion("1.10.3"); version.setApiVersion("1.22"); version.setGoVersion("go1.5.3"); version.setGitCommit("20f81dd"); version.setOs("linux"); version.setArch("amd64"); Version parsedVersion = dockerConnector.parseResponseStreamAndClose( new ByteArrayInputStream(response.getBytes()), Version.class); assertEquals(parsedVersion, version); } @Test public void shouldBeAbleToParseResponseStreamAsListOfImagesAndClose() throws IOException, JsonParseException { String response = "[\n" + " {\n" + " \"RepoTags\": [\n" + " \"ubuntu:12.04\",\n" + " \"ubuntu:precise\",\n" + " \"ubuntu:latest\"\n" + " ],\n" + " \"Id\": \"8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c\",\n" + " \"Created\": 1365714795,\n" + " \"Size\": 131506275,\n" + " \"VirtualSize\": 131506275,\n" + " \"Labels\": {}\n" + " },\n" + " {\n" + " \"RepoTags\": [\n" + " \"ubuntu:12.10\",\n" + " \"ubuntu:quantal\"\n" + " ],\n" + " \"ParentId\": \"27cf784147099545\",\n" + " \"Id\": \"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc\",\n" + " \"Created\": 1364102658,\n" + " \"Size\": 24653,\n" + " \"VirtualSize\": 180116135,\n" + " \"Labels\": {\n" + " \"com.example.version\": \"v1\"\n" + " }\n" + " }\n" + "]\n"; List<Image> images = dockerConnector.parseResponseStreamAndClose(new ByteArrayInputStream(response.getBytes()), new TypeToken<List<Image>>() {}); assertEquals(images.size(), 2); Image actualImage1 = images.get(0); Image actualImage2 = images.get(1); assertEquals(actualImage1.getRepoTags(), new String[] {"ubuntu:12.04", "ubuntu:precise", "ubuntu:latest"}); assertEquals(actualImage1.getId(), "8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c"); assertEquals(actualImage1.getCreated(), 1365714795); assertEquals(actualImage1.getSize(), 131506275); assertEquals(actualImage1.getVirtualSize(), 131506275); assertEquals(actualImage1.getLabels(), emptyMap()); assertEquals(actualImage2.getRepoTags(), new String[] {"ubuntu:12.10", "ubuntu:quantal"}); assertEquals(actualImage2.getId(), "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc"); assertEquals(actualImage2.getParentId(), "27cf784147099545"); assertEquals(actualImage2.getCreated(), 1364102658); assertEquals(actualImage2.getSize(), 24653); assertEquals(actualImage2.getVirtualSize(), 180116135); assertEquals(actualImage2.getLabels(), singletonMap("com.example.version", "v1")); } @Test public void shouldBeAbleToParseResponseStreamAsListOfContainersAndClose() throws IOException, JsonParseException { String response = " [\n" + " {\n" + " \"Id\": \"8dfafdbc3a40\",\n" + " \"Image\": \"ubuntu:latest\",\n" + " \"Command\": \"echo 1\",\n" + " \"Created\": 1367854155,\n" + " \"Status\": \"Exit 0\",\n" + " \"SizeRw\": 12288,\n" + " \"SizeRootFs\": 0\n" + " }" + "]\n"; List<ContainerListEntry> containers = dockerConnector.parseResponseStreamAndClose(new ByteArrayInputStream(response.getBytes()), new TypeToken<List<ContainerListEntry>>() {}); assertEquals(containers.size(), 1); ContainerListEntry actualContainer1 = containers.get(0); assertEquals(actualContainer1.getId(), "8dfafdbc3a40"); assertEquals(actualContainer1.getImage(), "ubuntu:latest"); assertEquals(actualContainer1.getCommand(), "echo 1"); assertEquals(actualContainer1.getCreated(), 1367854155); assertEquals(actualContainer1.getStatus(), "Exit 0"); assertEquals(actualContainer1.getSizeRw(), 12288); assertEquals(actualContainer1.getSizeRootFs(), 0); } @Test public void shouldBeAbleToParseResponseStreamAsEmptyListOfContainersAndClose() throws IOException, JsonParseException { String response = "[]"; List<ContainerListEntry> containers = dockerConnector.parseResponseStreamAndClose(new ByteArrayInputStream(response.getBytes()), new TypeToken<List<ContainerListEntry>>() {}); assertEquals(containers.size(), 0); } @Test public void shouldBeAbleToGetNetworks() throws Exception { // given doReturn(inputStream).when(dockerResponse).getInputStream(); doReturn(singletonList(createNetwork())).when(dockerConnector).getNetworks(any(GetNetworksParams.class)); // when dockerConnector.getNetworks(); // then verify(dockerConnector).getNetworks(eq(GetNetworksParams.create())); } @Test public void shouldBeAbleToGetNetworksWithParams() throws Exception { // given Network network = createNetwork(); List<Network> originNetworks = singletonList(network); ByteArrayInputStream inputStream = new ByteArrayInputStream(GSON.toJson(originNetworks).getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); GetNetworksParams getNetworksParams = GetNetworksParams.create().withFilters(new Filters().withFilter("key", "value1", "value2")); // when List<Network> actual = dockerConnector.getNetworks(getNetworksParams); // then assertEquals(actual, originNetworks); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/networks"); verify(dockerConnection).query(eq("filters"), anyObject()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Error response from docker API, status: 404, message: exc_message") public void shouldThrowExceptionOnGetNetworksIfResponseCodeIsNot20x() throws Exception { // given doReturn(404).when(dockerResponse).getStatus(); ByteArrayInputStream inputStream = new ByteArrayInputStream("exc_message".getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); // when dockerConnector.getNetworks(); } @Test public void shouldBeAbleToInspectNetwork() throws Exception { // given Network network = createNetwork(); doReturn(network).when(dockerConnector).inspectNetwork(any(InspectNetworkParams.class)); // when dockerConnector.inspectNetwork(network.getId()); // then verify(dockerConnector).inspectNetwork(InspectNetworkParams.create(network.getId())); } @Test public void shouldBeAbleToInspectNetworkWithParams() throws Exception { // given Network originNetwork = createNetwork(); ByteArrayInputStream inputStream = new ByteArrayInputStream(GSON.toJson(originNetwork).getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); // when Network actual = dockerConnector.inspectNetwork(InspectNetworkParams.create(originNetwork.getId())); // then assertEquals(actual, originNetwork); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_GET); verify(dockerConnection).path("/networks/" + originNetwork.getId()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Error response from docker API, status: 404, message: exc_message") public void shouldThrowExceptionOnInspectNetworkIfResponseCodeIsNot20x() throws Exception { // given doReturn(404).when(dockerResponse).getStatus(); ByteArrayInputStream inputStream = new ByteArrayInputStream("exc_message".getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); // when dockerConnector.inspectNetwork("net_id"); } @Test public void shouldBeAbleToCreateNetwork() throws Exception { // given CreateNetworkParams createNetworkParams = CreateNetworkParams.create(createNewNetwork()); NetworkCreated originNetworkCreated = new NetworkCreated().withId("some_id").withWarning("some_warning"); ByteArrayInputStream inputStream = new ByteArrayInputStream(GSON.toJson(originNetworkCreated).getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); // when NetworkCreated networkCreated = dockerConnector.createNetwork(createNetworkParams); // then assertEquals(networkCreated, originNetworkCreated); verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/networks/create"); verify(dockerConnection).header("Content-Type", MediaType.APPLICATION_JSON); verify(dockerConnection).header(eq("Content-Length"), anyInt()); ArgumentCaptor<byte[]> argumentCaptor = ArgumentCaptor.forClass(byte[].class); verify(dockerConnection).entity(argumentCaptor.capture()); assertEquals(argumentCaptor.getValue(), GSON.toJson(createNetworkParams.getNetwork()).getBytes()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); verify(dockerResponse).getInputStream(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Error response from docker API, status: 404, message: exc_message") public void shouldThrowExceptionOnCreateNetworkIfResponseCodeIsNot20x() throws Exception { // given doReturn(404).when(dockerResponse).getStatus(); ByteArrayInputStream inputStream = new ByteArrayInputStream("exc_message".getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); CreateNetworkParams createNetworkParams = CreateNetworkParams.create(createNewNetwork()); // when dockerConnector.createNetwork(createNetworkParams); } @Test public void shouldBeAbleToConnectContainerToNetwork() throws Exception { // given String netId = "net_id"; String containerId = "container_id"; doNothing().when(dockerConnector).connectContainerToNetwork(any(ConnectContainerToNetworkParams.class)); // when dockerConnector.connectContainerToNetwork(netId, containerId); // then verify(dockerConnector).connectContainerToNetwork( ConnectContainerToNetworkParams.create(netId, new ConnectContainer().withContainer(containerId))); } @Test public void shouldBeAbleToConnectContainerToNetworkWithParams() throws Exception { // given String netId = "net_id"; ConnectContainerToNetworkParams connectToNetworkParams = ConnectContainerToNetworkParams.create(netId, createConnectContainer()); // when dockerConnector.connectContainerToNetwork(connectToNetworkParams); // then verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/networks/" + netId + "/connect"); verify(dockerConnection).header("Content-Type", MediaType.APPLICATION_JSON); verify(dockerConnection).header(eq("Content-Length"), anyInt()); ArgumentCaptor<byte[]> argumentCaptor = ArgumentCaptor.forClass(byte[].class); verify(dockerConnection).entity(argumentCaptor.capture()); assertEquals(argumentCaptor.getValue(), GSON.toJson(connectToNetworkParams.getConnectContainer()).getBytes()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Error response from docker API, status: 404, message: exc_message") public void shouldThrowExceptionOnConnectToNetworkIfResponseCodeIsNot20x() throws Exception { // given doReturn(404).when(dockerResponse).getStatus(); ByteArrayInputStream inputStream = new ByteArrayInputStream("exc_message".getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); ConnectContainerToNetworkParams connectToNetworkParams = ConnectContainerToNetworkParams.create("net_id", createConnectContainer()); // when dockerConnector.connectContainerToNetwork(connectToNetworkParams); } @Test public void shouldBeAbleToDisconnectContainerFromNetwork() throws Exception { // given String netId = "net_id"; String containerId = "container_id"; doNothing().when(dockerConnector).disconnectContainerFromNetwork(any(DisconnectContainerFromNetworkParams.class)); // when dockerConnector.disconnectContainerFromNetwork(netId, containerId); // then verify(dockerConnector).disconnectContainerFromNetwork( DisconnectContainerFromNetworkParams.create(netId, new DisconnectContainer().withContainer(containerId))); } @Test public void shouldBeAbleToDisconnectContainerFromNetworkWithParams() throws Exception { // given String netId = "net_id"; DisconnectContainerFromNetworkParams disconnectFromNetworkParams = DisconnectContainerFromNetworkParams.create(netId, new DisconnectContainer().withContainer("container_id") .withForce(true)); // when dockerConnector.disconnectContainerFromNetwork(disconnectFromNetworkParams); // then verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_POST); verify(dockerConnection).path("/networks/" + netId + "/disconnect"); verify(dockerConnection).header("Content-Type", MediaType.APPLICATION_JSON); verify(dockerConnection).header(eq("Content-Length"), anyInt()); ArgumentCaptor<byte[]> argumentCaptor = ArgumentCaptor.forClass(byte[].class); verify(dockerConnection).entity(argumentCaptor.capture()); assertEquals(argumentCaptor.getValue(), GSON.toJson(disconnectFromNetworkParams.getDisconnectContainer()).getBytes()); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = DockerException.class, expectedExceptionsMessageRegExp = "Error response from docker API, status: 404, message: exc_message") public void shouldThrowExceptionOnDisconnectFromNetworkIfResponseCodeIsNot20x() throws Exception { // given doReturn(404).when(dockerResponse).getStatus(); ByteArrayInputStream inputStream = new ByteArrayInputStream("exc_message".getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); DisconnectContainerFromNetworkParams disconnectFromNetworkParams = DisconnectContainerFromNetworkParams.create("net_id", new DisconnectContainer().withContainer("container_id") .withForce(true)); // when dockerConnector.disconnectContainerFromNetwork(disconnectFromNetworkParams); } @Test public void shouldBeAbleToRemoveNetwork() throws Exception { // given String netId = "net_id"; doNothing().when(dockerConnector).removeNetwork(any(RemoveNetworkParams.class)); // when dockerConnector.removeNetwork(netId); // then verify(dockerConnector).removeNetwork(RemoveNetworkParams.create(netId)); } @Test public void shouldBeAbleToRemoveNetworkWithParams() throws Exception { // given String netId = "net_id"; RemoveNetworkParams removeNetworkParams = RemoveNetworkParams.create(netId); // when dockerConnector.removeNetwork(removeNetworkParams); // then verify(dockerConnectionFactory).openConnection(any(URI.class)); verify(dockerConnection).method(REQUEST_METHOD_DELETE); verify(dockerConnection).path("/networks/" + netId); verify(dockerConnection).request(); verify(dockerResponse).getStatus(); } @Test(expectedExceptions = NetworkNotFoundException.class, expectedExceptionsMessageRegExp = "exc_message") public void shouldThrowExceptionOnRemoveNetworkIfResponseCodeIsNot20x() throws Exception { // given doReturn(404).when(dockerResponse).getStatus(); ByteArrayInputStream inputStream = new ByteArrayInputStream("exc_message".getBytes()); doReturn(inputStream).when(dockerResponse).getInputStream(); RemoveNetworkParams removeNetworkParams = RemoveNetworkParams.create("net_id"); // when dockerConnector.removeNetwork(removeNetworkParams); } private Network createNetwork() { return new Network().withName("some_name") .withLabels(singletonMap("label1", "val1")) .withIPAM(new Ipam().withConfig(singletonList(new IpamConfig().withGateway("some_gateway") .withIPRange("some_ip_range") .withSubnet("some_subnet"))) .withDriver("some_driver2") .withOptions(singletonMap("opt1", "val1"))) .withInternal(true) .withScope("some_scope") .withId("some_id") .withContainers(singletonMap("some_container_key", new ContainerInNetwork().withEndpointID("some_endpoint_id") .withIPv4Address("some_ipv4_address") .withIPv6Address("some_ipv6_address") .withMacAddress("some_mac_address") .withName("some_container_name"))) .withDriver("some_driver") .withEnableIPv6(true) .withOptions(singletonMap("opt2", "val1")); } private NewNetwork createNewNetwork() { return new NewNetwork().withCheckDuplicate(true) .withDriver("some_driver") .withName("some_name") .withEnableIPv6(true) .withInternal(true) .withIPAM(new Ipam().withConfig(singletonList(new IpamConfig().withGateway("some_gateway") .withIPRange("some_ip_range") .withSubnet("some_subnet"))) .withDriver("some_driver2") .withOptions(singletonMap("opt1", "val1"))) .withLabels(singletonMap("label1", "val1")) .withOptions(singletonMap("opt1", "val1")); } private ConnectContainer createConnectContainer() { return new ConnectContainer().withContainer("container_id") .withEndpointConfig( new EndpointConfig().withLinks(new String[] {"link_1"}) .withAliases(new String[] {"alias_1"}) .withIPAMConfig(new NewIpamConfig().withIPv4Address("ipv4_address") .withIPv6Address("ipv6_address"))); } }