use of com.yahoo.config.provision.HostSpec in project vespa by vespa-engine.
the class HostsXmlProvisionerTest method require_basic_works.
@Test
public void require_basic_works() {
HostsXmlProvisioner hostProvisioner = createProvisioner(threeHosts);
// 4 services, 2 host aliases, mapping to 2 host.
List<String> aliases = createAliases();
Map<String, HostSpec> map = allocate(hostProvisioner, aliases);
assertCorrectNumberOfHosts(map, 2);
for (HostSpec hostSpec : map.values()) {
if (hostSpec.hostname().equals("test2.yahoo.com")) {
assertThat(hostSpec.aliases().size(), is(2));
} else {
assertThat(hostSpec.aliases().size(), is(1));
}
}
assertThat(map.size(), is(2));
assertTrue(map.keySet().containsAll(aliases));
// 5 services, 3 host aliases, mapping to 2 host.
aliases = createAliases(Collections.singletonList("node3"));
map = allocate(hostProvisioner, aliases);
assertCorrectNumberOfHosts(map, 2);
assertThat(map.size(), is(3));
assertTrue(map.keySet().containsAll(aliases));
// 5 services, 3 host aliases, mapping to 3 host.
aliases = createAliases(Collections.singletonList("node4"));
map = allocate(hostProvisioner, aliases);
assertThat(map.size(), is(3));
assertCorrectNumberOfHosts(map, 3);
assertTrue(map.keySet().containsAll(aliases));
assertEquals("", System.getProperty("zookeeper.vespa.clients"));
}
use of com.yahoo.config.provision.HostSpec in project vespa by vespa-engine.
the class NodeRepositoryProvisioner method asSortedHosts.
private List<HostSpec> asSortedHosts(List<Node> nodes) {
nodes.sort(Comparator.comparingInt(node -> node.allocation().get().membership().index()));
List<HostSpec> hosts = new ArrayList<>(nodes.size());
for (Node node : nodes) {
log.log(LogLevel.DEBUG, () -> "Prepared node " + node.hostname() + " - " + node.flavor());
hosts.add(new HostSpec(node.hostname(), node.allocation().orElseThrow(IllegalStateException::new).membership(), node.flavor()));
}
return hosts;
}
use of com.yahoo.config.provision.HostSpec in project vespa by vespa-engine.
the class InactiveAndFailedExpirerTest method inactive_and_failed_times_out.
@Test
public void inactive_and_failed_times_out() {
ProvisioningTester tester = new ProvisioningTester(new Zone(Environment.prod, RegionName.from("us-east")));
List<Node> nodes = tester.makeReadyNodes(2, "default");
// Allocate then deallocate 2 nodes
ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Version.fromString("6.42"), false);
List<HostSpec> preparedNodes = tester.prepare(applicationId, cluster, Capacity.fromNodeCount(2), 1);
tester.activate(applicationId, new HashSet<>(preparedNodes));
assertEquals(2, tester.getNodes(applicationId, Node.State.active).size());
tester.deactivate(applicationId);
List<Node> inactiveNodes = tester.getNodes(applicationId, Node.State.inactive).asList();
assertEquals(2, inactiveNodes.size());
// Inactive times out
tester.advanceTime(Duration.ofMinutes(14));
new InactiveExpirer(tester.nodeRepository(), tester.clock(), Duration.ofMinutes(10), new JobControl(tester.nodeRepository().database())).run();
assertEquals(0, tester.nodeRepository().getNodes(Node.State.inactive).size());
List<Node> dirty = tester.nodeRepository().getNodes(Node.State.dirty);
assertEquals(2, dirty.size());
assertFalse(dirty.get(0).allocation().isPresent());
assertFalse(dirty.get(1).allocation().isPresent());
// One node is set back to ready
Node ready = tester.nodeRepository().setReady(Collections.singletonList(dirty.get(0)), Agent.system, getClass().getSimpleName()).get(0);
assertEquals("Allocated history is removed on readying", Arrays.asList(History.Event.Type.provisioned, History.Event.Type.readied), ready.history().events().stream().map(History.Event::type).collect(Collectors.toList()));
// Dirty times out for the other one
tester.advanceTime(Duration.ofMinutes(14));
new DirtyExpirer(tester.nodeRepository(), tester.clock(), Duration.ofMinutes(10), new JobControl(tester.nodeRepository().database())).run();
assertEquals(0, tester.nodeRepository().getNodes(NodeType.tenant, Node.State.dirty).size());
List<Node> failed = tester.nodeRepository().getNodes(NodeType.tenant, Node.State.failed);
assertEquals(1, failed.size());
assertEquals(1, failed.get(0).status().failCount());
}
use of com.yahoo.config.provision.HostSpec in project vespa by vespa-engine.
the class Activator method updateFrom.
/**
* Returns the input nodes with the changes resulting from applying the settings in hosts to the given list of nodes.
*/
private List<Node> updateFrom(Collection<HostSpec> hosts, List<Node> nodes) {
List<Node> updated = new ArrayList<>();
for (Node node : nodes) {
HostSpec hostSpec = getHost(node.hostname(), hosts);
node = hostSpec.membership().get().retired() ? node.retire(nodeRepository.clock().instant()) : node.unretire();
node = node.with(node.allocation().get().with(hostSpec.membership().get()));
if (// Docker nodes may change flavor
hostSpec.flavor().isPresent())
node = node.with(hostSpec.flavor().get());
updated.add(node);
}
return updated;
}
use of com.yahoo.config.provision.HostSpec in project vespa by vespa-engine.
the class DynamicDockerProvisioningTest method spare_capacity_used_only_when_replacement.
@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();
tester.makeReadyNodes(5, "host-small", NodeType.host, 32);
deployZoneApp(tester);
Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3");
// Deploy initial state (can max deploy 3 nodes due to redundancy requirements)
List<HostSpec> hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 3, 1, flavor.canonicalName());
tester.activate(application1, ImmutableSet.copyOf(hosts));
DockerHostCapacity capacity = new DockerHostCapacity(tester.nodeRepository().getNodes(Node.State.values()));
assertThat(capacity.freeCapacityInFlavorEquivalence(flavor), greaterThan(0));
List<Node> initialSpareCapacity = findSpareCapacity(tester);
assertThat(initialSpareCapacity.size(), is(2));
try {
hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 4, 1, flavor.canonicalName());
fail("Was able to deploy with 4 nodes, should not be able to use spare capacity");
} catch (OutOfCapacityException e) {
}
tester.fail(hosts.get(0));
hosts = tester.prepare(application1, ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.100"), false), 3, 1, flavor.canonicalName());
tester.activate(application1, ImmutableSet.copyOf(hosts));
List<Node> finalSpareCapacity = findSpareCapacity(tester);
assertThat(finalSpareCapacity.size(), is(1));
}
Aggregations