ContainerOperationsImpl implements ContainerOperations { ProcessResult executeNodeCtlInContainer(NodeAgentContext context, String program) { String[] command = new String[] {context.pathInNodeUnderVespaHome("bin/vespa-nodectl").toString(), program}; ProcessResult result = executeCommandInContainerAsRoot(context, command); if (!result.isSuccess()) { throw new RuntimeException("Container " + context.containerName().asString() + ": command " + Arrays.toString(command) + " failed: " + result); } return result; } ContainerOperationsImpl(ContainerEngine containerEngine, Terminal terminal, IPAddresses ipAddresses, FileSystem fileSystem); @Override void createContainer(NodeAgentContext context, ContainerData containerData, ContainerResources containerResources); @Override void startContainer(NodeAgentContext context); @Override void removeContainer(NodeAgentContext context, Container container); @Override void updateContainer(NodeAgentContext context, ContainerResources containerResources); @Override Optional<Container> getContainer(NodeAgentContext context); @Override boolean pullImageAsyncIfNeeded(DockerImage dockerImage); @Override ProcessResult executeCommandInContainerAsRoot(NodeAgentContext context, Long timeoutSeconds, String... command); @Override ProcessResult executeCommandInContainerAsRoot(NodeAgentContext context, String... command); @Override CommandResult executeCommandInNetworkNamespace(NodeAgentContext context, String... command); @Override void resumeNode(NodeAgentContext context); @Override void suspendNode(NodeAgentContext context); @Override void restartVespa(NodeAgentContext context); @Override void startServices(NodeAgentContext context); @Override void stopServices(NodeAgentContext context); @Override Optional<ContainerStats> getContainerStats(NodeAgentContext context); @Override boolean noManagedContainersRunning(); @Override boolean deleteUnusedContainerImages(List<DockerImage> excludes, Duration minImageAgeToDelete);  }
@Test public void processResultFromNodeProgramWhenSuccess() { final NodeAgentContext context = new NodeAgentContextImpl.Builder("container-123.domain.tld").build(); final ProcessResult actualResult = new ProcessResult(0, "output", "errors"); when(containerEngine.executeInContainerAsUser(any(), any(), any(), any())) .thenReturn(actualResult); ProcessResult result = dockerOperations.executeNodeCtlInContainer(context, "start"); final InOrder inOrder = inOrder(containerEngine); inOrder.verify(containerEngine, times(1)).executeInContainerAsUser( eq(context.containerName()), eq("root"), eq(OptionalLong.empty()), eq("/opt/vespa/bin/vespa-nodectl"), eq("start")); assertThat(result, is(actualResult)); }
@Test(expected = RuntimeException.class) public void processResultFromNodeProgramWhenNonZeroExitCode() { final NodeAgentContext context = new NodeAgentContextImpl.Builder("container-123.domain.tld").build(); final ProcessResult actualResult = new ProcessResult(3, "output", "errors"); when(containerEngine.executeInContainerAsUser(any(), any(), any(), any())) .thenReturn(actualResult); dockerOperations.executeNodeCtlInContainer(context, "start"); }