diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2018-11-19 13:22:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-19 13:22:05 +0100 |
commit | b24390316ab4d79076eb781ba14414281ebab406 (patch) | |
tree | 5a57997849b5501fb950822539912d1d515ee487 /node-repository/src/test | |
parent | ef973b9d1e68f7ac4e4dee3fb894b3a52c48e253 (diff) | |
parent | 743229db619150ba3628a39280d47277618ced88 (diff) |
Merge pull request #7691 from vespa-engine/mpolden/dual-stack-containers
Add support for dual-stack Docker containers
Diffstat (limited to 'node-repository/src/test')
5 files changed, 79 insertions, 60 deletions
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/monitoring/MetricsReporterTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/monitoring/MetricsReporterTest.java index 248299e7991..2b91262d291 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/monitoring/MetricsReporterTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/monitoring/MetricsReporterTest.java @@ -1,6 +1,7 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.monitoring; +import com.google.common.collect.ImmutableSet; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterMembership; @@ -31,7 +32,6 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -120,13 +120,9 @@ public class MetricsReporterTest { true); // Allow 4 containers - Set<String> additionalIps = new HashSet<>(); - additionalIps.add("::2"); - additionalIps.add("::3"); - additionalIps.add("::4"); - additionalIps.add("::5"); + Set<String> ipAddressPool = ImmutableSet.of("::2", "::3", "::4", "::5"); - Node dockerHost = Node.create("openStackId1", Collections.singleton("::1"), additionalIps, "dockerHost", Optional.empty(), nodeFlavors.getFlavorOrThrow("host"), NodeType.host); + Node dockerHost = Node.create("openStackId1", Collections.singleton("::1"), ipAddressPool, "dockerHost", Optional.empty(), nodeFlavors.getFlavorOrThrow("host"), NodeType.host); nodeRepository.addNodes(Collections.singletonList(dockerHost)); nodeRepository.dirtyRecursively("dockerHost", Agent.system, getClass().getSimpleName()); nodeRepository.setReady("dockerHost", Agent.system, getClass().getSimpleName()); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java index 6f7ba72ff7e..b3f1fdb3fb2 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.persistence; import com.google.common.collect.ImmutableSet; @@ -239,18 +239,18 @@ public class SerializationTest { } @Test - public void serialize_additional_ip_addresses() { + public void serialize_ip_address_pool() { Node node = createNode(); - // Test round-trip with additional addresses - node = node.withAdditionalIpAddresses(ImmutableSet.of("10.0.0.1", "10.0.0.2", "10.0.0.3")); + // Test round-trip with IP address pool + node = node.withIpAddressPool(ImmutableSet.of("::1", "::2", "::3")); Node copy = nodeSerializer.fromJson(node.state(), nodeSerializer.toJson(node)); - assertEquals(node.additionalIpAddresses(), copy.additionalIpAddresses()); + assertEquals(node.ipAddressPool(), copy.ipAddressPool()); - // Test round-trip without additional addresses (handle empty ip set) + // Test round-trip without IP address pool (handle empty pool) node = createNode(); copy = nodeSerializer.fromJson(node.state(), nodeSerializer.toJson(node)); - assertEquals(node.additionalIpAddresses(), copy.additionalIpAddresses()); + assertEquals(node.ipAddressPool(), copy.ipAddressPool()); } @Test diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java index 1e69b26d0e0..d13d3ee4945 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.provisioning; import com.yahoo.config.provision.Flavor; @@ -10,7 +10,7 @@ import org.junit.Test; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -124,11 +124,11 @@ public class DockerHostCapacityTest { private Set<String> generateIPs(int start, int count) { // Allow 4 containers - Set<String> additionalIps = new HashSet<>(); + Set<String> ipAddressPool = new LinkedHashSet<>(); for (int i = start; i < (start + count); i++) { - additionalIps.add("::" + i); + ipAddressPool.add("::" + i); } - return additionalIps; + return ipAddressPool; } } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisioningTest.java index 223a8bc83b0..2875d4e4cf9 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisioningTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisioningTest.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.provisioning; import com.google.common.collect.ImmutableSet; @@ -20,7 +20,7 @@ import com.yahoo.vespa.curator.transaction.CuratorTransaction; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.node.Agent; -import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import java.time.Instant; @@ -79,8 +79,8 @@ public class DynamicDockerProvisioningTest { addAndAssignNode(application2, "2b", dockerHosts.get(3).hostname(), clusterSpec2, flavor, 1, tester); // Redeploy both applications (to be agnostic on which hosts are picked as spares) - deployapp(application1, clusterSpec1, flavor, tester, 2); - deployapp(application2, clusterSpec2, flavor, tester, 2); + deployApp(application1, clusterSpec1, flavor, tester, 2); + deployApp(application2, clusterSpec2, flavor, tester, 2); // Assert that we have two spare nodes (two hosts that are don't have allocations) Set<String> hostsWithChildren = new HashSet<>(); @@ -89,7 +89,7 @@ public class DynamicDockerProvisioningTest { hostsWithChildren.add(node.parentHostname().get()); } } - Assert.assertEquals(4 - tester.provisioner().getSpareCapacityProd(), hostsWithChildren.size()); + assertEquals(4 - tester.provisioner().getSpareCapacityProd(), hostsWithChildren.size()); } @@ -112,26 +112,26 @@ public class DynamicDockerProvisioningTest { // Application 1 ApplicationId application1 = makeApplicationId("t1", "a1"); ClusterSpec clusterSpec1 = clusterSpec("myContent.t1.a1"); - deployapp(application1, clusterSpec1, flavor, tester, 3); + deployApp(application1, clusterSpec1, flavor, tester, 3); // Application 2 ApplicationId application2 = makeApplicationId("t2", "a2"); ClusterSpec clusterSpec2 = clusterSpec("myContent.t2.a2"); - deployapp(application2, clusterSpec2, flavor, tester, 2); + deployApp(application2, clusterSpec2, flavor, tester, 2); // Application 3 ApplicationId application3 = makeApplicationId("t3", "a3"); ClusterSpec clusterSpec3 = clusterSpec("myContent.t3.a3"); - deployapp(application3, clusterSpec3, flavor, tester, 2); + deployApp(application3, clusterSpec3, flavor, tester, 2); // App 2 and 3 should have been allocated to the same nodes - fail one of the parent hosts from there String parent = tester.nodeRepository().getNodes(application2).stream().findAny().get().parentHostname().get(); tester.nodeRepository().failRecursively(parent, Agent.system, "Testing"); // Redeploy all applications - deployapp(application1, clusterSpec1, flavor, tester, 3); - deployapp(application2, clusterSpec2, flavor, tester, 2); - deployapp(application3, clusterSpec3, flavor, tester, 2); + deployApp(application1, clusterSpec1, flavor, tester, 3); + deployApp(application2, clusterSpec2, flavor, tester, 2); + deployApp(application3, clusterSpec3, flavor, tester, 2); Map<Integer, Integer> numberOfChildrenStat = new HashMap<>(); for (Node node : dockerHosts) { @@ -173,7 +173,7 @@ public class DynamicDockerProvisioningTest { addAndAssignNode(application1, "1b", dockerHosts.get(1).hostname(), clusterSpec1, flavor, 1, tester); // Redeploy both applications (to be agnostic on which hosts are picked as spares) - deployapp(application1, clusterSpec1, flavor, tester, 2); + deployApp(application1, clusterSpec1, flavor, tester, 2); // Assert that we have two spare nodes (two hosts that are don't have allocations) Set<String> hostsWithChildren = new HashSet<>(); @@ -182,7 +182,7 @@ public class DynamicDockerProvisioningTest { hostsWithChildren.add(node.parentHostname().get()); } } - Assert.assertEquals(2, hostsWithChildren.size()); + assertEquals(2, hostsWithChildren.size()); } @Test(expected = OutOfCapacityException.class) @@ -199,19 +199,14 @@ public class DynamicDockerProvisioningTest { fail("Two groups have been allocated to the same parent host"); } + @Ignore // TODO: Re-enable if we reintroduce spare capacity requirement @Test public void spare_capacity_used_only_when_replacement() { // Use spare capacity only when replacement (i.e one node is failed) // Test should allocate as much capacity as possible, verify that it is not possible to allocate one more unit // Verify that there is still capacity (available spare) // Fail one node and redeploy, Verify that one less node is empty. - - ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")), flavorsConfig()); - // Only run test if there _is_ spare capacity - if (tester.provisioner().getSpareCapacityProd() == 0) { - return; - } // Setup test ApplicationId application1 = tester.makeApplicationId(); @@ -271,12 +266,28 @@ public class DynamicDockerProvisioningTest { tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, flavor.canonicalName()); } + @Test + public void provision_dual_stack_containers() { + ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")), flavorsConfig()); + tester.makeReadyNodes(2, "host-large", NodeType.host, 10, true); + deployZoneApp(tester); + + ApplicationId application = tester.makeApplicationId(); + Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3"); + List<HostSpec> hosts = tester.prepare(application, clusterSpec("myContent.t1.a1"), 2, 1, flavor.canonicalName()); + tester.activate(application, hosts); + + List<Node> activeNodes = tester.nodeRepository().getNodes(application); + assertEquals(ImmutableSet.of("::12", "127.0.127.12"), activeNodes.get(0).ipAddresses()); + assertEquals(ImmutableSet.of("::2", "127.0.127.2"), activeNodes.get(1).ipAddresses()); + } + private ApplicationId makeApplicationId(String tenant, String appName) { return ApplicationId.from(tenant, appName, "default"); } - private void deployapp(ApplicationId id, ClusterSpec spec, Flavor flavor, ProvisioningTester tester, int nodecount) { - List<HostSpec> hostSpec = tester.prepare(id, spec, nodecount, 1, flavor.canonicalName()); + private void deployApp(ApplicationId id, ClusterSpec spec, Flavor flavor, ProvisioningTester tester, int nodeCount) { + List<HostSpec> hostSpec = tester.prepare(id, spec, nodeCount, 1, flavor.canonicalName()); tester.activate(id, new HashSet<>(hostSpec)); } @@ -338,6 +349,6 @@ public class DynamicDockerProvisioningTest { } private ClusterSpec clusterSpec(String clusterId) { - return ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from(clusterId), Version.fromString("6.100"), false); + return ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from(clusterId), Version.fromString("6.42"), false); } } diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java index d5ef20a63df..81414c0ac2d 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.provisioning; import com.yahoo.component.Version; @@ -38,6 +38,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -151,7 +152,7 @@ public class ProvisioningTester { return hosts2; } - public void activate(ApplicationId application, Set<HostSpec> hosts) { + public void activate(ApplicationId application, Collection<HostSpec> hosts) { NestedTransaction transaction = new NestedTransaction(); transaction.add(new CuratorTransaction(curator)); provisioner.activate(transaction, application, hosts); @@ -165,7 +166,7 @@ public class ProvisioningTester { deactivateTransaction.commit(); } - Set<String> toHostNames(Set<HostSpec> hosts) { + Collection<String> toHostNames(Collection<HostSpec> hosts) { return hosts.stream().map(HostSpec::hostname).collect(Collectors.toSet()); } @@ -231,9 +232,12 @@ public class ProvisioningTester { return makeReadyNodes(n, flavor, type, 0); } - List<Node> makeProvisionedNodes(int n, String flavor, NodeType type, int additionalIps) { - List<Node> nodes = new ArrayList<>(n); + List<Node> makeProvisionedNodes(int count, String flavor, NodeType type, int ipAddressPoolSize) { + return makeProvisionedNodes(count, flavor, type, ipAddressPoolSize, false); + } + List<Node> makeProvisionedNodes(int n, String flavor, NodeType type, int ipAddressPoolSize, boolean dualStack) { + List<Node> nodes = new ArrayList<>(n); for (int i = 0; i < n; i++) { nextHost++; @@ -257,21 +261,26 @@ public class ProvisioningTester { hostIps.add(ipv4); hostIps.add(ipv6); - Set<String> addips = new HashSet<>(); - for (int ipSeq = 1; ipSeq < additionalIps; ipSeq++) { + Set<String> ipAddressPool = new LinkedHashSet<>(); + for (int poolIp = 1; poolIp < ipAddressPoolSize; poolIp++) { nextIP++; - String ipv6node = String.format("::%d", nextIP); - addips.add(ipv6node); - nameResolver.addRecord(String.format("node-%d-of-%s",ipSeq, hostname), ipv6node); + String ipv6Addr = String.format("::%d", nextIP); + ipAddressPool.add(ipv6Addr); + nameResolver.addRecord(String.format("node-%d-of-%s", poolIp, hostname), ipv6Addr); + if (dualStack) { + String ipv4Addr = String.format("127.0.127.%d", nextIP); + ipAddressPool.add(ipv4Addr); + nameResolver.addRecord(String.format("node-%d-of-%s", poolIp, hostname), ipv4Addr); + } } nodes.add(nodeRepository.createNode(hostname, - hostname, - hostIps, - addips, - Optional.empty(), - nodeFlavors.getFlavorOrThrow(flavor), - type)); + hostname, + hostIps, + ipAddressPool, + Optional.empty(), + nodeFlavors.getFlavorOrThrow(flavor), + type)); } nodes = nodeRepository.addNodes(nodes); return nodes; @@ -309,9 +318,12 @@ public class ProvisioningTester { return nodeRepository.getNodes(application.getApplicationId(), Node.State.active); } + List<Node> makeReadyNodes(int n, String flavor, NodeType type, int ipAddressPoolSize) { + return makeReadyNodes(n, flavor, type, ipAddressPoolSize, false); + } - List<Node> makeReadyNodes(int n, String flavor, NodeType type, int additionalIps) { - List<Node> nodes = makeProvisionedNodes(n, flavor, type, additionalIps); + List<Node> makeReadyNodes(int n, String flavor, NodeType type, int ipAddressPoolSize, boolean dualStack) { + List<Node> nodes = makeProvisionedNodes(n, flavor, type, ipAddressPoolSize, dualStack); nodes = nodeRepository.setDirty(nodes, Agent.system, getClass().getSimpleName()); return nodeRepository.setReady(nodes, Agent.system, getClass().getSimpleName()); } |