| /******************************************************************************* |
| * Copyright (c) 2017 Red Hat, Inc. |
| * Distributed under license by Red Hat, Inc. All rights reserved. |
| * This program is 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 |
| * |
| * Contributor: |
| * Red Hat, Inc. - initial API and implementation |
| ******************************************************************************/ |
| |
| package org.eclipse.linuxtools.docker.integration.tests.ui; |
| |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.eclipse.linuxtools.docker.core.DockerException; |
| import org.eclipse.linuxtools.docker.integration.tests.image.AbstractImageBotTest; |
| import org.eclipse.linuxtools.docker.integration.tests.mock.MockUtils; |
| import org.eclipse.linuxtools.docker.reddeer.preferences.DockerComposePreferencePage; |
| import org.eclipse.linuxtools.docker.reddeer.ui.DockerImagesTab; |
| import org.eclipse.linuxtools.docker.reddeer.utils.BrowserContentsCheck; |
| import org.eclipse.linuxtools.internal.docker.core.DockerCompose; |
| import org.eclipse.linuxtools.internal.docker.core.ProcessLauncher; |
| import org.eclipse.linuxtools.internal.docker.ui.testutils.CustomMatchers; |
| import org.jboss.reddeer.common.matcher.RegexMatcher; |
| import org.jboss.reddeer.common.wait.TimePeriod; |
| import org.jboss.reddeer.common.wait.WaitWhile; |
| import org.jboss.reddeer.core.condition.JobIsRunning; |
| import org.jboss.reddeer.core.matcher.WithTextMatcher; |
| import org.jboss.reddeer.eclipse.condition.ConsoleHasNoChange; |
| import org.jboss.reddeer.eclipse.jdt.ui.packageexplorer.PackageExplorer; |
| import org.jboss.reddeer.eclipse.ui.browser.BrowserView; |
| import org.jboss.reddeer.jface.preference.PreferenceDialog; |
| import org.jboss.reddeer.swt.api.Menu; |
| import org.jboss.reddeer.swt.exception.SWTLayerException; |
| import org.jboss.reddeer.swt.impl.button.FinishButton; |
| import org.jboss.reddeer.swt.impl.button.OkButton; |
| import org.jboss.reddeer.swt.impl.combo.LabeledCombo; |
| import org.jboss.reddeer.swt.impl.menu.ContextMenu; |
| import org.jboss.reddeer.swt.impl.menu.ShellMenu; |
| import org.jboss.reddeer.swt.impl.shell.DefaultShell; |
| import org.jboss.reddeer.workbench.ui.dialogs.WorkbenchPreferenceDialog; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.Matchers; |
| import org.mockito.Mockito; |
| import org.mockito.invocation.InvocationOnMock; |
| import org.mockito.stubbing.Answer; |
| |
| /** |
| * |
| * @author jkopriva@redhat.com |
| * |
| */ |
| |
| public class ComposeTest extends AbstractImageBotTest { |
| |
| private static final String FILE_DOCKER_COMPOSE = "docker-compose.yml"; |
| private static final String SYSPROP_DOCKER_COMPOSE_PATH = "dockerComposePath"; |
| private static final String PATH_TEST_COMPOSE = "resources/test-compose"; |
| private static final String PROJECT_TEST_COMPOSE = "test-compose"; |
| private static final String IMAGE_NAME = "test_compose"; |
| private static final String URL = "http://0.0.0.0:5000/"; |
| private String dockerComposePath = System.getProperty(SYSPROP_DOCKER_COMPOSE_PATH); |
| |
| // for Mockito |
| private CountDownLatch latch; |
| |
| @Before |
| public void before() throws DockerException, InterruptedException { |
| if (!mockitoIsUsed()) { |
| org.junit.Assume.assumeTrue(!StringUtils.isBlank(this.dockerComposePath)); |
| assertTrue( |
| "Please provide -D" + SYSPROP_DOCKER_COMPOSE_PATH |
| + "=<path to docker-compose binary> in your launch parameters.", |
| !StringUtils.isBlank(this.dockerComposePath)); |
| } |
| deleteAllConnections(); |
| if (mockitoIsUsed()) { |
| MockUtils.createDockerMockConnection(DEFAULT_CONNECTION_NAME); |
| // configure the 'docker-compose up' mocks with a CountDownLatch to |
| // simulate a long-running process |
| final ProcessLauncher mockProcessLauncher = Mockito.mock(ProcessLauncher.class, Mockito.RETURNS_DEEP_STUBS); |
| DockerCompose.getInstance().setProcessLauncher(mockProcessLauncher); |
| setupDockerComposeUpMockProcess(mockProcessLauncher); |
| // configure the 'docker-compose stop' mocks which release the |
| // CountDownLatch to halt the long-running process |
| setupDockerComposeStopMockProcess(mockProcessLauncher); |
| // Create temp file for DockerCompose |
| @SuppressWarnings("unused") |
| File dockerComposeTmpFile = null; |
| String tempDir = System.getProperty("java.io.tmpdir"); |
| dockerComposeTmpFile = new File(tempDir, "docker-compose"); |
| this.dockerComposePath = tempDir; |
| } |
| |
| } |
| |
| @Test |
| public void testCompose() { |
| // Set up Docker Compose location |
| PreferenceDialog dialog = new WorkbenchPreferenceDialog(); |
| DockerComposePreferencePage composePreference = new DockerComposePreferencePage(); |
| dialog.open(); |
| dialog.select(composePreference); |
| composePreference.setPathToDockerCompose(this.dockerComposePath); |
| composePreference.apply(); |
| new OkButton().click(); |
| |
| // Build Image |
| DockerImagesTab imagesTab = openDockerImagesTab(); |
| buildImage(IMAGE_NAME, PATH_TEST_COMPOSE, imagesTab); |
| assertConsoleSuccess(); |
| |
| // Import resource folder |
| importProject(PATH_TEST_COMPOSE); |
| |
| // Run Docker Compose |
| runDockerCompose(PROJECT_TEST_COMPOSE, FILE_DOCKER_COMPOSE); |
| |
| // Check if application is running |
| BrowserView browserView = new BrowserView(); |
| browserView.open(); |
| //Skip browser contents check, if mockito is used |
| if (!mockitoIsUsed()) { |
| browserView.openPageURL(URL); |
| BrowserContentsCheck.checkBrowserForErrorPage(browserView, URL); |
| } |
| |
| } |
| |
| private void runDockerCompose(String project, String projectFile) { |
| PackageExplorer pe = new PackageExplorer(); |
| pe.open(); |
| pe.getProject(project).getProjectItem(projectFile).select(); |
| @SuppressWarnings("unchecked") |
| Menu contextMenu = new ContextMenu(new WithTextMatcher("Run As"), new RegexMatcher(".*Docker Compose")); |
| contextMenu.select(); |
| new OkButton().click(); |
| try { |
| new DefaultShell("Docker Compose"); |
| new OkButton().click(); |
| fail("Docker Compose has not been found! Is it installed and the path is correct?"); |
| } catch (SWTLayerException ex) { |
| } |
| new WaitWhile(new JobIsRunning(), TimePeriod.VERY_LONG); |
| new WaitWhile(new ConsoleHasNoChange()); |
| } |
| |
| private void importProject(String path) { |
| new ShellMenu("File", "Open Projects from File System...").select(); |
| new LabeledCombo("Import source:").setText(path); |
| new FinishButton().click(); |
| new WaitWhile(new JobIsRunning()); |
| } |
| |
| private void setupDockerComposeUpMockProcess(final ProcessLauncher mockProcessLauncher) |
| throws DockerException, InterruptedException { |
| final Process mockDockerComposeUpProcess = Mockito.mock(Process.class); |
| Mockito.when(mockDockerComposeUpProcess.getInputStream()) |
| .thenReturn(new ByteArrayInputStream("up!\n".getBytes())); |
| Mockito.when(mockDockerComposeUpProcess.getErrorStream()).thenReturn(new ByteArrayInputStream("".getBytes())); |
| Mockito.when(mockDockerComposeUpProcess.getOutputStream()).thenReturn(new ByteArrayOutputStream()); |
| Mockito.when(mockProcessLauncher.processBuilder(Matchers.anyString(), |
| Matchers.eq(DockerCompose.getDockerComposeCommandName()), CustomMatchers.arrayContains("up")) |
| .workingDir(Matchers.anyString()).start()).thenReturn(mockDockerComposeUpProcess); |
| latch = new CountDownLatch(1); |
| Mockito.when(mockDockerComposeUpProcess.waitFor()).then(new Answer<Object>() { |
| |
| @Override |
| public Object answer(InvocationOnMock invocation) throws Throwable { |
| latch.await(5, TimeUnit.SECONDS); |
| return 0; |
| } |
| }); |
| } |
| |
| private void setupDockerComposeStopMockProcess(final ProcessLauncher mockProcessLauncher) |
| throws DockerException, InterruptedException { |
| final Process mockDockerComposeStopProcess = Mockito.mock(Process.class); |
| Mockito.when(mockDockerComposeStopProcess.getInputStream()) |
| .thenReturn(new ByteArrayInputStream("stop\n".getBytes())); |
| Mockito.when(mockDockerComposeStopProcess.getErrorStream()).thenReturn(new ByteArrayInputStream("".getBytes())); |
| Mockito.when(mockDockerComposeStopProcess.getOutputStream()).thenReturn(new ByteArrayOutputStream()); |
| |
| Mockito.when(mockProcessLauncher.processBuilder(Matchers.anyString(), |
| Matchers.eq(DockerCompose.getDockerComposeCommandName()), CustomMatchers.arrayContains("stop")) |
| .workingDir(Matchers.anyString()).start()).thenReturn(mockDockerComposeStopProcess); |
| Mockito.when(mockDockerComposeStopProcess.waitFor()).then(invocation -> { |
| latch.countDown(); |
| return 0; |
| }); |
| } |
| |
| @After |
| public void after() { |
| deleteImageContainerAfter("testcompose_web_1", "testcompose_redis_1", "testcompose_web", "test_compose", |
| "python:2.7", "redis"); |
| cleanUpWorkspace(); |
| } |
| |
| } |