/*******************************************************************************
* Copyright (c) 2012-2017 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.environment.server;
import org.eclipse.che.api.core.jsonrpc.commons.RequestTransmitter;
import org.eclipse.che.api.core.model.machine.Command;
import org.eclipse.che.api.core.notification.EventService;
import org.eclipse.che.api.core.util.JsonRpcEndpointIdsHolder;
import org.eclipse.che.api.core.util.LineConsumer;
import org.eclipse.che.api.machine.server.spi.Instance;
import org.eclipse.che.api.machine.server.spi.InstanceProcess;
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.lang.IoUtil;
import org.eclipse.che.commons.subject.SubjectImpl;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ThreadPoolExecutor;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertNotNull;
/**
* Unit tests for {@link MachineProcessManager}
*
* @author Anton Korneta
* @author Alexander Garagatyi
*/
@Listeners(MockitoTestNGListener.class)
public class MachineProcessManagerTest {
private static final String USER_ID = "userId";
private static final String MACHINE_ID = "machineId";
private static final String WORKSPACE_ID = "testWorkspaceId";
private static final SubjectImpl CREATOR = new SubjectImpl("name", USER_ID, "token", false);
@Mock
Instance instance;
@Mock
Command command;
@Mock
InstanceProcess instanceProcess;
@Mock
LineConsumer logConsumer;
@Mock
CheEnvironmentEngine environmentEngine;
@Mock
RequestTransmitter transmitter;
@Mock
JsonRpcEndpointIdsHolder endpointIdsHolder;
private MachineProcessManager manager;
@BeforeMethod
public void setUp() throws Exception {
final EventService eventService = mock(EventService.class);
final String machineLogsDir = targetDir().resolve("logs-dir").toString();
IoUtil.deleteRecursive(new File(machineLogsDir));
manager = spy(new MachineProcessManager(machineLogsDir,
eventService,
environmentEngine,
transmitter,
endpointIdsHolder));
EnvironmentContext envCont = new EnvironmentContext();
envCont.setSubject(CREATOR);
EnvironmentContext.setCurrent(envCont);
doReturn(logConsumer).when(manager).getProcessLogger(MACHINE_ID, 111, "outputChannel");
when(command.getCommandLine()).thenReturn("CommandLine");
when(command.getName()).thenReturn("CommandName");
when(command.getType()).thenReturn("CommandType");
when(instance.createProcess(command, "outputChannel")).thenReturn(instanceProcess);
when(instanceProcess.getPid()).thenReturn(111);
when(environmentEngine.getMachine(WORKSPACE_ID, MACHINE_ID)).thenReturn(instance);
}
@AfterMethod
public void tearDown() throws Exception {
EnvironmentContext.reset();
}
@Test
public void shouldCloseProcessLoggerIfExecIsSuccess() throws Exception {
//when
manager.exec(WORKSPACE_ID, MACHINE_ID, command, "outputChannel");
waitForExecutorIsCompletedTask();
//then
verify(logConsumer).close();
}
@Test
public void shouldCloseProcessLoggerIfExecFails() throws Exception {
//given
doThrow(Exception.class).when(instanceProcess).start();
//when
manager.exec(WORKSPACE_ID, MACHINE_ID, command, "outputChannel");
waitForExecutorIsCompletedTask();
//then
verify(logConsumer).close();
}
private void waitForExecutorIsCompletedTask() throws Exception {
for (int i = 0; ((ThreadPoolExecutor)manager.executor).getCompletedTaskCount() == 0 && i < 10; i++) {
Thread.sleep(300);
}
}
private static Path targetDir() throws Exception {
final URL url = Thread.currentThread().getContextClassLoader().getResource(".");
assertNotNull(url);
return Paths.get(url.toURI()).getParent();
}
}