diff options
author | Xavier Coulon | 2015-11-24 08:21:42 +0000 |
---|---|---|
committer | Xavier Coulon | 2015-11-25 15:46:04 +0000 |
commit | 22ec078ee9b1257ccda419b0187d011838a63ac6 (patch) | |
tree | 987948c9ef694f639618156011c6469194ec7a84 | |
parent | db8dd4400d77b4a5583656f0dd13598d95b87f14 (diff) | |
download | org.eclipse.linuxtools-22ec078ee9b1257ccda419b0187d011838a63ac6.tar.gz org.eclipse.linuxtools-22ec078ee9b1257ccda419b0187d011838a63ac6.tar.xz org.eclipse.linuxtools-22ec078ee9b1257ccda419b0187d011838a63ac6.zip |
Bug 481219 - Validate container name in "Image Run" wizard
Raise an error message when a container with the same name exists.
Also added checks to avoid NPE when initializing ContainerInfo and
ImageInfo
Refactored some SWT utility classes used to setup the mock connection
and moved some reusable blocks in JUnit rules.
Change-Id: Ie8363fb4af6e8e5d210734c7f9028b27ac70548a
Signed-off-by: Xavier Coulon <xcoulon@redhat.com>
Reviewed-on: https://git.eclipse.org/r/61113
Tested-by: Hudson CI
19 files changed, 543 insertions, 222 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java index 57fc86cee1..a67f905e5e 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java @@ -971,7 +971,8 @@ public class DockerConnection implements IDockerConnection, Closeable { final ContainerCreation creation = client .createContainer(builder.build(), containerName); - final String id = creation.id(); + + final String id = creation != null ? creation.id() : null; // force a refresh of the current containers to include the new one listContainers(); return id; diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnectionInfo.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnectionInfo.java index a4b8e548ae..73bb1e3ebf 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnectionInfo.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnectionInfo.java @@ -53,31 +53,32 @@ public class DockerConnectionInfo implements IDockerConnectionInfo { private final String dockerRootDir; public DockerConnectionInfo(final Info info, final Version version) { - this.containers = info.containers(); - this.debug = info.debug(); - this.executionDriver = info.executionDriver(); - this.fileDescriptors = info.fileDescriptors(); - this.goroutines = info.goroutines(); - this.images = info.images(); - this.initPath = info.initPath(); - this.kernelVersion = info.kernelVersion(); - this.memoryLimit = info.memoryLimit(); - this.storageDriver = info.storageDriver(); - this.swapLimit = info.swapLimit(); - this.apiVersion = version.apiVersion(); - this.gitCommit = version.gitCommit(); - this.os = version.os(); - this.version = version.version(); - this.driverStatus = info.driverStatus(); - this.cpuNumber = info.cpus(); - this.totalMemory = info.memTotal(); - this.name = info.name(); - this.id = info.id(); - this.initSha1 = info.initSha1(); - this.ipv4Forwarding = info.ipv4Forwarding(); - this.indexServerAddress = info.indexServerAddress(); - this.labels = info.labels(); - this.dockerRootDir = info.dockerRootDir(); + this.containers = info != null ? info.containers() : -1; + this.debug = info != null ? info.debug() : false; + this.executionDriver = info != null ? info.executionDriver() : null; + this.fileDescriptors = info != null ? info.fileDescriptors() : -1; + this.goroutines = info != null ? info.goroutines() : -1; + this.images = info != null ? info.images() : -1; + this.initPath = info != null ? info.initPath() : null; + this.kernelVersion = info != null ? info.kernelVersion() : null; + this.memoryLimit = info != null ? info.memoryLimit() : false; + this.storageDriver = info != null ? info.storageDriver() : null; + this.swapLimit = info != null ? info.swapLimit() : false; + this.apiVersion = version != null ? version.apiVersion() : null; + this.gitCommit = version != null ? version.gitCommit() : null; + this.os = version != null ? version.os() : ""; + this.version = version != null ? version.version() : null; + this.driverStatus = info != null ? info.driverStatus() : null; + this.cpuNumber = info != null ? info.cpus() : -1; + this.totalMemory = info != null ? info.memTotal() : -1; + this.name = info != null ? info.name() : null; + this.id = info != null ? info.id() : null; + this.initSha1 = info != null ? info.initSha1() : null; + this.ipv4Forwarding = info != null ? info.ipv4Forwarding() : false; + this.indexServerAddress = info != null ? info.indexServerAddress() + : null; + this.labels = info != null ? info.labels() : null; + this.dockerRootDir = info != null ? info.dockerRootDir() : null; } diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerInfo.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerInfo.java index 84d7db1004..f40f68cbe9 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerInfo.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerInfo.java @@ -45,25 +45,29 @@ public class DockerContainerInfo implements IDockerContainerInfo { private Map<String, Boolean> volumesRW; public DockerContainerInfo (final ContainerInfo info) { - this.id = info.id(); - this.created = info.created(); - this.path = info.path(); - this.args = info.args(); - this.config = new DockerContainerConfig(info.config()); - this.hostConfig = new DockerHostConfig(info.hostConfig()); - this.state = new DockerContainerState(info.state()); - this.image = info.image(); - this.networkSettings = new DockerNetworkSettings(info.networkSettings()); - this.resolvConfPath = info.resolvConfPath(); - this.hostnamePath = info.hostnamePath(); - this.hostsPath = info.hostsPath(); - this.name = info.name(); - this.driver = info.driver(); - this.execDriver = info.execDriver(); - this.processLabel = info.processLabel(); - this.mountLabel = info.mountLabel(); - this.volumes = info.volumes(); - this.volumesRW = info.volumesRW(); + this.id = info != null ? info.id() : null; + this.created = info != null ? info.created() : null; + this.path = info != null ? info.path() : null; + this.args = info != null ? info.args() : null; + this.config = info != null ? new DockerContainerConfig(info.config()) + : null; + this.hostConfig = info != null ? new DockerHostConfig(info.hostConfig()) + : null; + this.state = info != null ? new DockerContainerState(info.state()) + : null; + this.image = info != null ? info.image() : null; + this.networkSettings = info != null + ? new DockerNetworkSettings(info.networkSettings()) : null; + this.resolvConfPath = info != null ? info.resolvConfPath() : null; + this.hostnamePath = info != null ? info.hostnamePath() : null; + this.hostsPath = info != null ? info.hostsPath() : null; + this.name = info != null ? info.name() : null; + this.driver = info != null ? info.driver() : null; + this.execDriver = info != null ? info.execDriver() : null; + this.processLabel = info != null ? info.processLabel() : null; + this.mountLabel = info != null ? info.mountLabel() : null; + this.volumes = info != null ? info.volumes() : null; + this.volumesRW = info != null ? info.volumesRW() : null; } @Override diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageInfo.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageInfo.java index 0514885f65..e9aff6f837 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageInfo.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageInfo.java @@ -32,19 +32,21 @@ public class DockerImageInfo implements IDockerImageInfo { private String os; private Long size; - public DockerImageInfo(ImageInfo info) { - this.id = info.id(); - this.parent = info.parent(); - this.comment = info.comment(); - this.created = info.created(); - this.container = info.container(); - this.containerConfig = new DockerContainerConfig(info.containerConfig()); - this.dockerVersion = info.dockerVersion(); - this.author = info.author(); - this.config = new DockerContainerConfig(info.config()); - this.architecture = info.architecture(); - this.os = info.os(); - this.size = info.size(); + public DockerImageInfo(final ImageInfo info) { + this.id = info != null ? info.id() : null; + this.parent = info != null ? info.parent() : null; + this.comment = info != null ? info.comment() : null; + this.created = info != null ? info.created() : null; + this.container = info != null ? info.container() : null; + this.containerConfig = info != null + ? new DockerContainerConfig(info.containerConfig()) : null; + this.dockerVersion = info != null ? info.dockerVersion() : null; + this.author = info != null ? info.author() : null; + this.config = info != null ? new DockerContainerConfig(info.config()) + : null; + this.architecture = info != null ? info.architecture() : null; + this.os = info != null ? info.os() : null; + this.size = info != null ? info.size() : null; } @Override diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java index e9c3893d57..58945c42e7 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java @@ -39,9 +39,9 @@ public class DockerConnectionManagerTest { } @Test - public void shouldRegisterConnectionOnRefreshContainersManager() throws InterruptedException { + public void shouldRegisterConnectionOnRefreshContainersManager() { // given - final DockerClient client = MockDockerClientFactory.noImages().noContainers(); + final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); dockerConnectionManager .setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(dockerConnection)); @@ -55,7 +55,7 @@ public class DockerConnectionManagerTest { @Test public void shouldUnregisterConnectionOnRefreshContainersManager() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages().noContainers(); + final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); dockerConnectionManager .setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(dockerConnection)); @@ -66,6 +66,5 @@ public class DockerConnectionManagerTest { SWTUtils.asyncExec(() -> dockerConnectionManager.removeConnection(dockerConnection)); // then Assertions.assertThat(dockerContainersRefreshManager.getConnections()).isEmpty(); - } } diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtilsSWTBotTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtilsSWTBotTest.java index feb9fd7d39..6af527e64c 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtilsSWTBotTest.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtilsSWTBotTest.java @@ -11,31 +11,26 @@ package org.eclipse.linuxtools.internal.docker.ui.commands; -import java.util.stream.Stream; - import org.assertj.core.api.Assertions; -import org.eclipse.linuxtools.docker.core.DockerConnectionManager; -import org.eclipse.linuxtools.docker.core.IDockerConnection; -import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionStorageManager; import org.eclipse.linuxtools.internal.docker.core.DockerConnection; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerClientFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionFactory; -import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionStorageManagerFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerContainerFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerContainerInfoFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerImageFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.ClearConnectionManagerRule; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.CloseWelcomePageRule; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.DockerConnectionManagerUtils; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.SWTUtils; import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView; import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; import org.eclipse.ui.PlatformUI; -import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; import com.spotify.docker.client.DockerClient; @@ -52,6 +47,9 @@ public class CommandUtilsSWTBotTest { @ClassRule public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule(); + @Rule + public ClearConnectionManagerRule clearConnectionManager = new ClearConnectionManagerRule(); + @Before public void lookupDockerExplorerView() throws InterruptedException { SWTUtils.asyncExec(() -> { @@ -71,38 +69,14 @@ public class CommandUtilsSWTBotTest { .forEach(v -> v.close()); } - @After - public void clearConnectionManager() throws InterruptedException { - SWTUtils.syncExec(() -> { - Stream.of(DockerConnectionManager.getInstance().getConnections()) - .forEach(c -> DockerConnectionManager.getInstance().removeConnection(c)); - dockerExplorerView.getCommonViewer().refresh(true); - }); - } - - @AfterClass - public static void restoreDefaultConfig() { - DockerConnectionManager.getInstance().setConnectionStorageManager(new DefaultDockerConnectionStorageManager()); - } - - private void configureConnectionManager(final IDockerConnection... connections) throws InterruptedException { - DockerConnectionManager.getInstance() - .setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(connections)); - SWTUtils.asyncExec(() -> { - DockerConnectionManager.getInstance().reloadConnections(); - dockerExplorerView.getCommonViewer().refresh(); - }); - - } - @Test public void shouldRetrieveConnectionFromSelectedContainersCategory() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build()).build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); - SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); + SWTUtils.syncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when selecting the container SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers").select(); // then current connection should be found @@ -112,11 +86,11 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainer() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build()).build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); - SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); + SWTUtils.syncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when selecting the container SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers", "foo_bar").select(); // then current connection should be found @@ -126,12 +100,12 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainerLinksCategory() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.link("/foo:/bar/foo").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); @@ -146,12 +120,12 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainerLink() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.link("/foo:/bar/foo").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); @@ -167,12 +141,12 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainerVolumesCategory() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.volume("/path/to/host:/path/to/container:Z,ro").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); @@ -188,12 +162,12 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainerVolume() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.volume("/path/to/host:/path/to/container:Z,ro").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); @@ -209,12 +183,12 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainerPortsCategory() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.port("8080/tcp", "0.0.0.0", "8080").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); @@ -229,12 +203,12 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedContainerPort() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.port("8080/tcp", "0.0.0.0", "8080").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers"); @@ -250,10 +224,10 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedImagesCategory() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.images(MockDockerImageFactory.name("foo").build()) + final DockerClient client = MockDockerClientFactory.image(MockDockerImageFactory.name("foo").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when selecting the images category SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Images").select(); @@ -264,10 +238,10 @@ public class CommandUtilsSWTBotTest { @Test public void shouldRetrieveConnectionFromSelectedImage() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.images(MockDockerImageFactory.name("foo").build()) + final DockerClient client = MockDockerClientFactory.image(MockDockerImageFactory.name("foo").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when selecting the image SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Images", "foo").select(); diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockDockerClientFactory.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockDockerClientFactory.java index 51f9bddfba..7ceaca7ea8 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockDockerClientFactory.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockDockerClientFactory.java @@ -12,10 +12,11 @@ package org.eclipse.linuxtools.internal.docker.ui.testutils; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.eclipse.linuxtools.docker.core.IDockerConnection; +import org.eclipse.linuxtools.docker.core.IDockerContainer; +import org.eclipse.linuxtools.docker.core.IDockerImage; import org.mockito.Matchers; import org.mockito.Mockito; @@ -24,50 +25,112 @@ import com.spotify.docker.client.DockerException; import com.spotify.docker.client.messages.Container; import com.spotify.docker.client.messages.ContainerInfo; import com.spotify.docker.client.messages.Image; +import com.spotify.docker.client.messages.ImageInfo; +import com.spotify.docker.client.messages.Info; /** * Factory for mocked {@link IDockerConnection} */ public class MockDockerClientFactory { - public static Builder images(final Image... images) { + /** + * @return an {@link DockerClient} with no {@link IDockerImage} and no {@link IDockerContainer}. + */ + public static DockerClient build() { + return image(null).build(); + } + + /** + * @param image the first {@link Image} to use to build the {@link DockerClient} + * @return a {@link Builder} to build a {@link DockerClient} + */ + public static Builder image(final Image image) { final Builder builder = new Builder(); - builder.images(Arrays.asList(images)); + builder.image(image); return builder; } - public static Builder noImages() { - return images(); + /** + * @param image the first {@link Image} to use to build the {@link DockerClient} + * @param imageInfo the associated {@link ImageInfo} + * @return a {@link Builder} to build a {@link DockerClient} + */ + public static Builder image(final Image image, final ImageInfo imageInfo) { + final Builder builder = new Builder(); + builder.image(image, imageInfo); + return builder; + } + + /** + * @param image the first {@link Container} to use to build the {@link DockerClient} + * @return a {@link Builder} to build a {@link DockerClient} + */ + public static Builder container(final Container container) { + final Builder builder = new Builder(); + builder.container(container); + return builder; } + /** + * @param container the first {@link Container} to use to build the {@link DockerClient} + * @param containerInfo the associated {@link ContainerInfo} + * @return a {@link Builder} to build a {@link DockerClient} + */ + public static Builder container(final Container container, final ContainerInfo containerInfo) { + final Builder builder = new Builder(); + builder.container(container, containerInfo); + return builder; + } public static class Builder { private final DockerClient dockerClient; + private final List<Image> images = new ArrayList<>(); + private final List<Container> containers = new ArrayList<>(); private Builder() { this.dockerClient = Mockito.mock(DockerClient.class); + try { + final Info info = Mockito.mock(Info.class); + Mockito.when(info.memTotal()).thenReturn(1024L); + Mockito.when(dockerClient.info()).thenReturn(info); + } catch (DockerException | InterruptedException e) { + // ignore while setting-up the mock instance + } } - public Builder images(final List<Image> images) { + public Builder image(final Image image) { + if(image != null) { + this.images.add(image); + } + return this; + } + + public Builder image(final Image image, final ImageInfo imageInfo) { + if(image != null ) { + this.images.add(image); + } try { - Mockito.when(dockerClient.listImages(Matchers.any())).thenReturn(images); + Mockito.when(this.dockerClient.inspectImage(image.id())).thenReturn(imageInfo); } catch (DockerException | InterruptedException e) { // rest assured, nothing will happen while mocking the DockerClient } return this; } - public Builder container(final Container container) { - this.containers.add(container); + if(container != null) { + this.containers.add(container); + } return this; } public Builder container(final Container container, final ContainerInfo containerInfo) { - this.containers.add(container); + if(container != null) { + this.containers.add(container); + } try { Mockito.when(this.dockerClient.inspectContainer(container.id())).thenReturn(containerInfo); } catch (DockerException | InterruptedException e) { @@ -78,17 +141,13 @@ public class MockDockerClientFactory { public DockerClient build() { try { + Mockito.when(this.dockerClient.listImages(Matchers.any())).thenReturn(this.images); Mockito.when(this.dockerClient.listContainers(Matchers.any())).thenReturn(this.containers); } catch (DockerException | InterruptedException e) { // nothing may happen when mocking the method call } return this.dockerClient; } - - public DockerClient noContainers() { - return this.dockerClient; - } - } } diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/ClearConnectionManagerRule.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/ClearConnectionManagerRule.java new file mode 100644 index 0000000000..b448362689 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/ClearConnectionManagerRule.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * 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: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.ui.testutils.swt; + +import java.util.stream.Stream; + +import org.eclipse.linuxtools.docker.core.DockerConnectionManager; +import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionSettingsFinder; +import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.junit.rules.ExternalResource; + +/** + * Clears the connection manager after each test. + */ +public class ClearConnectionManagerRule extends ExternalResource { + + @Override + protected void after() { + final SWTWorkbenchBot bot = new SWTWorkbenchBot(); + final SWTBotView dockerExplorerViewBot = bot.viewById("org.eclipse.linuxtools.docker.ui.dockerExplorerView"); + final DockerExplorerView dockerExplorerView = (DockerExplorerView) (dockerExplorerViewBot.getViewReference() + .getView(true)); + SWTUtils.syncExec(() -> { + Stream.of(DockerConnectionManager.getInstance().getConnections()) + .forEach(c -> DockerConnectionManager.getInstance().removeConnection(c)); + dockerExplorerView.getCommonViewer().refresh(true); + dockerExplorerView.showConnectionsOrExplanations(); + }); + DockerConnectionManager.getInstance().setConnectionSettingsFinder(new DefaultDockerConnectionSettingsFinder()); + } +} diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/CloseWizardRule.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/CloseWizardRule.java new file mode 100644 index 0000000000..b34acc2ae8 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/CloseWizardRule.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * 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: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.ui.testutils.swt; + +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.junit.rules.ExternalResource; + +/** + * Clears the connection manager after each test. + */ +public class CloseWizardRule extends ExternalResource { + + @Override + protected void after() { + final SWTWorkbenchBot bot = new SWTWorkbenchBot(); + if (bot.button("Cancel") != null) { + bot.button("Cancel").click(); + } + } +} diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/DockerConnectionManagerUtils.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/DockerConnectionManagerUtils.java new file mode 100644 index 0000000000..365ca030f6 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/DockerConnectionManagerUtils.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * 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: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.ui.testutils.swt; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.linuxtools.docker.core.DockerConnectionManager; +import org.eclipse.linuxtools.docker.core.IDockerConnection; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionStorageManagerFactory; +import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView; + +/** + * + */ +public class DockerConnectionManagerUtils { + + /** + * Configures the {@link DockerConnectionManager} with the given array of + * {@link IDockerConnection} (can be mocked) and refreshes the associated + * {@link DockerExplorerView}. + * + * @param dockerExplorerView + * @param connections + * @throws InterruptedException + */ + public static void configureConnectionManager(final DockerExplorerView dockerExplorerView, + final IDockerConnection... connections) throws InterruptedException { + DockerConnectionManager.getInstance() + .setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(connections)); + SWTUtils.syncExec(() -> { + DockerConnectionManager.getInstance().reloadConnections(); + dockerExplorerView.getCommonViewer().refresh(); + dockerExplorerView.showConnectionsOrExplanations(); + }); + Thread.sleep(TimeUnit.SECONDS.toMillis(1)); + } +} diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTBotTreeItemAssertions.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTBotTreeItemAssertions.java index 5ac1a21c5e..68d3b3f724 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTBotTreeItemAssertions.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/SWTBotTreeItemAssertions.java @@ -32,7 +32,7 @@ public class SWTBotTreeItemAssertions extends AbstractSWTBotAssertion<SWTBotTree public SWTBotTreeItemAssertions isExpanded() { notNullValue(); if(!actual.isExpanded()) { - failWithMessage("Expected tree item %s to be expanded but it was not.", actual.getText());; + failWithMessage("Expected tree item %s to be expanded but it was not.", actual.getText()); } return this; } @@ -45,7 +45,7 @@ public class SWTBotTreeItemAssertions extends AbstractSWTBotAssertion<SWTBotTree public SWTBotTreeItemAssertions hasChildItems(final int expectedCount) { notNullValue(); if(actual.getItems().length != expectedCount) { - failWithMessage("Expected tree item %s to be have %s items but it had %s.", actual.getText(), expectedCount, actual.getItems().length);; + failWithMessage("Expected tree item %s to be have %s items but it had %s.", actual.getText(), expectedCount, actual.getItems().length); } for (SWTBotTreeItem swtBotTreeItem : actual.getItems()) { Assertions.assertThat(swtBotTreeItem.getText()).isNotNull(); diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/TestLoggerRule.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/TestLoggerRule.java new file mode 100644 index 0000000000..b7c3d4b43a --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/swt/TestLoggerRule.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * 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: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.ui.testutils.swt; + +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; + +/** + * + */ +public class TestLoggerRule extends TestWatcher { + + @Override + protected void starting(final Description description) { + System.out.println("Starting " + description.getClassName() + "." + description.getMethodName()); + } +} diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java index 8121be146e..a8aa9fb4ab 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerViewSWTBotTest.java @@ -11,25 +11,21 @@ package org.eclipse.linuxtools.internal.docker.ui.views; -import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; - import org.assertj.core.api.Assertions; import org.eclipse.jface.viewers.Viewer; -import org.eclipse.linuxtools.docker.core.DockerConnectionManager; -import org.eclipse.linuxtools.docker.core.IDockerConnection; -import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionStorageManager; import org.eclipse.linuxtools.internal.docker.core.DockerConnection; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerClientFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionFactory; -import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionStorageManagerFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerContainerFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerContainerInfoFactory; import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerImageFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.ClearConnectionManagerRule; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.CloseWelcomePageRule; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.DockerConnectionManagerUtils; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.DockerExplorerViewAssertion; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.SWTBotTreeItemAssertions; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.SWTUtils; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.TestLoggerRule; import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.eclipse.finder.waits.Conditions; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; @@ -37,15 +33,11 @@ import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; import org.eclipse.ui.PlatformUI; -import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; import org.junit.runner.RunWith; import com.spotify.docker.client.DockerClient; @@ -65,12 +57,10 @@ public class DockerExplorerViewSWTBotTest { public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule(); @Rule - public TestWatcher watcher = new TestWatcher() { - @Override - protected void starting(final Description description) { - System.out.println("Starting " + description.getClassName() + "." + description.getMethodName()); - } - }; + public TestLoggerRule watcher = new TestLoggerRule(); + + @Rule + public ClearConnectionManagerRule clearConnectionManager = new ClearConnectionManagerRule(); @Before public void setup() throws InterruptedException { @@ -90,34 +80,10 @@ public class DockerExplorerViewSWTBotTest { .forEach(v -> v.close()); } - @After - public void clearConnectionManager() { - SWTUtils.syncExec(() -> { Stream.of(DockerConnectionManager.getInstance().getConnections()) - .forEach(c -> DockerConnectionManager.getInstance().removeConnection(c)); - dockerExplorerView.getCommonViewer().refresh(true); - dockerExplorerView.showConnectionsOrExplanations();}); - } - - @AfterClass - public static void restoreDefaultConfig() { - DockerConnectionManager.getInstance().setConnectionStorageManager(new DefaultDockerConnectionStorageManager()); - } - - private void configureConnectionManager(final IDockerConnection... connections) throws InterruptedException { - DockerConnectionManager.getInstance() - .setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(connections)); - SWTUtils.syncExec(() -> { - DockerConnectionManager.getInstance().reloadConnections(); - dockerExplorerView.getCommonViewer().refresh(); - dockerExplorerView.showConnectionsOrExplanations(); - }); - Thread.sleep(TimeUnit.SECONDS.toMillis(1)); - } - @Test public void shouldDisplayExplanationPane() throws InterruptedException { // given - configureConnectionManager(); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView); // then DockerExplorerViewAssertion.assertThat(dockerExplorerView).isEmpty(); } @@ -125,9 +91,9 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldDisplayConnectionsPane() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages().noContainers(); + final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); // then DockerExplorerViewAssertion.assertThat(dockerExplorerView).isNotEmpty(); } @@ -135,9 +101,9 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldRefreshImagesAndShowChanges() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages().noContainers(); + final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem[] allItems = dockerExplorerViewBot.bot().tree().getAllItems(); Assertions.assertThat(allItems).hasSize(1); @@ -148,7 +114,8 @@ public class DockerExplorerViewSWTBotTest { Assertions.assertThat(imagesTreeItem.getItems().length).isEqualTo(0); // update the client - final DockerClient updatedClient = MockDockerClientFactory.images(MockDockerImageFactory.name("foo/bar").build()).noContainers(); + final DockerClient updatedClient = MockDockerClientFactory.image(MockDockerImageFactory.name("foo/bar").build()) + .build(); dockerConnection.setClient(updatedClient); // when locating the 'Images' node and hit refresh dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); @@ -165,9 +132,9 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldRefreshContainersAndShowChanges() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages().noContainers(); + final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); Conditions.waitForJobs(DockerExplorerView.class, "Docker Explorer View jobs"); final SWTBotTreeItem[] allItems = dockerExplorerViewBot.bot().tree().getAllItems(); @@ -180,7 +147,7 @@ public class DockerExplorerViewSWTBotTest { Assertions.assertThat(containersTreeItem.getItems().length).isEqualTo(0); // update the client - final DockerClient updatedClient = MockDockerClientFactory.noImages().container(MockDockerContainerFactory.name("foo_bar").build()).build(); + final DockerClient updatedClient = MockDockerClientFactory.container(MockDockerContainerFactory.name("foo_bar").build()).build(); dockerConnection.setClient(updatedClient); dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); dockerExplorerViewTreeBot.select(containersTreeItem); @@ -195,12 +162,12 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldShowContainerPortMapping() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory .port("8080/tcp", "0.0.0.0", "8080").port("8787/tcp", "0.0.0.0", "8787").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when a second call to expand the container is done (because the first // expandAll stopped with a "Loading..." job that retrieved the @@ -224,12 +191,12 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldShowContainerLinks() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory .link("/postgres-demo:/foo_bar/postgres1").link("/postgres-demo:/foo_bar/postgres2").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when a second call to expand the container is done (because the first // expandAll stopped with a "Loading..." job that retrieved the @@ -250,14 +217,14 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldShowContainerVolumes() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.volume("/path/to/container") .volume("/path/to/host:/path/to/container") .volume("/path/to/host:/path/to/container:Z,ro").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); // when a second call to expand the container is done (because the first // expandAll stopped with a "Loading..." job that retrieved the @@ -281,7 +248,7 @@ public class DockerExplorerViewSWTBotTest { @Test public void shouldRemainExpandedAfterRefresh() throws InterruptedException { // given - final DockerClient client = MockDockerClientFactory.noImages() + final DockerClient client = MockDockerClientFactory .container(MockDockerContainerFactory.name("foo_bar").build(), MockDockerContainerInfoFactory.volume("/path/to/container") .port("8080/tcp", "0.0.0.0", "8080") @@ -289,7 +256,7 @@ public class DockerExplorerViewSWTBotTest { .volume("/path/to/host:/path/to/container:Z,ro").build()) .build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); - configureConnectionManager(dockerConnection); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); SWTUtils.asyncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); final SWTBotTreeItem containersTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test (null)", "Containers"); @@ -305,11 +272,9 @@ public class DockerExplorerViewSWTBotTest { SWTBotTreeItemAssertions.assertThat(SWTUtils.getTreeItem(containerTreeItem, "Volumes")).isExpanded(); }); // when refreshing the container - SWTUtils.asyncExec(() -> { - dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); - dockerExplorerViewTreeBot.select(containersTreeItem); - dockerExplorerViewTreeBot.contextMenu("Refresh").click(); - }); + dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); + dockerExplorerViewTreeBot.select(containersTreeItem); + dockerExplorerViewTreeBot.contextMenu("Refresh").click(); SWTUtils.asyncExec(() -> containersTreeItem.expand()); // then all items should remain expanded (after they were reloaded) SWTUtils.syncAssert(() -> { diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSWTBotTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSWTBotTest.java new file mode 100644 index 0000000000..d1730c62ef --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSWTBotTest.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * 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: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.ui.wizards; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.eclipse.linuxtools.internal.docker.core.DockerConnection; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerClientFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerContainerFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerImageFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.ClearConnectionManagerRule; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.CloseWelcomePageRule; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.CloseWizardRule; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.DockerConnectionManagerUtils; +import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.SWTUtils; +import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView; +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; + +import com.spotify.docker.client.DockerClient; + +/** + * Testing the {@link ImageRun} wizard + */ +public class ImageRunSWTBotTest { + + private SWTWorkbenchBot bot = new SWTWorkbenchBot(); + private DockerExplorerView dockerExplorerView; + private SWTBotView dockerExplorerViewBot; + + @ClassRule + public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule(); + + @Rule + public ClearConnectionManagerRule clearConnectionManager = new ClearConnectionManagerRule(); + + @Rule + public CloseWizardRule closeWizard = new CloseWizardRule(); + + @Before + public void lookupDockerExplorerView() { + dockerExplorerViewBot = bot.viewById("org.eclipse.linuxtools.docker.ui.dockerExplorerView"); + dockerExplorerView = (DockerExplorerView) (dockerExplorerViewBot.getViewReference().getView(true)); + dockerExplorerViewBot.show(); + dockerExplorerViewBot.setFocus(); + } + + @Test + public void shouldReportErrorIfContainerWithSameNameExists() throws InterruptedException { + // given + final DockerClient client = MockDockerClientFactory.image(MockDockerImageFactory.name("foo:latest").build()) + .container(MockDockerContainerFactory.name("foo_bar").build()).build(); + final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); + // expand the 'Images' node + SWTUtils.syncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); + final SWTBotTreeItem imagesTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Images"); + final SWTBotTreeItem imageTreeItem = SWTUtils.getTreeItem(imagesTreeItem, "foo"); + + // when opening the "Run Image..." wizard + final SWTBotTree dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); + dockerExplorerViewTreeBot.select(imageTreeItem); + dockerExplorerViewTreeBot.contextMenu("Run Image...").click(); + + // when use an existing container name + bot.textWithLabel(WizardMessages.getString("ImageRunSelectionPage.containerName")).setText("foo_bar"); + // then + // wait for https://bugs.eclipse.org/bugs/show_bug.cgi?id=482889 to be able to check the wiazard validation message + //assertThat(bot.text(WizardMessages.getString("ImageRunSelectionPage.containerWithSameName"))).isNotNull(); + assertThat(bot.button("Finish").isEnabled()).isEqualTo(false); + } + + @Test + public void shouldNotReportErrorIfNoContainerWithSameNameExists() throws InterruptedException { + // given + final DockerClient client = MockDockerClientFactory.image(MockDockerImageFactory.name("foo:latest").build()) + .container(MockDockerContainerFactory.name("foo_bar").build()).build(); + final DockerConnection dockerConnection = MockDockerConnectionFactory.from("Test", client).get(); + DockerConnectionManagerUtils.configureConnectionManager(dockerExplorerView, dockerConnection); + // expand the 'Images' node + SWTUtils.syncExec(() -> dockerExplorerView.getCommonViewer().expandAll()); + final SWTBotTreeItem imagesTreeItem = SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Images"); + final SWTBotTreeItem imageTreeItem = SWTUtils.getTreeItem(imagesTreeItem, "foo"); + + // when opening the "Run Image..." wizard + final SWTBotTree dockerExplorerViewTreeBot = dockerExplorerViewBot.bot().tree(); + dockerExplorerViewTreeBot.select(imageTreeItem); + dockerExplorerViewTreeBot.contextMenu("Run Image...").click(); + + // when use an existing container name + bot.textWithLabel(WizardMessages.getString("ImageRunSelectionPage.containerName")).setText("foo_bar_baz"); + // then + assertThat(bot.button("Finish").isEnabled()).isEqualTo(true); + } + +} diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java index c6549ab204..20d012f72d 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java @@ -243,7 +243,10 @@ public class CommandUtils { * @return the {@link RunConsole} or {@code null} */ public static RunConsole getRunConsole(final IDockerConnection connection, final IDockerContainer container) { - if (connection.getContainerInfo(container.id()).config().tty()) { + if (container != null + && connection.getContainerInfo(container.id()) != null + && connection.getContainerInfo(container.id()).config() != null + && connection.getContainerInfo(container.id()).config().tty()) { RunConsole.attachToTerminal(connection, container.id()); return null; } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java index 42fb893fbb..6465a9f7a5 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java @@ -230,10 +230,20 @@ public class ImageRun extends Wizard { return config.build(); } - // Create a proper command list after handling quotation. - private List<String> getCmdList(String s) { - ArrayList<String> list = new ArrayList<>(); - int length = s.length(); + /** + * Create a proper command list after handling quotation. + * + * @param command + * the command as a single {@link String} + * @return the command splitted in a list of ars or <code>null</code> if the + * input <code>command</code> was <code>null</code>. + */ + private List<String> getCmdList(final String command) { + if (command == null) { + return null; + } + final List<String> list = new ArrayList<>(); + int length = command.length(); boolean insideQuote1 = false; // single-quote boolean insideQuote2 = false; // double-quote boolean escaped = false; @@ -242,7 +252,7 @@ public class ImageRun extends Wizard { // separated by white-space or are quoted. Ignore characters // that have been escaped, including the escape character. for (int i = 0; i < length; ++i) { - char c = s.charAt(i); + char c = command.charAt(i); if (escaped) { buffer.append(c); escaped = false; diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java index 50a06670df..cd61b0847f 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java @@ -97,7 +97,8 @@ public class ImageRunResourceVolumesVariablesModel if (selectedImage != null) { this.imageInfo = selectedImage.getConnection() .getImageInfo(selectedImage.id()); - if (this.imageInfo.config().volumes() != null) { + if (this.imageInfo.config() != null + && this.imageInfo.config().volumes() != null) { for (String volume : this.imageInfo.config().volumes()) { newDataVolumes.add(new DataVolumeModel(volume)); } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java index 41e54f8aae..880ca13f9e 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java @@ -16,7 +16,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Set; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; @@ -55,6 +54,7 @@ import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.linuxtools.docker.core.DockerException; import org.eclipse.linuxtools.docker.core.IDockerConnection; +import org.eclipse.linuxtools.docker.core.IDockerContainer; import org.eclipse.linuxtools.docker.core.IDockerImage; import org.eclipse.linuxtools.docker.core.IDockerImageInfo; import org.eclipse.linuxtools.docker.ui.Activator; @@ -174,6 +174,13 @@ public class ImageRunSelectionPage extends WizardPage { final ImageSelectionValidator imageSelectionValidator = new ImageSelectionValidator( imageSelectionObservable); dbc.addValidationStatusProvider(imageSelectionValidator); + final IObservableValue containerNameObservable = BeanProperties + .value(ImageRunSelectionModel.class, + ImageRunSelectionModel.CONTAINER_NAME) + .observe(model); + final ContainerNameValidator containerNameValidator = new ContainerNameValidator( + model.getSelectedConnection(), containerNameObservable); + dbc.addValidationStatusProvider(containerNameValidator); // setControl(container); } @@ -198,7 +205,8 @@ public class ImageRunSelectionPage extends WizardPage { private void createImageSettingsSection(final Composite container) { // Image selection name final Label imageSelectionLabel = new Label(container, SWT.NONE); - imageSelectionLabel.setText("Image:"); //$NON-NLS-1$ + imageSelectionLabel.setText( + WizardMessages.getString("ImageRunSelectionPage.imageName")); //$NON-NLS-1$ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) .grab(false, false).applyTo(imageSelectionLabel); final Combo imageSelectionCombo = new Combo(container, SWT.BORDER); @@ -262,7 +270,8 @@ public class ImageRunSelectionPage extends WizardPage { final Label containerNameLabel = new Label(container, SWT.NONE); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) .grab(false, false).applyTo(imageSelectionLabel); - containerNameLabel.setText("Name:"); //$NON-NLS-1$ + containerNameLabel.setText(WizardMessages + .getString("ImageRunSelectionPage.containerName")); //$NON-NLS-1$ final Text containerNameText = new Text(container, SWT.BORDER); containerNameText.setToolTipText(WizardMessages .getString("ImageRunSelectionPage.containerTooltip")); //$NON-NLS-1$ @@ -781,24 +790,24 @@ public class ImageRunSelectionPage extends WizardPage { getContainer().run(true, true, findImageInfoRunnable); final IDockerImageInfo selectedImageInfo = findImageInfoRunnable .getResult(); - final Set<String> exposedPortInfos = selectedImageInfo.config() - .exposedPorts(); - final WritableList availablePorts = new WritableList(); - if (exposedPortInfos != null) { - for (String exposedPortInfo : exposedPortInfos) { - final String privatePort = exposedPortInfo.substring(0, - exposedPortInfo.indexOf('/')); - final String type = exposedPortInfo - .substring(exposedPortInfo.indexOf('/')); // $NON-NLS-1$ - final ExposedPortModel exposedPort = new ExposedPortModel( - privatePort, type, "", privatePort); - availablePorts.add(exposedPort); // $NON-NLS-1$ + if (selectedImageInfo.config() != null) { + model.setCommand(selectedImageInfo.config().cmd()); + model.setEntrypoint(selectedImageInfo.config().entrypoint()); + if (selectedImageInfo.config().exposedPorts() != null) { + final WritableList availablePorts = new WritableList(); + for (String exposedPortInfo : selectedImageInfo.config() + .exposedPorts()) { + final String privatePort = exposedPortInfo.substring(0, + exposedPortInfo.indexOf('/')); + final String type = exposedPortInfo + .substring(exposedPortInfo.indexOf('/')); // $NON-NLS-1$ + final ExposedPortModel exposedPort = new ExposedPortModel( + privatePort, type, "", privatePort); + availablePorts.add(exposedPort); // $NON-NLS-1$ + } + model.setExposedPorts(availablePorts); } } - model.setExposedPorts(availablePorts); - model.setCommand(selectedImageInfo.config().cmd()); - model.setEntrypoint(selectedImageInfo.config().entrypoint()); - } catch (InvocationTargetException | InterruptedException e) { Activator.log(e); } @@ -921,4 +930,39 @@ public class ImageRunSelectionPage extends WizardPage { } + private class ContainerNameValidator extends MultiValidator { + + private final IDockerConnection connection; + + private final IObservableValue containerNameObservable; + + ContainerNameValidator(final IDockerConnection connection, + final IObservableValue containerNameObservable) { + this.connection = connection; + this.containerNameObservable = containerNameObservable; + } + + @Override + protected IStatus validate() { + final String containerName = (String) containerNameObservable + .getValue(); + + for (IDockerContainer container : connection.getContainers()) { + if (container.name().equals(containerName)) { + return ValidationStatus.error(WizardMessages.getString( + "ImageRunSelectionPage.containerWithSameName")); //$NON-NLS-1$ + } + } + return ValidationStatus.ok(); + } + + @Override + public IObservableList getTargets() { + WritableList targets = new WritableList(); + targets.add(containerNameObservable); + return targets; + } + + } + } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties index 1e93aa9079..e8d495a389 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties @@ -227,8 +227,10 @@ ImageSelectionPage.runImage=Run a Docker Image ImageSelectionPage.exposedPortTitle=Image Selection and Exposed Port Publishing ImageRunSelectionPage.exposedPortMsg=Select the Docker Image to run and the ports to expose ImageRunSelectionPage.selectTooltip=Select the Docker Image to run +ImageRunSelectionPage.imageName=Image: ImageRunSelectionPage.search=Search... ImageRunSelectionPage.pullImage=<a>Pull this image...</a> +ImageRunSelectionPage.containerName=Name: ImageRunSelectionPage.containerTooltip=a UUID long identifier, a UUID short identifier or a String ImageRunSelectionPage.entrypoint=Entrypoint: ImageRunSelectionPage.command=Command: @@ -251,6 +253,7 @@ ImageRunSelectionPage.autoRemove=Automatically remove the container when it exit ImageRunSelectionPage.pullingTask=Pulling image ''{0}'' ImageRunSelectionPage.specifyImageMsg=Please specify the image to run. ImageRunSelectionPage.imageNotFoundMessage=Image named ''{0}'' does not exist locally. Click on the link under the 'Image' combo to start pulling it. +ImageRunSelectionPage.containerWithSameName=A container with the same name already exists. ImageRunResourceVolVarPage.title=Volumes, Environment Variables and Resource Limitations ImageRunResourceVolVarPage.enableLimitationButton=Enable resource limitations |