diff options
Diffstat (limited to 'node-admin')
11 files changed, 88 insertions, 147 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java index 8e67cac5b2f..0fbd69708db 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java @@ -1,6 +1,7 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.node.admin.nodeagent; +import com.fasterxml.jackson.core.JsonProcessingException; import com.yahoo.vespa.hosted.dockerapi.Container; import com.yahoo.vespa.hosted.dockerapi.ContainerName; import com.yahoo.vespa.hosted.dockerapi.Docker; @@ -575,14 +576,20 @@ public class NodeAgentImpl implements NodeAgent { // Push metrics to the metrics proxy in each container - give it maximum 1 seconds to complete try { - //TODO The command here is almost a dummy command until we have the proper RPC method in place - // Remember proper argument encoding - dockerOperations.executeCommandInContainerAsRoot(containerName, 1L, "sh", "-c", "'echo " + metricReceiver.toString() + "'"); - } catch (DockerExecTimeoutException e) { + dockerOperations.executeCommandInContainerAsRoot(containerName, 1L, "rpc_invoke", "-t 1", "tcp/localhost:19091", "setExtraMetrics", buildRPCArgumentFromMetrics()); + } catch (DockerExecTimeoutException|JsonProcessingException e) { logger.warning("Unable to push metrics to container: " + containerName, e); } } + protected String buildRPCArgumentFromMetrics() throws JsonProcessingException { + StringBuilder params = new StringBuilder(); + for (MetricReceiverWrapper.DimensionMetrics dimensionMetrics : metricReceiver.getAllMetrics()) { + params.append(dimensionMetrics.toSecretAgentReport()); + } + return "s:'" + params.toString() + "'"; + } + @SuppressWarnings("unchecked") private void addIfNotNull(Dimensions dimensions, String yamasName, Object metrics, String metricName) { Map<String, Object> metricsMap = (Map<String, Object>) metrics; diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java index 11a01c10f1b..6041c95b565 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerFailTest.java @@ -32,14 +32,13 @@ public class DockerFailTest { Thread.sleep(10); } - CallOrderVerifier callOrderVerifier = dockerTester.getCallOrderVerifier(); - callOrderVerifier.assertInOrder( + dockerTester.callOrderVerifier.assertInOrder( "createContainerCommand with DockerImage { imageId=dockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); - dockerTester.deleteContainer(new ContainerName("host1")); + dockerTester.dockerMock.deleteContainer(new ContainerName("host1")); - callOrderVerifier.assertInOrder( + dockerTester.callOrderVerifier.assertInOrder( "deleteContainer with ContainerName { name=host1 }", "createContainerCommand with DockerImage { imageId=dockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java index 356bbe2ef58..e1ba6b89f6a 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java @@ -11,7 +11,9 @@ import java.io.File; import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @@ -22,7 +24,7 @@ import java.util.stream.Collectors; * @author freva */ public class DockerMock implements Docker { - private List<Container> containers = new ArrayList<>(); + private final Map<ContainerName, Container> containersByContainerName = new HashMap<>(); public final CallOrderVerifier callOrderVerifier; private static final Object monitor = new Object(); @@ -38,7 +40,8 @@ public class DockerMock implements Docker { synchronized (monitor) { callOrderVerifier.add("createContainerCommand with " + dockerImage + ", HostName: " + hostName + ", " + containerName); - containers.add(new Container(hostName, dockerImage, containerName, Container.State.RUNNING, 2)); + containersByContainerName.put( + containerName, new Container(hostName, dockerImage, containerName, Container.State.RUNNING, 2)); } return new StartContainerCommandMock(); @@ -59,14 +62,14 @@ public class DockerMock implements Docker { @Override public List<Container> getAllContainersManagedBy(String manager) { synchronized (monitor) { - return new ArrayList<>(containers); + return new ArrayList<>(containersByContainerName.values()); } } @Override public List<ContainerName> listAllContainersManagedBy(String manager) { synchronized (monitor) { - return containers.stream().map(container -> container.name).collect(Collectors.toList()); + return getAllContainersManagedBy(manager).stream().map(container -> container.name).collect(Collectors.toList()); } } @@ -86,10 +89,9 @@ public class DockerMock implements Docker { public void stopContainer(ContainerName containerName) { synchronized (monitor) { callOrderVerifier.add("stopContainer with " + containerName); - containers = containers.stream() - .map(container -> container.name.equals(containerName) ? - new Container(container.hostname, container.image, container.name, Container.State.EXITED, 0) : container) - .collect(Collectors.toList()); + Container container = containersByContainerName.get(containerName); + containersByContainerName.put(containerName, + new Container(container.hostname, container.image, container.name, Container.State.EXITED, 0)); } } @@ -97,16 +99,14 @@ public class DockerMock implements Docker { public void deleteContainer(ContainerName containerName) { synchronized (monitor) { callOrderVerifier.add("deleteContainer with " + containerName); - containers = containers.stream() - .filter(container -> !container.name.equals(containerName)) - .collect(Collectors.toList()); + containersByContainerName.remove(containerName); } } @Override public Optional<Container> getContainer(ContainerName containerName) { synchronized (monitor) { - return containers.stream().filter(container -> container.name.equals(containerName)).findFirst(); + return Optional.ofNullable(containersByContainerName.get(containerName)); } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerTester.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerTester.java index e52052e4cfa..e94c172d56b 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerTester.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerTester.java @@ -1,7 +1,6 @@ package com.yahoo.vespa.hosted.node.admin.integrationTests; import com.yahoo.metrics.simple.MetricReceiver; -import com.yahoo.vespa.hosted.dockerapi.ContainerName; import com.yahoo.vespa.hosted.dockerapi.Docker; import com.yahoo.vespa.hosted.dockerapi.metrics.MetricReceiverWrapper; import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; @@ -32,13 +31,12 @@ import static org.mockito.Mockito.when; */ // Need to deconstruct updater public class DockerTester implements AutoCloseable { - - private final NodeRepoMock nodeRepositoryMock; - private CallOrderVerifier callOrderVerifier; - private Docker dockerMock; + final CallOrderVerifier callOrderVerifier = new CallOrderVerifier(); + final Docker dockerMock = new DockerMock(callOrderVerifier); + final NodeRepoMock nodeRepositoryMock = new NodeRepoMock(callOrderVerifier); + final OrchestratorMock orchestratorMock = new OrchestratorMock(callOrderVerifier); private final NodeAdminStateUpdater updater; private final NodeAdmin nodeAdmin; - private final OrchestratorMock orchestratorMock; public DockerTester() { @@ -52,11 +50,6 @@ public class DockerTester implements AutoCloseable { Environment environment = new Environment.Builder() .inetAddressResolver(inetAddressResolver) .pathResolver(new PathResolver(Paths.get("/tmp"), Paths.get("/tmp"))).build(); - - callOrderVerifier = new CallOrderVerifier(); - orchestratorMock = new OrchestratorMock(callOrderVerifier); - nodeRepositoryMock = new NodeRepoMock(callOrderVerifier); - dockerMock = new DockerMock(callOrderVerifier); Clock clock = Clock.systemUTC(); StorageMaintainerMock storageMaintainer = new StorageMaintainerMock(dockerMock, environment, callOrderVerifier, clock); @@ -71,45 +64,17 @@ public class DockerTester implements AutoCloseable { } public void addContainerNodeSpec(ContainerNodeSpec containerNodeSpec) { - nodeRepositoryMock.addContainerNodeSpec(containerNodeSpec); - } - - public Optional<ContainerNodeSpec> getContainerNodeSpec(String hostname) { - return nodeRepositoryMock.getContainerNodeSpec(hostname); - } - - public int getNumberOfContainerSpecs() { - return nodeRepositoryMock.getNumberOfContainerSpecs(); - } - - public void updateContainerNodeSpec(ContainerNodeSpec containerNodeSpec) { nodeRepositoryMock.updateContainerNodeSpec(containerNodeSpec); } - public void clearContainerNodeSpecs() { - nodeRepositoryMock.clearContainerNodeSpecs(); - } - public NodeAdmin getNodeAdmin() { return nodeAdmin; } - public OrchestratorMock getOrchestratorMock() { - return orchestratorMock; - } - public NodeAdminStateUpdater getNodeAdminStateUpdater() { return updater; } - public CallOrderVerifier getCallOrderVerifier() { - return callOrderVerifier; - } - - public void deleteContainer(ContainerName containerName) { - dockerMock.deleteContainer(containerName); - } - @Override public void close() { updater.deconstruct(); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java index c06febe3f17..3d2d75c8edf 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/MultiDockerTest.java @@ -22,21 +22,20 @@ public class MultiDockerTest { ContainerNodeSpec containerNodeSpec2 = addAndWaitForNode( dockerTester, "host2.test.yahoo.com", new DockerImage("image2")); - dockerTester.updateContainerNodeSpec( + dockerTester.addContainerNodeSpec( new ContainerNodeSpec.Builder(containerNodeSpec2) .nodeState(Node.State.dirty) .build()); // Wait until it is marked ready - while (dockerTester.getContainerNodeSpec(containerNodeSpec2.hostname) + while (dockerTester.nodeRepositoryMock.getContainerNodeSpec(containerNodeSpec2.hostname) .filter(nodeSpec -> nodeSpec.nodeState != Node.State.ready).isPresent()) { Thread.sleep(10); } addAndWaitForNode(dockerTester, "host3.test.yahoo.com", new DockerImage("image1")); - CallOrderVerifier callOrderVerifier = dockerTester.getCallOrderVerifier(); - callOrderVerifier.assertInOrder( + dockerTester.callOrderVerifier.assertInOrder( "createContainerCommand with DockerImage { imageId=image1 }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]", @@ -49,11 +48,12 @@ public class MultiDockerTest { "createContainerCommand with DockerImage { imageId=image1 }, HostName: host3.test.yahoo.com, ContainerName { name=host3 }", "executeInContainerAsRoot with ContainerName { name=host3 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); - callOrderVerifier.assertInOrderWithAssertMessage("Maintainer did not receive call to delete application storage", - "deleteContainer with ContainerName { name=host2 }", - "DeleteContainerStorage with ContainerName { name=host2 }"); + dockerTester.callOrderVerifier.assertInOrderWithAssertMessage( + "Maintainer did not receive call to delete application storage", + "deleteContainer with ContainerName { name=host2 }", + "DeleteContainerStorage with ContainerName { name=host2 }"); - callOrderVerifier.assertInOrder( + dockerTester.callOrderVerifier.assertInOrder( "updateNodeAttributes with HostName: host1.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image1, vespaVersion='1.2.3'}", "updateNodeAttributes with HostName: host2.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image2, vespaVersion='1.2.3'}", "markNodeAvailableForNewAllocation with HostName: host2.test.yahoo.com", @@ -76,12 +76,12 @@ public class MultiDockerTest { tester.addContainerNodeSpec(containerNodeSpec); // Wait for node admin to be notified with node repo state and the docker container has been started - while (tester.getNodeAdmin().getListOfHosts().size() != tester.getNumberOfContainerSpecs()) { + while (tester.getNodeAdmin().getListOfHosts().size() != tester.nodeRepositoryMock.getNumberOfContainerSpecs()) { Thread.sleep(10); } ContainerName containerName = ContainerName.fromHostname(hostName); - tester.getCallOrderVerifier().assertInOrder( + tester.callOrderVerifier.assertInOrder( "createContainerCommand with " + dockerImage + ", HostName: " + hostName + ", " + containerName, "executeInContainerAsRoot with " + containerName + ", args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java index e0aa2281436..da536d6bd25 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeRepoMock.java @@ -14,7 +14,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; /** * Mock with some simple logic @@ -22,10 +21,9 @@ import java.util.stream.Collectors; * @author dybis */ public class NodeRepoMock implements NodeRepository { - private static final Object monitor = new Object(); - private List<ContainerNodeSpec> containerNodeSpecs = new ArrayList<>(); + private final Map<String, ContainerNodeSpec> containerNodeSpecsByHostname = new HashMap<>(); private final Map<String, List<ContainerAclSpec>> acls = new HashMap<>(); private final CallOrderVerifier callOrderVerifier; @@ -36,16 +34,14 @@ public class NodeRepoMock implements NodeRepository { @Override public List<ContainerNodeSpec> getContainersToRun() throws IOException { synchronized (monitor) { - return containerNodeSpecs; + return new ArrayList<>(containerNodeSpecsByHostname.values()); } } @Override public Optional<ContainerNodeSpec> getContainerNodeSpec(String hostName) { synchronized (monitor) { - return containerNodeSpecs.stream() - .filter(containerNodeSpec -> containerNodeSpec.hostname.equals(hostName)) - .findFirst(); + return Optional.ofNullable(containerNodeSpecsByHostname.get(hostName)); } } @@ -95,43 +91,12 @@ public class NodeRepoMock implements NodeRepository { } public void updateContainerNodeSpec(ContainerNodeSpec containerNodeSpec) { - addContainerNodeSpec(containerNodeSpec); - } - - public void addContainerNodeSpec(ContainerNodeSpec containerNodeSpec) { - removeContainerNodeSpec(containerNodeSpec.hostname); - synchronized (monitor) { - containerNodeSpecs.add(containerNodeSpec); - } - } - - public void clearContainerNodeSpecs() { - synchronized (monitor) { - containerNodeSpecs.clear(); - } - } - - public void removeContainerNodeSpec(String hostName) { - synchronized (monitor) { - containerNodeSpecs = containerNodeSpecs.stream() - .filter(c -> !c.hostname.equals(hostName)) - .collect(Collectors.toList()); - } + containerNodeSpecsByHostname.put(containerNodeSpec.hostname, containerNodeSpec); } public int getNumberOfContainerSpecs() { synchronized (monitor) { - return containerNodeSpecs.size(); - } - } - - public void addContainerAclSpecs(String hostname, List<ContainerAclSpec> containerAclSpecs) { - synchronized (monitor) { - if (this.acls.containsKey(hostname)) { - this.acls.get(hostname).addAll(containerAclSpecs); - } else { - this.acls.put(hostname, containerAclSpecs); - } + return containerNodeSpecsByHostname.size(); } } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java index 187bfa22195..8774fef576b 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/NodeStateTest.java @@ -33,7 +33,7 @@ public class NodeStateTest { Thread.sleep(10); } - tester.getCallOrderVerifier().assertInOrder( + tester.callOrderVerifier.assertInOrder( "createContainerCommand with DockerImage { imageId=dockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); } @@ -44,20 +44,20 @@ public class NodeStateTest { try (DockerTester dockerTester = new DockerTester()) { setup(dockerTester); // Change node state to dirty - dockerTester.updateContainerNodeSpec(new ContainerNodeSpec.Builder(initialContainerNodeSpec) + dockerTester.addContainerNodeSpec(new ContainerNodeSpec.Builder(initialContainerNodeSpec) .nodeState(Node.State.dirty) .build()); // Wait until it is marked ready - while (dockerTester.getContainerNodeSpec(initialContainerNodeSpec.hostname) + while (dockerTester.nodeRepositoryMock.getContainerNodeSpec(initialContainerNodeSpec.hostname) .filter(nodeSpec -> nodeSpec.nodeState != Node.State.ready).isPresent()) { Thread.sleep(10); } - dockerTester.getCallOrderVerifier() - .assertInOrder("executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", stop]", - "stopContainer with ContainerName { name=host1 }", - "deleteContainer with ContainerName { name=host1 }"); + dockerTester.callOrderVerifier.assertInOrder( + "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", stop]", + "stopContainer with ContainerName { name=host1 }", + "deleteContainer with ContainerName { name=host1 }"); } } @@ -70,28 +70,29 @@ public class NodeStateTest { DockerImage newDockerImage = new DockerImage("newDockerImage"); // Change node state to inactive and change the wanted docker image - dockerTester.updateContainerNodeSpec(new ContainerNodeSpec.Builder(initialContainerNodeSpec) + dockerTester.addContainerNodeSpec(new ContainerNodeSpec.Builder(initialContainerNodeSpec) .wantedDockerImage(newDockerImage) .nodeState(Node.State.inactive) .build()); - CallOrderVerifier callOrderVerifier = dockerTester.getCallOrderVerifier(); - callOrderVerifier.assertInOrderWithAssertMessage("Node set to inactive, but no stop/delete call received", - "stopContainer with ContainerName { name=host1 }", - "deleteContainer with ContainerName { name=host1 }"); + dockerTester.callOrderVerifier.assertInOrderWithAssertMessage( + "Node set to inactive, but no stop/delete call received", + "stopContainer with ContainerName { name=host1 }", + "deleteContainer with ContainerName { name=host1 }"); // Change node state to active - dockerTester.updateContainerNodeSpec(new ContainerNodeSpec.Builder(initialContainerNodeSpec) + dockerTester.addContainerNodeSpec(new ContainerNodeSpec.Builder(initialContainerNodeSpec) .wantedDockerImage(newDockerImage) .nodeState(Node.State.active) .build()); // Check that the container is started again after the delete call - callOrderVerifier.assertInOrderWithAssertMessage("Node not started again after being put to active state", - "deleteContainer with ContainerName { name=host1 }", - "createContainerCommand with DockerImage { imageId=newDockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", - "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); + dockerTester.callOrderVerifier.assertInOrderWithAssertMessage( + "Node not started again after being put to active state", + "deleteContainer with ContainerName { name=host1 }", + "createContainerCommand with DockerImage { imageId=newDockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", + "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", resume]"); } } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RebootTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RebootTest.java index 31145fdc6a0..04f8d226d57 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RebootTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RebootTest.java @@ -36,10 +36,10 @@ public class RebootTest { Thread.sleep(10); } - CallOrderVerifier callOrderVerifier = dockerTester.getCallOrderVerifier(); // Check that the container is started and NodeRepo has received the PATCH update - callOrderVerifier.assertInOrder("createContainerCommand with DockerImage { imageId=dockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", - "updateNodeAttributes with HostName: host1.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=null, dockerImage=dockerImage, vespaVersion='null'}"); + dockerTester.callOrderVerifier.assertInOrder( + "createContainerCommand with DockerImage { imageId=dockerImage }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", + "updateNodeAttributes with HostName: host1.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=null, dockerImage=dockerImage, vespaVersion='null'}"); NodeAdminStateUpdater updater = dockerTester.getNodeAdminStateUpdater(); assertThat(updater.setResumeStateAndCheckIfResumed(NodeAdminStateUpdater.State.SUSPENDED), @@ -56,7 +56,8 @@ public class RebootTest { assertTrue(nodeAdmin.setFrozen(false)); - callOrderVerifier.assertInOrder("executeInContainer with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", stop]"); + dockerTester.callOrderVerifier.assertInOrder( + "executeInContainer with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", stop]"); } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RestartTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RestartTest.java index a0024fae3dc..10028e6862c 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RestartTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/RestartTest.java @@ -29,17 +29,18 @@ public class RestartTest { Thread.sleep(10); } - CallOrderVerifier callOrderVerifier = dockerTester.getCallOrderVerifier(); // Check that the container is started and NodeRepo has received the PATCH update - callOrderVerifier.assertInOrder("createContainerCommand with DockerImage { imageId=image:1.2.3 }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", - "updateNodeAttributes with HostName: host1.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image:1.2.3, vespaVersion='1.2.3'}"); + dockerTester.callOrderVerifier.assertInOrder( + "createContainerCommand with DockerImage { imageId=image:1.2.3 }, HostName: host1.test.yahoo.com, ContainerName { name=host1 }", + "updateNodeAttributes with HostName: host1.test.yahoo.com, NodeAttributes{restartGeneration=1, rebootGeneration=0, dockerImage=image:1.2.3, vespaVersion='1.2.3'}"); wantedRestartGeneration = 2; currentRestartGeneration = 1; - dockerTester.updateContainerNodeSpec(createContainerNodeSpec(wantedRestartGeneration, currentRestartGeneration)); + dockerTester.addContainerNodeSpec(createContainerNodeSpec(wantedRestartGeneration, currentRestartGeneration)); - callOrderVerifier.assertInOrder("Suspend for host1.test.yahoo.com", - "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", restart-vespa]"); + dockerTester.callOrderVerifier.assertInOrder( + "Suspend for host1.test.yahoo.com", + "executeInContainerAsRoot with ContainerName { name=host1 }, args: [" + DockerOperationsImpl.NODE_PROGRAM + ", restart-vespa]"); } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java index 93371c93f73..ef9d52e95aa 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/acl/AclMaintainerTest.java @@ -5,8 +5,7 @@ import com.yahoo.vespa.hosted.dockerapi.ContainerName; import com.yahoo.vespa.hosted.dockerapi.DockerImage; import com.yahoo.vespa.hosted.node.admin.ContainerAclSpec; import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; -import com.yahoo.vespa.hosted.node.admin.integrationTests.CallOrderVerifier; -import com.yahoo.vespa.hosted.node.admin.integrationTests.NodeRepoMock; +import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; import org.junit.Before; import org.junit.Test; import org.mockito.verification.VerificationMode; @@ -32,13 +31,13 @@ public class AclMaintainerTest { private AclMaintainer aclMaintainer; private DockerOperations dockerOperations; - private NodeRepoMock nodeRepository; + private NodeRepository nodeRepository; private List<Container> containers; @Before public void before() { this.dockerOperations = mock(DockerOperations.class); - this.nodeRepository = new NodeRepoMock(new CallOrderVerifier()); + this.nodeRepository = mock(NodeRepository.class); this.aclMaintainer = new AclMaintainer(dockerOperations, nodeRepository, NODE_ADMIN_HOSTNAME); this.containers = new ArrayList<>(); when(dockerOperations.getAllManagedContainers()).thenReturn(containers); @@ -48,7 +47,7 @@ public class AclMaintainerTest { public void configures_container_acl() { Container container = makeContainer("container-1"); List<ContainerAclSpec> aclSpecs = makeAclSpecs(3, container.name); - nodeRepository.addContainerAclSpecs(NODE_ADMIN_HOSTNAME, aclSpecs); + when(nodeRepository.getContainerAclSpecs(NODE_ADMIN_HOSTNAME)).thenReturn(aclSpecs); aclMaintainer.run(); assertAclsApplied(container.name, aclSpecs); } @@ -57,7 +56,7 @@ public class AclMaintainerTest { public void does_not_configure_acl_if_unchanged() { Container container = makeContainer("container-1"); List<ContainerAclSpec> aclSpecs = makeAclSpecs(3, container.name); - nodeRepository.addContainerAclSpecs(NODE_ADMIN_HOSTNAME, aclSpecs); + when(nodeRepository.getContainerAclSpecs(NODE_ADMIN_HOSTNAME)).thenReturn(aclSpecs); // Run twice aclMaintainer.run(); aclMaintainer.run(); @@ -68,7 +67,7 @@ public class AclMaintainerTest { public void reconfigures_acl_when_container_pid_changes() { Container container = makeContainer("container-1"); List<ContainerAclSpec> aclSpecs = makeAclSpecs(3, container.name); - nodeRepository.addContainerAclSpecs(NODE_ADMIN_HOSTNAME, aclSpecs); + when(nodeRepository.getContainerAclSpecs(NODE_ADMIN_HOSTNAME)).thenReturn(aclSpecs); aclMaintainer.run(); assertAclsApplied(container.name, aclSpecs); @@ -84,7 +83,7 @@ public class AclMaintainerTest { public void does_not_configure_acl_for_stopped_container() { Container stoppedContainer = makeContainer("container-1", Container.State.EXITED, 0); List<ContainerAclSpec> aclSpecs = makeAclSpecs(1, stoppedContainer.name); - nodeRepository.addContainerAclSpecs(NODE_ADMIN_HOSTNAME, aclSpecs); + when(nodeRepository.getContainerAclSpecs(NODE_ADMIN_HOSTNAME)).thenReturn(aclSpecs); aclMaintainer.run(); assertAclsApplied(stoppedContainer.name, aclSpecs, never()); } @@ -92,7 +91,7 @@ public class AclMaintainerTest { @Test public void rollback_is_attempted_when_applying_acl_fail() { Container container = makeContainer("container-1"); - nodeRepository.addContainerAclSpecs(NODE_ADMIN_HOSTNAME, makeAclSpecs(1, container.name)); + when(nodeRepository.getContainerAclSpecs(NODE_ADMIN_HOSTNAME)).thenReturn(makeAclSpecs(1, container.name)); doThrow(new RuntimeException("iptables command failed")) .doNothing() diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java index 83a00241919..174c9eeb695 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java @@ -488,8 +488,6 @@ public class NodeAgentImplTest { verify(nodeAgent, times(3)).converge(); } - - @Test @SuppressWarnings("unchecked") public void testGetRelevantMetrics() throws Exception { @@ -536,6 +534,11 @@ public class NodeAgentImplTest { Set<Map<String, Object>> expectedMetrics = objectMapper.readValue(expectedMetricsFile, Set.class); Set<Map<String, Object>> actualMetrics = metricReceiver.getAllMetricsRaw(); + String arg = nodeAgent.buildRPCArgumentFromMetrics(); + arg = arg.replaceAll("\"timestamp\":\\d+", "\"timestamp\":0"); + + assertEquals("s:'{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"vespa.node\",\"metrics\":{\"mem.limit\":4.294967296E9,\"mem.used\":1.073741824E9,\"alive\":1.0,\"disk.used\":4.2547019776E10,\"disk.util\":15.85,\"cpu.util\":6.75,\"disk.limit\":2.68435456E11,\"mem.util\":25.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"vespa.node\",\"metrics\":{\"net.out.bytes\":2.0303455E7,\"net.out.dropped\":13.0,\"net.in.dropped\":4.0,\"net.in.bytes\":1.949927E7,\"net.out.errors\":3.0,\"net.in.errors\":55.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"interface\":\"eth0\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"vespa.node\",\"metrics\":{\"net.out.bytes\":5.4246745E7,\"net.out.dropped\":0.0,\"net.in.dropped\":0.0,\"net.in.bytes\":3245766.0,\"net.out.errors\":0.0,\"net.in.errors\":0.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"interface\":\"eth1\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"host_life\",\"metrics\":{\"alive\":1.0,\"uptime\":1234.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"docker\",\"metrics\":{\"node.disk.limit\":2.68435456E11,\"node.disk.used\":4.2547019776E10,\"node.memory.usage\":1.073741824E9,\"node.cpu.busy.pct\":6.75,\"node.cpu.throttled_time\":4523.0,\"node.memory.limit\":4.294967296E9,\"node.alive\":1.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"docker\",\"metrics\":{\"node.net.in.dropped\":4.0,\"node.net.out.errors\":3.0,\"node.net.out.bytes\":2.0303455E7,\"node.net.in.bytes\":1.949927E7,\"node.net.out.dropped\":13.0,\"node.net.in.errors\":55.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"interface\":\"eth0\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}{\"routing\":{\"yamas\":{\"namespaces\":[\"Vespa\"]}},\"application\":\"docker\",\"metrics\":{\"node.net.in.dropped\":0.0,\"node.net.out.errors\":0.0,\"node.net.out.bytes\":5.4246745E7,\"node.net.in.bytes\":3245766.0,\"node.net.out.dropped\":0.0,\"node.net.in.errors\":0.0},\"dimensions\":{\"app\":\"testapp.testinstance\",\"role\":\"tenants\",\"instanceName\":\"testinstance\",\"vespaVersion\":\"1.2.3\",\"clusterid\":\"clustId\",\"interface\":\"eth1\",\"parentHostname\":\"parent.host.name.yahoo.com\",\"flavor\":\"docker\",\"clustertype\":\"clustType\",\"tenantName\":\"tester\",\"zone\":\"dev.us-east-1\",\"host\":\"host1.test.yahoo.com\",\"state\":\"active\",\"applicationId\":\"tester.testapp.testinstance\",\"applicationName\":\"testapp\"},\"timestamp\":0}'", arg); + assertEquals(expectedMetrics, actualMetrics); } |