/******************************************************************************* * Copyright (c) 2015, 2016 Red Hat Inc. * 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 java.io.File; import java.io.IOException; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.wizard.Wizard; import org.eclipse.linuxtools.docker.core.IDockerConnection; import org.eclipse.linuxtools.internal.docker.core.DockerConnection; import org.eclipse.linuxtools.internal.docker.core.SystemUtils; 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.MockDockerConnectionSettingsFinder; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.ButtonAssertions; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.CheckBoxAssertions; import org.eclipse.linuxtools.internal.docker.ui.testutils.swt.CloseShellRule; 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.RadioAssertion; 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.TextAssertions; import org.eclipse.linuxtools.internal.docker.ui.views.DockerContainersView; import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView; import org.eclipse.linuxtools.internal.docker.ui.views.DockerImagesView; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Display; import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; import org.eclipse.swtbot.swt.finder.waits.Conditions; import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton; import org.eclipse.ui.PlatformUI; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import com.spotify.docker.client.DockerClient; /** * Testing the {@link NewDockerConnection} {@link Wizard} */ @RunWith(SWTBotJunit4ClassRunner.class) public class NewDockerConnectionSWTBotTest { private SWTWorkbenchBot bot = new SWTWorkbenchBot(); private SWTBotToolbarButton addConnectionButton; private SWTBotView dockerExplorerViewBot; @ClassRule public static CloseWelcomePageRule closeWelcomePage = new CloseWelcomePageRule( CloseWelcomePageRule.DOCKER_PERSPECTIVE_ID); @Rule public CloseShellRule closeShell = new CloseShellRule(IDialogConstants.CANCEL_LABEL); @Before public void lookupDockerExplorerView() throws Exception { 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()); } }); dockerExplorerViewBot = bot.viewById(DockerExplorerView.VIEW_ID); dockerExplorerViewBot.show(); bot.views().stream().filter(v -> v.getReference().getId().equals(DockerContainersView.VIEW_ID) || v.getReference().getId().equals(DockerImagesView.VIEW_ID)).forEach(v -> v.close()); dockerExplorerViewBot.setFocus(); this.addConnectionButton = dockerExplorerViewBot.toolbarButton("&Add Connection"); } @Before public void clearClipboards() { // Clear all clipboards Display.getDefault().syncExec(() -> { Clipboard clip = new Clipboard(Display.getCurrent()); clip.clearContents(DND.CLIPBOARD); clip.clearContents(DND.SELECTION_CLIPBOARD); }); } private IDockerConnection configureUnixSocketConnection(final String connectionName, final String pathToSocket) { final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from(connectionName, client) .withUnixSocketConnectionSettings(pathToSocket); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); return dockerConnection; } private IDockerConnection configureTCPConnection(final String connectionName, final String host) { final DockerClient client = MockDockerClientFactory.build(); final DockerConnection dockerConnection = MockDockerConnectionFactory.from(connectionName, client) .withTCPConnectionSettings(host, null); DockerConnectionManagerUtils.configureConnectionManager(dockerConnection); return dockerConnection; } @Test public void shouldShowCustomUnixSocketSettingsWhenNoConnectionAvailable() { // given MockDockerConnectionSettingsFinder.noDockerConnectionAvailable(); // when addConnectionButton.click(); // then // Empty Connection name TextAssertions.assertThat(bot.text(0)).isEnabled().isEmpty(); // "Use custom connection settings" should be enabled and checked CheckBoxAssertions.assertThat(bot.checkBox(0)).isEnabled().isChecked(); // "Unix socket" radio should be enabled and selected RadioAssertion.assertThat(bot.radio(0)).isEnabled().isSelected(); // "Unix socket path" text should be enabled and empty TextAssertions.assertThat(bot.text(1)).isEnabled().isEmpty(); // "TCP Connection" radio should be enabled but unselected RadioAssertion.assertThat(bot.radio(1)).isEnabled().isNotSelected(); // "URI" should be disabled but empty TextAssertions.assertThat(bot.text(2)).isNotEnabled().isEmpty(); // "Enable Auth" checkbox should be unselected and disabled CheckBoxAssertions.assertThat(bot.checkBox(1)).isNotEnabled().isNotChecked(); // "Path" for certs should be disabled and empty TextAssertions.assertThat(bot.text(3)).isNotEnabled().isEmpty(); } @Test public void shouldShowDefaultUnixSocketConnectionSettingsWithValidConnectionAvailable() { // given MockDockerConnectionSettingsFinder.validUnixSocketConnectionAvailable(); // when addConnectionButton.click(); // then // Connection name TextAssertions.assertThat(bot.text(0)).isEnabled().textEquals("mock"); // "Use custom connection settings" should be enabled but unchecked CheckBoxAssertions.assertThat(bot.checkBox(0)).isEnabled().isNotChecked(); // "Unix socket" radio should be disabled and selected RadioAssertion.assertThat(bot.radio(0)).isNotEnabled().isSelected(); // "Unix socket path" text should be disabled and not empty TextAssertions.assertThat(bot.text(1)).isNotEnabled().textEquals("unix:///var/run/docker.sock"); // "TCP Connection" radio should be unselected and disabled RadioAssertion.assertThat(bot.radio(1)).isNotEnabled().isNotSelected(); // "URI" should be disabled and empty TextAssertions.assertThat(bot.text(2)).isNotEnabled().isEmpty(); // "Enable Auth" checkbox should be unselected and disabled CheckBoxAssertions.assertThat(bot.checkBox(1)).isNotEnabled().isNotChecked(); // "Path" for certs should be disabled but not empty TextAssertions.assertThat(bot.text(3)).isNotEnabled().isEmpty(); } @Test public void shouldShowDefaultTCPSettingsWithValidConnectionAvailable() { // given MockDockerConnectionSettingsFinder.validTCPConnectionAvailable(); // when addConnectionButton.click(); bot.waitUntil(Conditions.shellIsActive(WizardMessages.getString("NewDockerConnection.title"))); //$NON-NLS-1$ // then // Connection name TextAssertions.assertThat(bot.text(0)).isEnabled().textEquals("mock"); // "Use custom connection settings" should be enabled but unchecked CheckBoxAssertions.assertThat(bot.checkBox(0)).isEnabled().isNotChecked(); // "Unix socket" radio should be disabled and unselected RadioAssertion.assertThat(bot.radio(0)).isNotEnabled().isNotSelected(); // "Unix socket path" text should be disabled and not empty TextAssertions.assertThat(bot.text(1)).isNotEnabled().isEmpty(); // "TCP Connection" radio should be selected but diabled RadioAssertion.assertThat(bot.radio(1)).isNotEnabled().isSelected(); // "URI" should be disabled but not empty TextAssertions.assertThat(bot.text(2)).isNotEnabled().textEquals("https://1.2.3.4:1234"); // "Enable Auth" checkbox should be selected but disabled CheckBoxAssertions.assertThat(bot.checkBox(1)).isNotEnabled().isChecked(); // "Path" for certs should be disabled but not empty TextAssertions.assertThat(bot.text(3)).isNotEnabled().textEquals("/path/to/certs"); } @Test public void shouldAddConnectionToDockerExplorerView() throws IOException { // given final File dockerSocketTmpFile = File.createTempFile("docker", ".sock"); MockDockerConnectionSettingsFinder.validUnixSocketConnectionAvailable("Mock", "unix://" + dockerSocketTmpFile.getAbsolutePath()); // when open wizard addConnectionButton.click(); bot.waitUntil(Conditions.shellIsActive(WizardMessages.getString("NewDockerConnection.title"))); //$NON-NLS-1$ // when click on "OK" bot.button("Finish").click(); // then the Docker Explorer view should have a connection named "Mock" SWTBotTreeItemAssertions.assertThat(SWTUtils.getTreeItem(dockerExplorerViewBot.bot().tree(), "Mock")) .isNotNull(); } @Test public void shouldNotAllowNewConnectionWithDifferentNameAndSameUnixSocketSettings() throws IOException { // given final String dockerSocketTmpPath = File.createTempFile("docker", ".sock").getAbsolutePath(); MockDockerConnectionSettingsFinder.validUnixSocketConnectionAvailable("Mock", "unix://" + dockerSocketTmpPath); // add an existing connection based on the settings above configureUnixSocketConnection("Mock", dockerSocketTmpPath); // when open wizard addConnectionButton.click(); bot.waitUntil(Conditions.shellIsActive(WizardMessages.getString("NewDockerConnection.title"))); //$NON-NLS-1$ // when changing connection name bot.text(0).setText("foo"); // then the wizard should not allow for completion because a connection // with the connection settings already exists. ButtonAssertions.assertThat(bot.button("Finish")).isNotEnabled(); } @Test public void shouldNotAllowNewConnectionWithDifferentNameAndSameTCPSettings() { // given MockDockerConnectionSettingsFinder.validTCPConnectionAvailable("Mock", "https://foo:1234", null); // add an existing connection based on the settings above configureTCPConnection("Mock", "https://foo:1234"); // when open wizard addConnectionButton.click(); bot.waitUntil(Conditions.shellIsActive(WizardMessages.getString("NewDockerConnection.title"))); //$NON-NLS-1$ // when changing connection name bot.text(0).setText("foo"); // then the wizard should not allow for completion because a connection // with the connection settings already exists. ButtonAssertions.assertThat(bot.button("Finish")).isNotEnabled(); } @Test public void shouldAllowNewConnectionWithDifferentNameAndUnixSettings() throws IOException { // given final String dockerSocketTmpPath = File.createTempFile("docker", ".sock").getAbsolutePath(); configureUnixSocketConnection("Bar", dockerSocketTmpPath); MockDockerConnectionSettingsFinder.validUnixSocketConnectionAvailable("Mock", "unix://" + dockerSocketTmpPath); final String otherDockerSocketTmpPath = File.createTempFile("docker", ".sock").getAbsolutePath(); // when open wizard addConnectionButton.click(); bot.waitUntil(Conditions.shellIsActive(WizardMessages.getString("NewDockerConnection.title"))); //$NON-NLS-1$ // when changing connection name bot.text(0).setText("foo"); bot.checkBox(0).select(); bot.text(1).setText(otherDockerSocketTmpPath); // then the wizard should not allow for completion because a connection // with the connection settings already exists. ButtonAssertions.assertThat(bot.button("Finish")).isEnabled(); } @Test public void shouldAllowNewConnectionWithDifferentNameAndTCPSettings() { // given MockDockerConnectionSettingsFinder.validTCPConnectionAvailable("Mock", "https://foo:1234", null); // add an existing connection based on the settings above configureTCPConnection("Mock", "https://foo"); // when open wizard addConnectionButton.click(); bot.waitUntil(Conditions.shellIsActive(WizardMessages.getString("NewDockerConnection.title"))); //$NON-NLS-1$ // when changing connection name bot.text(0).setText("foo"); bot.checkBox(0).select(); bot.text(2).setText("https://bar:1234"); // then the wizard should not allow for completion because a connection // with the connection settings already exists. ButtonAssertions.assertThat(bot.button("Finish")).isEnabled(); } @Test public void shouldPopulateConnectionWithClipboard() { verifyPopulateConnectionWithClipboard(DND.CLIPBOARD); } @Test public void shouldPopulateConnectionWithSelectionClipboard() { // SELECTION_CLIPBOARD does not seem to be supported on platforms other // than Linux (GTK/Motif) Assume.assumeTrue("This test only runs on Linux", SystemUtils.isLinux()); verifyPopulateConnectionWithClipboard(DND.SELECTION_CLIPBOARD); } private void verifyPopulateConnectionWithClipboard(final int clipboardType) { // given final String[] connectionData = new String[] { "DOCKER_HOST=https://1.2.3.4:1234 DOCKER_CERT_PATH=/path/to/certs DOCKER_TLS_VERIFY=1" }; Display.getDefault().syncExec(() -> { Clipboard clip = new Clipboard(Display.getCurrent()); clip.setContents(connectionData, new Transfer[] { TextTransfer.getInstance() }, clipboardType); }); // when addConnectionButton.click(); // then // Connection name TextAssertions.assertThat(bot.text(0)).isEnabled().isEmpty(); // "Use custom connection settings" should be enabled and checked CheckBoxAssertions.assertThat(bot.checkBox(0)).isEnabled().isChecked(); // "Unix socket" radio should be enabled and unselected RadioAssertion.assertThat(bot.radio(0)).isEnabled().isNotSelected(); // "Unix socket path" text should be disabled and empty TextAssertions.assertThat(bot.text(1)).isNotEnabled().isEmpty(); // "TCP Connection" radio should be enabled and selected RadioAssertion.assertThat(bot.radio(1)).isEnabled().isSelected(); // "URI" should be enabled and not empty TextAssertions.assertThat(bot.text(2)).isEnabled().textEquals("https://1.2.3.4:1234"); // "Enable Auth" checkbox should be enabled and selected CheckBoxAssertions.assertThat(bot.checkBox(1)).isEnabled().isChecked(); // "Path" for certs should be enabled and not empty TextAssertions.assertThat(bot.text(3)).isEnabled().textEquals("/path/to/certs"); // Close wizard bot.button("Cancel").click(); } }