/*******************************************************************************
* Copyright (c) 2016 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.views;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.core.IDockerImageHierarchyNode;
import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
import org.eclipse.linuxtools.internal.docker.ui.testutils.MockContainerFactory;
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.MockImageFactory;
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.DockerImageHierarchyViewAssertions;
import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.MenuAssertion;
import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.SWTUtils;
import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.TabDescriptorAssertions;
import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.TestLoggerRule;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.junit.After;
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;
import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.Image;
/**
* Testing the {@link DockerImageHierarchyView} call from the
* {@link DockerExplorerView}.
*/
public class DockerImageHierarchyViewSWTBotTest {
private SWTWorkbenchBot bot = new SWTWorkbenchBot();
private SWTBotView dockerExplorerViewBot;
private DockerExplorerView dockerExplorerView;
@ClassRule
public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule(
CloseWelcomePageRule.DOCKER_PERSPECTIVE_ID);
@Rule
public TestLoggerRule watcher = new TestLoggerRule();
@Rule
public ClearConnectionManagerRule clearConnectionManager = new ClearConnectionManagerRule();
private DockerConnection connection;
@Before
public void setupViews() {
this.bot = new SWTWorkbenchBot();
SWTUtils.asyncExec(() -> {
try {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.showView(DockerExplorerView.VIEW_ID);
} catch (Exception e) {
e.printStackTrace();
Assert.fail("Failed to open Docker Explorer view: " + e.getMessage());
}
});
this.dockerExplorerViewBot = bot.viewById(DockerExplorerView.VIEW_ID);
this.dockerExplorerView = (DockerExplorerView) (dockerExplorerViewBot.getViewReference().getView(true));
// make sure that the Docker Image Hierarchy view is closed
this.bot.views().stream().filter(v -> v.getReference().getId().equals(DockerImageHierarchyView.VIEW_ID))
.forEach(v -> v.close());
}
@Before
public void setupData() {
// data is built as follows:
// root_image
// |- foo_image1
// _|- foo_container1 (Up)
// _|- foo_image2
// __|- foo_container21 (Exited)
// __|- foo_container22 (Paused)
// |- bar_image11
// _|- bar_container1
final Image rootImage = MockImageFactory.id("sha256:root_image").name("root_image").build();
final Image fooImage1 = MockImageFactory.id("sha256:foo_image1").name("foo_image1")
.parentId("sha256:root_image").build();
final Image fooImage2 = MockImageFactory.id("sha256:foo_image2").name("foo_image2", "foo_image2_alias")
.parentId("sha256:foo_image1").build();
final Container fooContainer1 = MockContainerFactory.id("sha256:foo_container1").name("foo_container1")
.imageName("foo_image1").status("Up").build();
final Container fooContainer21 = MockContainerFactory.id("sha256:foo_container21").name("foo_container21")
.imageName("foo_image2").status("Exited").build();
final Container fooContainer22 = MockContainerFactory.id("sha256:foo_container22").name("foo_container22")
.imageName("foo_image2_alias").status("Up (Paused)").build();
final Image barImage1 = MockImageFactory.id("sha256:bar_image1").name("bar_image1")
.parentId("sha256:root_image").build();
final Container barContainer1 = MockContainerFactory.id("sha256:bar_container1").name("bar_container1")
.imageName("bar_image1").build();
final DockerClient client = MockDockerClientFactory.image(rootImage).image(fooImage1).container(fooContainer1)
.image(fooImage2).container(fooContainer21).container(fooContainer22).image(barImage1)
.container(barContainer1).build();
this.connection = MockDockerConnectionFactory.from("Test", client).withDefaultTCPConnectionSettings();
this.connection.getImages(true);
this.connection.getContainers(true);
DockerConnectionManagerUtils.configureConnectionManager(connection);
}
@After
public void hideMenu() {
try {
SWTUtils.hideMenu(dockerExplorerViewBot.bot().tree());
} catch (WidgetNotFoundException e) {
// ignore if widget is not found, that's probably because there's no
// tree in the
// Docker Explorer view for the test that just ran.
}
}
private List<String> getChildrenElementIds(final IDockerImageHierarchyNode fooImageHierarchy) {
return fooImageHierarchy.getChildren().stream().map(e -> {
if (e.getElement() instanceof IDockerImage) {
return ((IDockerImage) e.getElement()).id();
}
return ((IDockerContainer) e.getElement()).id();
}).collect(Collectors.toList());
}
private DockerImageHierarchyView getDockerImageHierarchyView() {
final SWTBotView hierarchyViewBot = bot.viewById(DockerImageHierarchyView.VIEW_ID);
return (DockerImageHierarchyView) hierarchyViewBot.getViewReference().getView(true);
}
private static SWTBotTreeItem selectImageInTreeView(final SWTWorkbenchBot bot, final String... path) {
final SWTBotView dockerImageHierarchyViewBot = bot.viewById(DockerImageHierarchyView.VIEW_ID);
final DockerImageHierarchyView dockerImageHierarchyView = (DockerImageHierarchyView) (dockerImageHierarchyViewBot
.getViewReference().getView(true));
SWTUtils.asyncExec(() -> dockerImageHierarchyView.getCommonViewer().expandAll());
// when a second call to expand the container is done (because the first
// expandAll stopped with a "Loading..." job that retrieved the
// containers)
return SWTUtils.getTreeItem(dockerImageHierarchyViewBot, path).select();
}
@Test
public void shouldDisplayImageHierarchyViewWhenSelectingImage() {
// given
SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Images", "foo_image1").select();
// when
dockerExplorerViewBot.bot().tree().contextMenu("Open Image Hierarchy").click(); //$NON-NLS-1$
// then the view should be visible and selection should be on
// foo_image1
DockerImageHierarchyViewAssertions.assertThat(getDockerImageHierarchyView())
.hasSelectedElement(this.connection.getImage("sha256:foo_image1"));
}
@Test
public void shouldDisplayImageHierarchyViewWhenSelectingImageAlias() {
// given
SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Images", "foo_image2_alias").select();
// when
dockerExplorerViewBot.bot().tree().contextMenu("Open Image Hierarchy").click(); //$NON-NLS-1$
// then the view should be visible and selection should be on
// foo_image2
DockerImageHierarchyViewAssertions.assertThat(getDockerImageHierarchyView())
.hasSelectedElement(this.connection.getImage("sha256:foo_image2"));
}
@Test
public void shouldDisplayImageHierarchyViewWhenSelectingContainer() {
// given
SWTUtils.getTreeItem(dockerExplorerViewBot, "Test", "Containers", "foo_container1").select();
// when
dockerExplorerViewBot.bot().tree().contextMenu("Open Image Hierarchy").click(); //$NON-NLS-1$
// then the view should be visible and selection should be on
// foo_container1
DockerImageHierarchyViewAssertions.assertThat(SWTUtils.getView(this.bot, DockerImageHierarchyView.VIEW_ID))
.hasSelectedElement(this.connection.getContainer("sha256:foo_container1"));
}
@Test
public void shouldRetrieveImageHierarchyFromRootImage() {
// given
final IDockerImage rootImage = this.connection.getImage("sha256:root_image");
// when
final IDockerImageHierarchyNode rootImageHierarchy = this.connection.resolveImageHierarchy(rootImage);
// then
assertThat(rootImageHierarchy).isNotNull();
assertThat(rootImageHierarchy.getElement()).isEqualTo(rootImage);
// 2 direct children: foo_image1 and bar_image1
assertThat(rootImageHierarchy.getChildren()).hasSize(2);
assertThat(rootImageHierarchy.getParent()).isNull();
final IDockerImageHierarchyNode fooImage1Hierarchy = rootImageHierarchy.getChild("sha256:foo_image1");
assertThat(fooImage1Hierarchy.getParent()).isEqualTo(rootImageHierarchy);
// 2 direct children: foo_image2/foo_image2_alias and foo_container1
assertThat(fooImage1Hierarchy.getChildren()).hasSize(2);
}
@Test
public void shouldRetrieveImageHierarchyFromIntermediateImage() {
// given
final IDockerImage fooImage1 = this.connection.getImage("sha256:foo_image1");
// when
final IDockerImageHierarchyNode fooImage1Hierarchy = this.connection.resolveImageHierarchy(fooImage1);
// then
assertThat(fooImage1Hierarchy).isNotNull();
assertThat(fooImage1Hierarchy.getElement()).isEqualTo(fooImage1);
assertThat(getChildrenElementIds(fooImage1Hierarchy)).contains("sha256:foo_container1", "sha256:foo_image2");
final IDockerImage rootElement = (IDockerImage) fooImage1Hierarchy.getParent().getElement();
assertThat(rootElement.id()).isEqualTo("sha256:root_image");
// the parent only shows this child element, not its whole descendants
assertThat(fooImage1Hierarchy.getParent().getChildren()).containsExactly(fooImage1Hierarchy);
final IDockerImageHierarchyNode fooImage2HierarchyNode = fooImage1Hierarchy.getChild("sha256:foo_image2");
assertThat(fooImage2HierarchyNode).isNotNull();
// 2 child containers: foo_container21 and foo_container22
assertThat(fooImage2HierarchyNode.getChildren()).hasSize(2);
final IDockerImageHierarchyNode fooContainer1HierarchyNode = fooImage1Hierarchy
.getChild("sha256:foo_container1");
assertThat(fooContainer1HierarchyNode).isNotNull();
assertThat(fooContainer1HierarchyNode.getChildren()).isEmpty();
}
@Test
public void shouldRetrieveImageHierarchyFromLeafImage() {
// given
final IDockerImage fooImage2 = this.connection.getImage("sha256:foo_image2");
// when
final IDockerImageHierarchyNode fooImage2Hierarchy = this.connection.resolveImageHierarchy(fooImage2);
// then
assertThat(fooImage2Hierarchy).isNotNull();
assertThat(fooImage2Hierarchy.getElement()).isEqualTo(fooImage2);
// 2 containers: foo_container21 and foo_container22
assertThat(fooImage2Hierarchy.getChildren()).hasSize(2);
assertThat((IDockerContainer) fooImage2Hierarchy.getChild("sha256:foo_container21").getElement()).isNotNull();
final IDockerImageHierarchyNode fooImage1Hierarchy = fooImage2Hierarchy.getParent();
final IDockerImage fooImage = (IDockerImage) fooImage1Hierarchy.getElement();
assertThat(fooImage.id()).isEqualTo("sha256:foo_image1");
// in this case, intermediate images shows a single child
assertThat(fooImage1Hierarchy.getChildren()).hasSize(1);
assertThat(fooImage1Hierarchy.getChildren()).containsExactly(fooImage2Hierarchy);
}
@Test
public void shouldRetrieveImageHierarchyFromContainerBasedOnIntermediateImage() {
// given
final IDockerContainer fooContainer1 = this.connection.getContainer("sha256:foo_container1");
// when
final IDockerImageHierarchyNode fooContainer1Hierarchy = this.connection.resolveImageHierarchy(fooContainer1);
// then
assertThat(fooContainer1Hierarchy).isNotNull();
assertThat(fooContainer1Hierarchy.getElement()).isEqualTo(fooContainer1);
assertThat(fooContainer1Hierarchy.getChildren()).isEmpty();
final IDockerImage fooImage1 = (IDockerImage) fooContainer1Hierarchy.getParent().getElement();
assertThat(fooImage1.id()).isEqualTo("sha256:foo_image1");
// parent images hierarchy only shows the selected container as its
// child.
assertThat(fooContainer1Hierarchy.getParent().getChildren()).containsExactly(fooContainer1Hierarchy);
}
@Test
public void shouldRetrieveImageHierarchyFromContainerBasedOnLeafImage() {
// given
// when
final IDockerContainer barContainer1 = this.connection.getContainer("sha256:bar_container1");
final IDockerImageHierarchyNode barContainer1Hierarchy = this.connection.resolveImageHierarchy(barContainer1);
// then
assertThat(barContainer1Hierarchy).isNotNull();
assertThat(barContainer1Hierarchy.getElement()).isEqualTo(barContainer1);
assertThat(barContainer1Hierarchy.getChildren()).isEmpty();
final IDockerImage barImageElement = (IDockerImage) barContainer1Hierarchy.getParent().getElement();
assertThat(barImageElement.id()).isEqualTo("sha256:bar_image1");
}
@Test
public void shouldShowSelectedImageInPropertiesView() {
// given
final PropertySheet propertySheet = SWTUtils
.syncExec(() -> SWTUtils.getView(bot, "org.eclipse.ui.views.PropertySheet", true));
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root");
// show container info in Properties view
SWTUtils.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Show In", "Properties")
.click();
// the properties view should be visible and filled with images details
assertThat(propertySheet.getCurrentPage()).isInstanceOf(TabbedPropertySheetPage.class);
final TabbedPropertySheetPage currentPage = (TabbedPropertySheetPage) propertySheet.getCurrentPage();
TabDescriptorAssertions.assertThat(currentPage.getSelectedTab()).isNotNull()
.hasId("org.eclipse.linuxtools.docker.ui.properties.image.info");
}
@Test
public void shouldShowSelectedContainerInPropertiesView() {
// given
final PropertySheet propertySheet = SWTUtils
.syncExec(() -> SWTUtils.getView(bot, "org.eclipse.ui.views.PropertySheet", true));
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_container1");
// show container info in Properties view
SWTUtils.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Show In", "Properties")
.click();
assertThat(propertySheet.getCurrentPage()).isInstanceOf(TabbedPropertySheetPage.class);
final TabbedPropertySheetPage currentPage = (TabbedPropertySheetPage) propertySheet.getCurrentPage();
TabDescriptorAssertions.assertThat(currentPage.getSelectedTab()).isNotNull()
.hasId("org.eclipse.linuxtools.docker.ui.properties.container.info");
}
@Test
public void shouldProvideEnabledRemoveCommandOnSelectedImage() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Remove");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledAddTagCommandOnSelectedImage() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Add Tag");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledPushCommandOnSelectedImage() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Push...");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledStartCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_image2", "foo_container21");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Start");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledPauseCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_container1");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Pause");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledUnpauseCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_image2", "foo_container22");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Unpause");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledKillCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_container1");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Kill");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledRemoveCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_image2", "foo_container21");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Remove");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledCommitCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_image2", "foo_container21");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Commit");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledDisplayLogCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_image2", "foo_container21");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Display Log");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
@Test
public void shouldProvideEnabledRemoveLogCommandOnSelectedContainer() {
// given
shouldDisplayImageHierarchyViewWhenSelectingImage();
// when
selectImageInTreeView(bot, "root", "foo_image1", "foo_image2", "foo_container21");
final SWTBotMenu menu = SWTUtils
.getContextMenu(bot.viewById(DockerImageHierarchyView.VIEW_ID).bot().tree(), "Remove Log");
// then
MenuAssertion.assertThat(menu).isVisible().isEnabled();
}
}