From 1eceaebe75b9038dc98b61b422136a29d9cb9e26 Mon Sep 17 00:00:00 2001 From: Alexander Garagatyi Date: Fri, 9 Dec 2016 14:53:03 +0200 Subject: [PATCH] CODENVY-1271: fix agent launching in some cases Fix AbstractAgentLauncher. Code cleanup. Signed-off-by: Alexander Garagatyi --- .../che/api/core/util/CommandLine.java | 2 - exec-agent/pom.xml | 2 +- .../che/plugin/docker/client/LogMessage.java | 2 +- .../plugin/docker/machine/DockerInstance.java | 4 +- .../plugin/docker/machine/DockerProcess.java | 2 +- .../docker/machine/local/LocalDockerNode.java | 20 +- .../LocalWorkspaceFolderPathProvider.java | 1 + .../docker/machine/node/DockerNode.java | 13 +- .../machine/MachineProviderImplTest.java | 1 - wsmaster/che-core-api-agent/pom.xml | 5 + .../launcher/AbstractAgentLauncher.java | 19 +- .../launcher/AbstractAgentLauncherTest.java | 275 ++++++++++++++++++ .../src/test/resources/config.sh | 15 - .../src/test/resources/lib.sh | 104 ------- .../src/test/resources/logback-test.xml | 25 ++ .../src/test/resources/test.sh | 94 ------ .../api/machine/server/spi/InstanceNode.java | 5 - 17 files changed, 336 insertions(+), 253 deletions(-) create mode 100644 wsmaster/che-core-api-agent/src/test/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncherTest.java delete mode 100755 wsmaster/che-core-api-agent/src/test/resources/config.sh delete mode 100755 wsmaster/che-core-api-agent/src/test/resources/lib.sh create mode 100644 wsmaster/che-core-api-agent/src/test/resources/logback-test.xml delete mode 100755 wsmaster/che-core-api-agent/src/test/resources/test.sh diff --git a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/util/CommandLine.java b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/util/CommandLine.java index f6d16b4171..ccaf609d19 100644 --- a/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/util/CommandLine.java +++ b/core/che-core-api-core/src/main/java/org/eclipse/che/api/core/util/CommandLine.java @@ -127,14 +127,12 @@ public class CommandLine { public String toString() { final String[] str = asArray(); final StringBuilder sb = new StringBuilder(); -// sb.append('\''); for (String s : str) { if (sb.length() > 1) { sb.append(' '); } sb.append(s); } -// sb.append('\''); return sb.toString(); } } diff --git a/exec-agent/pom.xml b/exec-agent/pom.xml index b0be215532..d648c94234 100644 --- a/exec-agent/pom.xml +++ b/exec-agent/pom.xml @@ -200,7 +200,7 @@ - + diff --git a/plugins/plugin-docker/che-plugin-docker-client/src/main/java/org/eclipse/che/plugin/docker/client/LogMessage.java b/plugins/plugin-docker/che-plugin-docker-client/src/main/java/org/eclipse/che/plugin/docker/client/LogMessage.java index c603db3bac..d8fa1e5637 100644 --- a/plugins/plugin-docker/che-plugin-docker-client/src/main/java/org/eclipse/che/plugin/docker/client/LogMessage.java +++ b/plugins/plugin-docker/che-plugin-docker-client/src/main/java/org/eclipse/che/plugin/docker/client/LogMessage.java @@ -24,7 +24,7 @@ public class LogMessage { private final Type type; private final String content; - LogMessage(Type type, String content) { + public LogMessage(Type type, String content) { this.type = type; this.content = content; } diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerInstance.java b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerInstance.java index f09fdcb7e5..975d7a77e3 100644 --- a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerInstance.java +++ b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerInstance.java @@ -14,6 +14,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.inject.assistedinject.Assisted; import org.eclipse.che.api.core.NotFoundException; +import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.model.machine.Command; import org.eclipse.che.api.core.model.machine.Machine; import org.eclipse.che.api.core.model.machine.MachineSource; @@ -285,7 +286,8 @@ public class DockerInstance extends AbstractInstance { docker.removeContainer(RemoveContainerParams.create(container) .withRemoveVolumes(true) .withForce(true)); - } catch (IOException e) { + } catch (IOException | ServerException e) { + LOG.error(e.getLocalizedMessage(), e); throw new MachineException(e.getLocalizedMessage()); } diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerProcess.java b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerProcess.java index e4e5be5793..ecb893dcd0 100644 --- a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerProcess.java +++ b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerProcess.java @@ -94,6 +94,7 @@ public class DockerProcess extends AbstractMachineProcess implements InstancePro if (started) { throw new ConflictException("Process already started."); } + started = true; // Trap is invoked when bash session ends. Here we kill all sub-processes of shell and remove pid-file. final String trap = format("trap '[ -z \"$(jobs -p)\" ] || kill $(jobs -p); [ -e %1$s ] && rm %1$s' EXIT", pidFilePath); // 'echo' saves shell pid in file, then run command @@ -106,7 +107,6 @@ public class DockerProcess extends AbstractMachineProcess implements InstancePro throw new MachineException(format("Error occurs while initializing command %s in docker container %s: %s", Arrays.toString(command), container, e.getMessage()), e); } - started = true; try { docker.startExec(StartExecParams.create(exec.getId()), output == null ? null : new LogMessagePrinter(output)); } catch (IOException e) { diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/LocalDockerNode.java b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/LocalDockerNode.java index 30a742ddf1..2d74d633fc 100644 --- a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/LocalDockerNode.java +++ b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/LocalDockerNode.java @@ -12,7 +12,7 @@ package org.eclipse.che.plugin.docker.machine.local; import com.google.inject.assistedinject.Assisted; -import org.eclipse.che.api.machine.server.exception.MachineException; +import org.eclipse.che.api.core.ServerException; import org.eclipse.che.plugin.docker.client.DockerConnectorConfiguration; import org.eclipse.che.plugin.docker.machine.node.DockerNode; import org.eclipse.che.plugin.docker.machine.node.WorkspaceFolderPathProvider; @@ -29,7 +29,6 @@ import java.io.IOException; */ public class LocalDockerNode implements DockerNode { - private final String workspaceFolder; private final String host; @Inject @@ -37,25 +36,16 @@ public class LocalDockerNode implements DockerNode { WorkspaceFolderPathProvider workspaceFolderNodePathProvider, DockerConnectorConfiguration dockerConnectorConfiguration) throws IOException { - workspaceFolder = workspaceFolderNodePathProvider.getPath(workspaceId); + // TODO investigate whether we can remove that after abandonment of native Che + workspaceFolderNodePathProvider.getPath(workspaceId); host = dockerConnectorConfiguration.getDockerHost(); } @Override - public void bindWorkspace() throws MachineException { - - } + public void bindWorkspace() throws ServerException {} @Override - public void unbindWorkspace() throws MachineException { - - } - - @Override - public String getProjectsFolder() { - return workspaceFolder; - } - + public void unbindWorkspace() throws ServerException {} @Override public String getHost() { diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/node/provider/LocalWorkspaceFolderPathProvider.java b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/node/provider/LocalWorkspaceFolderPathProvider.java index 1316a94f89..33a82e9340 100644 --- a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/node/provider/LocalWorkspaceFolderPathProvider.java +++ b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/local/node/provider/LocalWorkspaceFolderPathProvider.java @@ -189,6 +189,7 @@ public class LocalWorkspaceFolderPathProvider implements WorkspaceFolderPathProv } } else { try { + // TODO we should not create folders in this provider Files.createDirectories(folder); } catch (AccessDeniedException e) { throw new IOException( diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/node/DockerNode.java b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/node/DockerNode.java index aa8f843684..fc547fda72 100644 --- a/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/node/DockerNode.java +++ b/plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/node/DockerNode.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.che.plugin.docker.machine.node; -import org.eclipse.che.api.machine.server.exception.MachineException; +import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.machine.server.spi.InstanceNode; /** @@ -22,21 +22,18 @@ public interface DockerNode extends InstanceNode { /** * Bind the whole workspace on the Node. * - * @throws MachineException + * @throws ServerException * if error occurs on binding */ - void bindWorkspace() throws MachineException; + void bindWorkspace() throws ServerException; /** * Unbind the workspace on Node. * - * @throws MachineException + * @throws ServerException * if error occurs on binding */ - void unbindWorkspace() throws MachineException; - - @Override - String getProjectsFolder(); + void unbindWorkspace() throws ServerException; @Override String getHost(); diff --git a/plugins/plugin-docker/che-plugin-docker-machine/src/test/java/org/eclipse/che/plugin/docker/machine/MachineProviderImplTest.java b/plugins/plugin-docker/che-plugin-docker-machine/src/test/java/org/eclipse/che/plugin/docker/machine/MachineProviderImplTest.java index b0e07c0589..6d64de0ed5 100644 --- a/plugins/plugin-docker/che-plugin-docker-machine/src/test/java/org/eclipse/che/plugin/docker/machine/MachineProviderImplTest.java +++ b/plugins/plugin-docker/che-plugin-docker-machine/src/test/java/org/eclipse/che/plugin/docker/machine/MachineProviderImplTest.java @@ -121,7 +121,6 @@ public class MachineProviderImplTest { @BeforeMethod public void setUp() throws Exception { when(dockerConnectorConfiguration.getDockerHostIp()).thenReturn("123.123.123.123"); - when(dockerNode.getProjectsFolder()).thenReturn("/tmp/projects"); provider = spy(new MachineProviderBuilder().build()); diff --git a/wsmaster/che-core-api-agent/pom.xml b/wsmaster/che-core-api-agent/pom.xml index 3142202ac6..6d0e9ec302 100644 --- a/wsmaster/che-core-api-agent/pom.xml +++ b/wsmaster/che-core-api-agent/pom.xml @@ -90,6 +90,11 @@ org.slf4j slf4j-api + + ch.qos.logback + logback-classic + test + org.everrest everrest-assured diff --git a/wsmaster/che-core-api-agent/src/main/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncher.java b/wsmaster/che-core-api-agent/src/main/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncher.java index e3429025a9..6f0ebb5809 100644 --- a/wsmaster/che-core-api-agent/src/main/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncher.java +++ b/wsmaster/che-core-api-agent/src/main/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncher.java @@ -18,16 +18,17 @@ import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.core.model.machine.Command; import org.eclipse.che.api.core.util.AbstractLineConsumer; import org.eclipse.che.api.core.util.LineConsumer; -import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler; import org.eclipse.che.api.machine.server.exception.MachineException; import org.eclipse.che.api.machine.server.model.impl.CommandImpl; import org.eclipse.che.api.machine.server.spi.Instance; import org.eclipse.che.api.machine.server.spi.InstanceProcess; +import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler; import org.eclipse.che.commons.lang.concurrent.ThreadLocalPropagateContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -97,18 +98,20 @@ public abstract class AbstractAgentLauncher implements AgentLauncher { } - protected InstanceProcess start(final Instance machine, final Agent agent) throws ServerException { - final Command command = new CommandImpl(agent.getId(), agent.getScript(), "agent"); - final InstanceProcess process = machine.createProcess(command, null); - final LineConsumer lineConsumer = new AbstractLineConsumer() { + protected InstanceProcess start(Instance machine, Agent agent) throws ServerException { + Command command = new CommandImpl(agent.getId(), agent.getScript(), "agent"); + InstanceProcess process = machine.createProcess(command, null); + LineConsumer lineConsumer = new AbstractLineConsumer() { @Override public void writeLine(String line) throws IOException { machine.getLogger().writeLine(line); } }; + CountDownLatch countDownLatch = new CountDownLatch(1); executor.execute(ThreadLocalPropagateContext.wrap(() -> { try { + countDownLatch.countDown(); process.start(lineConsumer); } catch (ConflictException | MachineException e) { try { @@ -122,6 +125,12 @@ public abstract class AbstractAgentLauncher implements AgentLauncher { } } })); + try { + // ensure that code inside of task submitted to executor is called before end of this method + countDownLatch.await(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } return process; } diff --git a/wsmaster/che-core-api-agent/src/test/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncherTest.java b/wsmaster/che-core-api-agent/src/test/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncherTest.java new file mode 100644 index 0000000000..4b16cce05d --- /dev/null +++ b/wsmaster/che-core-api-agent/src/test/java/org/eclipse/che/api/agent/server/launcher/AbstractAgentLauncherTest.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * Copyright (c) 2012-2016 Codenvy, S.A. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Codenvy, S.A. - initial API and implementation + *******************************************************************************/ +package org.eclipse.che.api.agent.server.launcher; + +import org.eclipse.che.api.agent.shared.model.Agent; +import org.eclipse.che.api.core.ServerException; +import org.eclipse.che.api.machine.server.exception.MachineException; +import org.eclipse.che.api.machine.server.model.impl.CommandImpl; +import org.eclipse.che.api.machine.server.spi.Instance; +import org.eclipse.che.api.machine.server.spi.InstanceProcess; +import org.mockito.Mock; +import org.mockito.stubbing.Answer; +import org.mockito.testng.MockitoTestNGListener; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +import java.util.ArrayList; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertTrue; + +/** + * @author Alexander Garagatyi + */ +@Listeners(MockitoTestNGListener.class) +public class AbstractAgentLauncherTest { + @Mock + private Instance machine; + @Mock + private Agent agent; + @Mock + private InstanceProcess process; + @Mock + private AgentLaunchingChecker agentChecker; + + private AbstractAgentLauncher launcher; + + @BeforeMethod + public void setUp() throws Exception { + launcher = spy(new TestAgentLauncher(500, 100, agentChecker)); + + when(agent.getScript()).thenReturn("script content"); + doReturn(process).when(launcher).start(any(Instance.class), any(Agent.class)); + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))).thenReturn(true); + } + + @Test + public void shouldBeAbleToCheckAgentState() throws Exception { + // when + launcher.launch(machine, agent); + + // then + verify(agentChecker).isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class)); + } + + @Test + public void doNothingIfAgentScriptIsNull() throws Exception { + // given + when(agent.getScript()).thenReturn(null); + + // when + launcher.launch(machine, agent); + + // then + verify(launcher, never()).start(any(Instance.class), any(Agent.class)); + verify(agent).getScript(); + verifyNoMoreInteractions(agent); + verifyZeroInteractions(machine); + } + + @Test + public void doNothingIfAgentScriptIsEmpty() throws Exception { + // given + when(agent.getScript()).thenReturn(""); + + // when + launcher.launch(machine, agent); + + // then + verify(launcher, never()).start(any(Instance.class), any(Agent.class)); + verify(agent).getScript(); + verifyNoMoreInteractions(agent); + verifyZeroInteractions(machine); + } + + @Test + public void shouldCheckIfAgentIsLaunchedUntilItIsLaunched() throws Exception { + // given + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))).thenReturn(false) + .thenReturn(false) + .thenReturn(false) + .thenReturn(false) + .thenReturn(true); + + // when + launcher.launch(machine, agent); + + // then + verify(agentChecker, times(5)).isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class)); + } + + @Test(expectedExceptions = ServerException.class, expectedExceptionsMessageRegExp = "Fail launching agent .*. Workspace ID:.*") + public void shouldNotCheckIfAgentIsLaunchedMoreThanAgentMaxStartTime() throws Exception { + // given + launcher = spy(new TestAgentLauncher(200, 100, agentChecker)); + doReturn(process).when(launcher).start(any(Instance.class), any(Agent.class)); + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))).thenReturn(false) + .thenReturn(false) + .thenReturn(false) + .thenReturn(false) + .thenReturn(true); + + // when + launcher.launch(machine, agent); + + // then + // ensure that isLaunched was called several times and then max pinging time was exceeded + verify(agentChecker, atLeast(2)).isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class)); + } + + @Test + public void shouldNotCheckMoreFrequentThanAgentCheckDelay() throws Exception { + // given + launcher = spy(new TestAgentLauncher(200, 10, agentChecker)); + doReturn(process).when(launcher).start(any(Instance.class), any(Agent.class)); + // record time of each check of agent state + ArrayList checkTimestamps = new ArrayList<>(5); + Answer recordTimestampAndReturnFalse = invocationOnMock -> { + checkTimestamps.add(System.currentTimeMillis()); + return false; + }; + Answer recordTimestampAndReturnTrue = invocationOnMock -> { + checkTimestamps.add(System.currentTimeMillis()); + return true; + }; + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))).thenAnswer(recordTimestampAndReturnFalse) + .thenAnswer(recordTimestampAndReturnFalse) + .thenAnswer(recordTimestampAndReturnFalse) + .thenAnswer(recordTimestampAndReturnFalse) + .thenAnswer(recordTimestampAndReturnTrue); + + // when + launcher.launch(machine, agent); + + // then + // ensure that each check was done after required timeout + for (int i = 1; i < checkTimestamps.size(); i++) { + assertTrue(checkTimestamps.get(i) - checkTimestamps.get(i - 1) >= 10); + } + } + + @Test(expectedExceptions = ServerException.class, expectedExceptionsMessageRegExp = "agent launcher test exception") + public void shouldThrowServerExceptionIfMachineExceptionIsThrownByAgentCheck() throws Exception { + // given + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))) + .thenThrow(new MachineException("agent launcher test exception")); + + // when + launcher.launch(machine, agent); + } + + @Test + public void shouldSetBackInterruptedFlagIfThreadWasInterrupted() throws Exception { + try { + // imitate interruption of launching thread + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))).thenAnswer(invocationOnMock -> { + Thread.currentThread().interrupt(); + return false; + }); + + // when + launcher.launch(machine, agent); + } catch (ServerException e) { + // Ensure that after exiting launcher thread is still in interrupted state + assertTrue(Thread.currentThread().isInterrupted()); + } finally { + // cleanup interrupted state + Thread.interrupted(); + } + } + + @Test(expectedExceptions = ServerException.class, expectedExceptionsMessageRegExp = "Launching agent .* is interrupted") + public void shouldThrowServerExceptionIfAgentCheckWasInterrupted() throws Exception { + try { + when(agentChecker.isLaunched(any(Agent.class), + any(InstanceProcess.class), + any(Instance.class))).thenAnswer(invocationOnMock -> { + Thread.currentThread().interrupt(); + return false; + }); + + // when + launcher.launch(machine, agent); + } finally { + // cleanup interrupted state + Thread.interrupted(); + } + } + + @Test + public void shouldStartMachineProcessWithAgentScriptExecution() throws Exception { + // given + String agentId = "testAgentId"; + String agentScript = "testAgentScript"; + when(agent.getId()).thenReturn(agentId); + when(agent.getScript()).thenReturn(agentScript); + when(launcher.start(any(Instance.class), any(Agent.class))).thenCallRealMethod(); + + // when + launcher.launch(machine, agent); + + // then + verify(machine).createProcess(eq(new CommandImpl(agentId, agentScript, "agent")), eq(null)); + } + + private static class TestAgentLauncher extends AbstractAgentLauncher { + public TestAgentLauncher(long agentMaxStartTimeMs, + long agentPingDelayMs, + AgentLaunchingChecker agentLaunchingChecker) { + super(agentMaxStartTimeMs, agentPingDelayMs, agentLaunchingChecker); + } + + @Override + protected InstanceProcess start(Instance machine, Agent agent) throws ServerException { + return super.start(machine, agent); + } + + @Override + public String getAgentId() { + return "testAgentId"; + } + + @Override + public String getMachineType() { + return "testMachineType"; + } + } +} diff --git a/wsmaster/che-core-api-agent/src/test/resources/config.sh b/wsmaster/che-core-api-agent/src/test/resources/config.sh deleted file mode 100755 index 0e9ecbfa00..0000000000 --- a/wsmaster/che-core-api-agent/src/test/resources/config.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2012-2016 Codenvy, S.A. -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Codenvy, S.A. - initial API and implementation -# - -CHE_PATH=/home/tolusha/java/env-projects/che/assembly/assembly-main/target/eclipse-che-4.8.0-SNAPSHOT/eclipse-che-4.8.0-SNAPSHOT/bin -HOST_URL=localhost:8080 -TEST_LOG="agents-test.log" diff --git a/wsmaster/che-core-api-agent/src/test/resources/lib.sh b/wsmaster/che-core-api-agent/src/test/resources/lib.sh deleted file mode 100755 index bb9e2c2f49..0000000000 --- a/wsmaster/che-core-api-agent/src/test/resources/lib.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2012-2016 Codenvy, S.A. -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Codenvy, S.A. - initial API and implementation -# - -. ./config.sh - -trap cleanUp EXIT - -cleanUp() { - ${CHE_PATH}/che.sh stop -} - -printAndLog() { - echo $@ - log $@ -} - -logStartCommand() { - log - log "=== [ "`date`" ] COMMAND STARTED: "$@ -} - -logEndCommand() { - log "=================================== COMMAND COMPLETED: "$@ - log -} - -log() { - echo "TEST: "$@ >> ${TEST_LOG} -} - -fetchJsonParameter() { - OUTPUT=`echo ${OUTPUT} | sed 's/.*"'$1'"\s*:\s*"\([^"]*\)*".*/\1/'` -} - -# --method={POST|GET|...} -# --content-type=... -# --cookie=... -# --body=... -# --url=... -# --output-http-code -# --verbose -doHttpRequest() { - for var in "$@"; do - if [[ "$var" =~ --content-type=.+ ]]; then - CONTENT_TYPE_OPTION=`echo "-H \"Content-Type: $var\"" | sed -e "s/--content-type=//g"` - - elif [[ "$var" =~ --body=.+ ]]; then - local BODY_OPTION=`echo "-d '$var'" | sed -e "s/--body=//g"` - - elif [[ "$var" =~ --url=.+ ]]; then - local URL=`echo "'$var'" | sed -e "s/--url=//g"` - - elif [[ "$var" =~ --method=.+ ]]; then - local METHOD_OPTION=`echo "-X $var" | sed -e "s/--method=//g"` - - elif [[ "$var" == "--output-http-code" ]]; then - local OUTPUT_HTTP_CODE_OPTION="-o /dev/null -w \"%{http_code}\"" - - elif [[ "$var" == "--verbose" ]]; then - local VERBOSE_OPTION="-v" - - elif [[ "$var" =~ --cookie=.+ ]]; then - local COOKIE_OPTION=$(echo "-H \"Cookie: session-access-key=$var\"" | sed -e "s/--cookie=//g") - - fi - done - - local COMMAND="curl -s $VERBOSE_OPTION $OUTPUT_HTTP_CODE_OPTION $CONTENT_TYPE_OPTION $COOKIE_OPTION $BODY_OPTION $METHOD_OPTION $URL" - - logStartCommand $COMMAND - - OUTPUT=$(eval $COMMAND) - EXIT_CODE=$? - log ${OUTPUT} - - logEndCommand "curl" -} - -doPost() { - doHttpRequest --method=POST \ - --content-type=$1 \ - --body="$2" \ - --url=$3 \ - --cookie=$4 -} - -doGet() { - doHttpRequest --method=GET \ - --url=$1 -} - -doDelete() { - doHttpRequest --method=DELETE \ - --url=$1 -} diff --git a/wsmaster/che-core-api-agent/src/test/resources/logback-test.xml b/wsmaster/che-core-api-agent/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..540c86b747 --- /dev/null +++ b/wsmaster/che-core-api-agent/src/test/resources/logback-test.xml @@ -0,0 +1,25 @@ + + + + + + + %-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n + + + + + + + diff --git a/wsmaster/che-core-api-agent/src/test/resources/test.sh b/wsmaster/che-core-api-agent/src/test/resources/test.sh deleted file mode 100755 index e48b5d496f..0000000000 --- a/wsmaster/che-core-api-agent/src/test/resources/test.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash -# -# Copyright (c) 2012-2016 Codenvy, S.A. -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -# Contributors: -# Codenvy, S.A. - initial API and implementation -# - -. ./lib.sh - - -${CHE_PATH}/che.sh --debug start -sleep 20s - -DOCKER_CONTENT=("FROM fedora:23\nCMD tail -f /dev/null" - "FROM ubuntu:16.04\nCMD tail -f /dev/null" - "FROM ubuntu:14.04\nCMD tail -f /dev/null" - "FROM centos:7\nCMD tail -f /dev/null" - "FROM opensuse:13.2\nCMD tail -f /dev/null" - "FROM debian:8\nCMD tail -f /dev/null"); - -waitStatus() { - WORKSPACE_ID=$1 - STATUS=$2 - ATTEMPTS=200 - - for ((j = 0; j < ${ATTEMPTS}; j++)) - do - doGet "http://"${HOST_URL}"/api/workspace/"${WORKSPACE_ID} - if echo ${OUTPUT} | grep -qi "\"id\":\"${WORKSPACE_ID}\",\"status\":\"${STATUS}\""; then - echo ${STATUS} - break - fi - sleep 5s - done -} - -validateRunningProcess() { - WORKSPACE_ID=$1 - PROCESS=$2 - - CONTAINER_ID=$(docker ps -aqf "name="${WORKSPACE_ID}) - printAndLog "Container ID "${CONTAINER_ID}" validate "${PROCESS} - - PID=$(docker exec -ti ${CONTAINER_ID} ps -fC ${PROCESS}) - if [ "${PID}" = "" ]; then - printAndLog "RESULT: FAILED. Process "${PROCESS}" not found" - fi -} - -deleteWorkspace() { - WORKSPACE_ID=$1 - - doDelete "http://"${HOST_URL}"/api/workspace/"${WORKSPACE_ID}"/runtime" - STATUS=$(waitStatus ${WORKSPACE_ID} "STOPPED") - if echo ${STATUS} | grep -qi "STOPPED"; then - doDelete "http://"${HOST_URL}"/api/workspace/"${WORKSPACE_ID} - sleep 1m - else - printAndLog "ERROR. Workspace "${WORKSPACE_ID}" can't be stopped" - fi -} - -for ((i = 0; i < ${#DOCKER_CONTENT[@]}; i++)) -do - CONTENT="${DOCKER_CONTENT[$i]}" - printAndLog - printAndLog "####################################################################" - printAndLog "Creating workspace with recipe: \""${CONTENT}"\"" - printAndLog "####################################################################" - - NAME=$(date +%s | sha256sum | base64 | head -c 5) - doPost "application/json" "{\"name\":\"${NAME}\",\"projects\":[],\"defaultEnv\":\"${NAME}\",\"description\":null,\"environments\":[{\"name\":\"${NAME}\",\"recipe\":null,\"machineConfigs\":[{\"name\":\"ws-machine\",\"limits\":{\"ram\":1000},\"type\":\"docker\",\"source\":{\"type\":\"dockerfile\",\"content\":\"${CONTENT}\"},\"dev\":true}]}]}" "http://"${HOST_URL}"/api/workspace?account=" - fetchJsonParameter "id" - WORKSPACE_ID=${OUTPUT} - - printAndLog "Starting workspace: "${WORKSPACE_ID} - doPost "application/json" "{}" "http://"${HOST_URL}"/api/workspace/"${WORKSPACE_ID}"/runtime?environment="${NAME} - - STATUS=$(waitStatus ${WORKSPACE_ID} "RUNNING") - if echo ${STATUS} | grep -qi "RUNNING"; then - validateRunningProcess ${WORKSPACE_ID} "che-websocket-terminal" - validateRunningProcess ${WORKSPACE_ID} "java" - validateRunningProcess ${WORKSPACE_ID} "sshd" - else - printAndLog "RESULT: FAILED. Workspace not started." - fi - - deleteWorkspace ${WORKSPACE_ID} -done diff --git a/wsmaster/che-core-api-machine/src/main/java/org/eclipse/che/api/machine/server/spi/InstanceNode.java b/wsmaster/che-core-api-machine/src/main/java/org/eclipse/che/api/machine/server/spi/InstanceNode.java index 6efe47f28d..e28ba9a710 100644 --- a/wsmaster/che-core-api-machine/src/main/java/org/eclipse/che/api/machine/server/spi/InstanceNode.java +++ b/wsmaster/che-core-api-machine/src/main/java/org/eclipse/che/api/machine/server/spi/InstanceNode.java @@ -16,11 +16,6 @@ package org.eclipse.che.api.machine.server.spi; * @author Alexander Garagatyi */ public interface InstanceNode { - /** - * Get path of folder on machine node with workspace fs - */ - String getProjectsFolder(); - /** * Host of the server where machine is launched */