Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHE-3844: Show 'Add terminal button' in the machine node when WsAgent started. #4566

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class ProcessTreeNode {
private boolean hasTerminalAgent;
private boolean hasSSHAgent;
private boolean running;
private boolean showAddTerminalBtn;

public ProcessTreeNode(ProcessNodeType type,
ProcessTreeNode parent,
Expand Down Expand Up @@ -156,6 +157,14 @@ public void setRunning(boolean running) {
this.running = running;
}

public boolean isShowAddTerminalBtn() {
return showAddTerminalBtn;
}

public void setShowAddTerminalBtn(boolean showAddTerminalBtn) {
this.showAddTerminalBtn = showAddTerminalBtn;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import elemental.html.SpanElement;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.eclipse.che.api.core.model.machine.MachineConfig;
import org.eclipse.che.ide.api.machine.MachineEntity;
Expand All @@ -44,6 +45,7 @@
* @author Anna Shumilova
* @author Roman Nikitenko
*/
@Singleton
public class ProcessTreeRenderer implements NodeRenderer<ProcessTreeNode> {

public static final Map<String, String> LABELS = new HashMap<String, String>() {
Expand Down Expand Up @@ -141,7 +143,7 @@ private SpanElement createMachineElement(final ProcessTreeNode node) {
* New terminal button
*
***************************************************************************/
if (node.isRunning() && node.hasTerminalAgent()) {
if (node.isShowAddTerminalBtn() && node.hasTerminalAgent()) {
SpanElement newTerminalButton = Elements.createSpanElement(resources.getCss().newTerminalButton());
newTerminalButton.appendChild((Node)new SVGImage(resources.addTerminalIcon()).getElement());
root.appendChild(newTerminalButton);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.web.bindery.event.shared.EventBus;
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.MachineStatus;
import org.eclipse.che.api.core.model.machine.Server;
import org.eclipse.che.api.core.model.workspace.Environment;
import org.eclipse.che.api.core.model.workspace.ExtendedMachine;
Expand Down Expand Up @@ -866,7 +867,7 @@ private boolean hasTerminal(String machineId) {
}

/**
* Provides machine node:
* Provides machine node without "Add Terminal" button:
* <li>creates new machine node when this one not exist or {@code replace} is {@code true}</li>
* <li>returns old machine node when this one exist and {@code replace} is {@code false}</li>
*
Expand All @@ -877,6 +878,22 @@ private boolean hasTerminal(String machineId) {
* @return machine node
*/
private ProcessTreeNode provideMachineNode(@NotNull MachineEntity machine, boolean replace) {
return provideMachineNode(machine, replace, false);
}

/**
* Provides machine node:
* <li>creates new machine node when this one not exist or {@code replace} is {@code true}</li>
* <li>returns old machine node when this one exist and {@code replace} is {@code false}</li>
* <li>displays "Add terminal" button if {@param showAddTerminalBtn} is true, and hide this button otherwise.</li>
*
* @param machine
* machine to creating node
* @param replace
* existed node will be replaced when {@code replace} is {@code true}
* @return machine node
*/
private ProcessTreeNode provideMachineNode(@NotNull MachineEntity machine, boolean replace, boolean showAddTerminalBtn) {
final String machineId = machine.getId();
final ProcessTreeNode existedMachineNode = findTreeNodeById(machineId);
if (!replace && existedMachineNode != null) {
Expand All @@ -899,7 +916,8 @@ private ProcessTreeNode provideMachineNode(@NotNull MachineEntity machine, boole

// create new node
final ProcessTreeNode newMachineNode = new ProcessTreeNode(MACHINE_NODE, rootNode, machine, null, children);
newMachineNode.setRunning(true);
newMachineNode.setRunning(MachineStatus.RUNNING == machine.getStatus());
newMachineNode.setShowAddTerminalBtn(showAddTerminalBtn);
newMachineNode.setHasTerminalAgent(hasAgent(machine.getDisplayName(), TERMINAL_AGENT) || hasTerminal(machineId));
newMachineNode.setHasSSHAgent(hasAgent(machine.getDisplayName(), SSH_AGENT));
if (removedNodeChildrens != null) {
Expand Down Expand Up @@ -1007,6 +1025,7 @@ public void onWorkspaceStopped(WorkspaceStoppedEvent event) {
for (ProcessTreeNode node : rootNode.getChildren()) {
if (MACHINE_NODE == node.getType()) {
node.setRunning(false);
node.setShowAddTerminalBtn(false);

ArrayList<ProcessTreeNode> children = new ArrayList<>();
children.addAll(node.getChildren());
Expand Down Expand Up @@ -1053,6 +1072,7 @@ public void onWsAgentStarted(WsAgentStateEvent event) {
}

for (MachineEntity machine : machines) {
provideMachineNode(machine, true, true);
restoreState(machine);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,19 @@
import java.util.ArrayList;
import java.util.List;

import static java.util.Collections.singletonList;
import static org.eclipse.che.ide.extension.machine.client.processes.ProcessTreeNode.ProcessNodeType.COMMAND_NODE;
import static org.eclipse.che.ide.extension.machine.client.processes.ProcessTreeNode.ProcessNodeType.MACHINE_NODE;
import static org.eclipse.che.ide.extension.machine.client.processes.ProcessTreeNode.ProcessNodeType.ROOT_NODE;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -173,6 +176,8 @@ public void setUp() {
when(execAgentCommandManager.getProcesses(anyString(), anyBoolean())).thenReturn(promise);
when(promise.then(any(Operation.class))).thenReturn(promise);

when(appContext.getWorkspaceId()).thenReturn(WORKSPACE_ID);

presenter = new ProcessesPanelPresenter(view,
localizationConstant,
resources,
Expand All @@ -194,18 +199,17 @@ public void setUp() {

@Test
public void shouldAddMachineWhenMachineCreating() throws Exception {
MachineEntity machine = mock(MachineEntity.class);
MachineConfigDto machineConfigDto = mock(MachineConfigDto.class);
OutputConsole outputConsole = mock(OutputConsole.class);
when(machineConfigDto.getName()).thenReturn(MACHINE_NAME);
when(machine.getConfig()).thenReturn(machineConfigDto);
when(appContext.getWorkspaceId()).thenReturn(WORKSPACE_ID);
when(commandConsoleFactory.create(eq(MACHINE_NAME))).thenReturn(outputConsole);

MachineConfigDto machineConfigDto = createMachineConfig(MACHINE_NAME);
MachineEntity machine = createMachineEntity(MachineStatus.CREATING, MACHINE_NAME, machineConfigDto);

MachineStateEvent machineStateEvent = mock(MachineStateEvent.class);
when(machineStateEvent.getMachine()).thenReturn(machine);
verify(eventBus, times(9)).addHandler(anyObject(), machineStateHandlerCaptor.capture());
MachineStateEvent.Handler machineStateHandler = machineStateHandlerCaptor.getAllValues().get(0);

machineStateHandler.onMachineCreating(machineStateEvent);

verify(outputConsole).go(acceptsOneWidgetCaptor.capture());
Expand All @@ -215,6 +219,40 @@ public void shouldAddMachineWhenMachineCreating() throws Exception {
verify(commandConsoleFactory).create(eq(MACHINE_NAME));
verify(view).addWidget(anyString(), anyString(), anyObject(), anyObject(), anyBoolean());
verify(view).setProcessesData(eq(presenter.rootNode));

assertEquals(presenter.rootNode.getChildren().size(), 1);
ProcessTreeNode machineNode = presenter.rootNode.getChildren().iterator().next();
assertEquals(machineNode.isRunning(), false);
assertEquals(machineNode.isShowAddTerminalBtn(), false);
}

@Test
public void shouldUpdateMachineWhenMachineRunning() throws Exception {
OutputConsole outputConsole = mock(OutputConsole.class);
when(commandConsoleFactory.create(eq(MACHINE_NAME))).thenReturn(outputConsole);

MachineConfigDto machineConfigDto = createMachineConfig(MACHINE_NAME);
MachineEntity machine = createMachineEntity(MachineStatus.RUNNING, MACHINE_NAME, machineConfigDto);

MachineStateEvent machineStateEvent = mock(MachineStateEvent.class);
when(machineStateEvent.getMachine()).thenReturn(machine);
verify(eventBus, times(9)).addHandler(anyObject(), machineStateHandlerCaptor.capture());
MachineStateEvent.Handler machineStateHandler = machineStateHandlerCaptor.getAllValues().get(0);

machineStateHandler.onMachineRunning(machineStateEvent);

verify(outputConsole).go(acceptsOneWidgetCaptor.capture());
IsWidget widget = mock(IsWidget.class);
acceptsOneWidgetCaptor.getValue().setWidget(widget);

verify(commandConsoleFactory).create(eq(MACHINE_NAME));
verify(view).addWidget(anyString(), anyString(), anyObject(), anyObject(), anyBoolean());
verify(view).setProcessesData(eq(presenter.rootNode));

assertEquals(presenter.rootNode.getChildren().size(), 1);
ProcessTreeNode machineNode = presenter.rootNode.getChildren().iterator().next();
assertEquals(machineNode.isRunning(), true);
assertEquals(machineNode.isShowAddTerminalBtn(), false);
}

@Test
Expand Down Expand Up @@ -601,36 +639,52 @@ public void testGo() throws Exception {
}

@Test
public void commandShouldBeRestoredWhenWsAgentIsStarted() throws Exception {
public void addTerminalButtonShouldBeAddedWhenWSAgentStarted() throws Exception {
WsAgentStateEvent event = mock(WsAgentStateEvent.class);

MachineEntity machineEntity = mock(MachineEntity.class);
MachineConfigDto machineConfigDto = createMachineConfig(MACHINE_NAME);
MachineEntity machineEntity = createMachineEntity(MachineStatus.RUNNING, MACHINE_NAME, machineConfigDto);

MachineDto machine = mock(MachineDto.class);
when(machineEntity.getId()).thenReturn(MACHINE_ID);
when(machineEntity.getWorkspaceId()).thenReturn(WORKSPACE_ID);
when(entityFactory.createMachine(machine)).thenReturn(machineEntity);
MachineConfigDto machineConfigDto = mock(MachineConfigDto.class);
when(machine.getConfig()).thenReturn(machineConfigDto);
when(machineConfigDto.isDev()).thenReturn(true);
when(machine.getStatus()).thenReturn(MachineStatus.RUNNING);
List<MachineDto> machines = new ArrayList<>(2);
machines.add(machine);
when(workspaceRuntime.getMachines()).thenReturn(machines);

MachineProcessDto machineProcessDto = mock(MachineProcessDto.class);
when(machineProcessDto.getOutputChannel()).thenReturn(OUTPUT_CHANNEL);
when(machineProcessDto.getPid()).thenReturn(PID);
List<MachineProcessDto> processes = new ArrayList<>(1);
processes.add(machineProcessDto);
when(machine.getConfig()).thenReturn(machineConfigDto);

CommandOutputConsole outputConsole = mock(CommandOutputConsole.class);
when(entityFactory.createMachine(machine)).thenReturn(machineEntity);
when(workspaceRuntime.getMachines()).thenReturn(singletonList(machine));

CommandType commandType = mock(CommandType.class);
when(commandTypeRegistry.getCommandTypeById(anyString())).thenReturn(commandType);
when(commandConsoleFactory.create(anyObject(),
any(org.eclipse.che.api.core.model.machine.Machine.class))).thenReturn(outputConsole);
//machine running
MachineStateEvent machineStateEvent = mock(MachineStateEvent.class);
when(machineStateEvent.getMachine()).thenReturn(machineEntity);
presenter.onMachineRunning(machineStateEvent);
reset(view);

//ws agent started
presenter.onWsAgentStarted(event);

verify(view).setProcessesData(eq(presenter.rootNode));

assertEquals(presenter.rootNode.getChildren().size(), 1);
ProcessTreeNode machineNode = presenter.rootNode.getChildren().iterator().next();
assertEquals(machineNode.isRunning(), true);
assertEquals(machineNode.isShowAddTerminalBtn(), true);
}

private MachineEntity createMachineEntity(MachineStatus machineStatus, String machineName, MachineConfigDto machineConfigDto) {
MachineEntity machineEntity = mock(MachineEntity.class);

when(machineEntity.getConfig()).thenReturn(machineConfigDto);
when(machineEntity.getDisplayName()).thenReturn(machineName);
when(machineEntity.getId()).thenReturn(MACHINE_ID);
when(machineEntity.getStatus()).thenReturn(machineStatus);

return machineEntity;
}

private MachineConfigDto createMachineConfig(String machineName) {
MachineConfigDto machineConfigDto = mock(MachineConfigDto.class);
when(machineConfigDto.getName()).thenReturn(machineName);
when(machineConfigDto.isDev()).thenReturn(true);

return machineConfigDto;
}
}