diff options
Diffstat (limited to 'config-model/src')
17 files changed, 141 insertions, 108 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java index 8ca82692e98..3f229835914 100644 --- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java +++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java @@ -84,7 +84,8 @@ public class DeployState implements ConfigDefinitionStore { private DeployState(ApplicationPackage applicationPackage, SearchDocumentModel searchDocumentModel, RankProfileRegistry rankProfileRegistry, FileRegistry fileRegistry, DeployLogger deployLogger, Optional<HostProvisioner> hostProvisioner, DeployProperties properties, Optional<ApplicationPackage> permanentApplicationPackage, Optional<ConfigDefinitionRepo> configDefinitionRepo, - java.util.Optional<Model> previousModel, Set<Rotation> rotations, Zone zone, QueryProfiles queryProfiles, SemanticRules semanticRules, Instant now) { + java.util.Optional<Model> previousModel, Set<Rotation> rotations, Zone zone, QueryProfiles queryProfiles, + SemanticRules semanticRules, Instant now) { this.logger = deployLogger; this.fileRegistry = fileRegistry; this.rankProfileRegistry = rankProfileRegistry; diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/Host.java b/config-model/src/main/java/com/yahoo/config/model/provision/Host.java index afe4de7ef0d..360853d0f79 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/Host.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/Host.java @@ -1,40 +1,39 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.provision; +import com.google.common.collect.ImmutableList; + import java.util.ArrayList; import java.util.List; /** - * A hostname with zero or more aliases. + * A hostname with zero or more aliases. This is immutable. * * @author hmusum */ public class Host { private final String hostname; - private final List<String> hostAliases; + private final ImmutableList<String> aliases; public Host(String hostname) { this.hostname = hostname; - this.hostAliases = new ArrayList<>(); + this.aliases = ImmutableList.of(); } public Host(String hostname, List<String> hostAliases) { this.hostname = hostname; - this.hostAliases = hostAliases; + this.aliases = ImmutableList.copyOf(hostAliases); } - public String getHostname() { - return hostname; - } + public String hostname() { return hostname; } - public List<String> getHostAliases() { - return hostAliases; - } + /** Returns an immutable list of the aliases of this node, which may be empty but never null */ + public List<String> aliases() { return aliases; } @Override public String toString() { - return hostname + " (aliases: " + hostAliases + ")"; + return hostname + (aliases.size() > 0 ? " (aliases: " + aliases + ")" : "" ); } } diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java b/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java index bfb77612d31..6a5abee7cb3 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java @@ -1,8 +1,9 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.provision; +import com.google.common.collect.ImmutableMap; +import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.config.model.builder.xml.XmlHelper; -import com.yahoo.log.LogLevel; import com.yahoo.net.HostName; import com.yahoo.text.XML; import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder; @@ -17,26 +18,52 @@ import java.util.*; import java.util.logging.Logger; /** - * TODO: What is this? + * A collection of hosts * - * @author hmusum + * @author bratseth */ public class Hosts { public static final Logger log = Logger.getLogger(Hosts.class.getPackage().toString()); - private final HashMap<String, Host> hosts = new LinkedHashMap<>(); - private final Map<String, String> alias2hostname = new LinkedHashMap<>(); - private final Map<String, Host> alias2host = new LinkedHashMap<>(); + private final ImmutableMap<String, Host> hosts; + public Hosts(Collection<Host> hosts) { + validateAliases(hosts); + + ImmutableMap.Builder<String, Host> hostsBuilder = new ImmutableMap.Builder<>(); + for (Host host : hosts) + hostsBuilder.put(host.hostname(), host); + this.hosts = hostsBuilder.build(); + + // Don't limit zk connections on non-hosted systems + System.setProperty("zookeeper.vespa.clients", ""); + } + + /** Throw IllegalArgumentException if host aliases breaks invariants */ + private void validateAliases(Collection<Host> hosts) { + Set<String> aliases = new HashSet<>(); + for (Host host : hosts) { + if (host.aliases().size() > 0) { + if (host.aliases().size() < 1) + throw new IllegalArgumentException("Host '" + host.hostname() + "' must have at least one <alias> tag."); + for (String alias : host.aliases()) { + if (aliases.contains(alias)) + throw new IllegalArgumentException("Alias '" + alias + "' is used by multiple hosts."); + aliases.add(alias); + } + } + } + } + /** * Builds host system from a hosts.xml file * * @param hostsFile a reader for host from application package * @return the HostSystem for this application package */ - public static Hosts getHosts(Reader hostsFile) { - Hosts hosts = new Hosts(); + public static Hosts readFrom(Reader hostsFile) { + List<Host> hosts = new ArrayList<>(); Document doc; try { doc = XmlHelper.getDocumentBuilder().parse(new InputSource(hostsFile)); @@ -55,62 +82,13 @@ public class Hosts { if (hostAliases.isEmpty()) { throw new IllegalArgumentException("No host aliases defined for host '" + name + "'"); } - Host host = new Host(name, hostAliases); - hosts.addHost(host, hostAliases); - } - log.log(LogLevel.DEBUG, "Created hosts:" + hosts); - return hosts; - } - - public Collection<Host> getHosts() { - return hosts.values(); - } - - /** - * Adds one host to this host system. - * - * @param host The host to add - * @param aliases The aliases for this host. - */ - public void addHost(Host host, List<String> aliases) { - hosts.put(host.getHostname(), host); - if ((aliases != null) && (aliases.size() > 0)) { - addHostAliases(aliases, host); + hosts.add(new Host(name, hostAliases)); } + return new Hosts(hosts); } - /** - * Add all aliases for one host - * - * @param hostAliases A list of host aliases - * @param host The Host instance to add the alias for - */ - private void addHostAliases(List<String> hostAliases, Host host) { - if (hostAliases.size() < 1) { - throw new RuntimeException("Host '" + host.getHostname() + "' must have at least one <alias> tag."); - } - for (String alias : hostAliases) { - addHostAlias(alias, host); - } - } - - /** - * Adds an alias for the given host - * - * @param alias alias (string) for a Host - * @param host the {@link Host} to add the alias for - */ - protected void addHostAlias(String alias, Host host) { - if (alias2hostname.containsKey(alias)) { - throw new RuntimeException("Alias '" + alias + "' must be used for only one host!"); - } - alias2hostname.put(alias, host.getHostname()); - alias2host.put(alias, host); - } - - public Map<String, Host> getAlias2host() { - return alias2host; - } + /** Returns an immutable collection of the hosts of this */ + public Collection<Host> asCollection() { return hosts.values(); } @Override public String toString() { diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java index bf630b74272..32a7e79d278 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java @@ -22,27 +22,24 @@ public class HostsXmlProvisioner implements HostProvisioner { public static final String IMPLICIT_ADMIN_HOSTALIAS = "INTERNAL_VESPA_IMPLICIT_ADMIN"; public HostsXmlProvisioner(Reader hosts) { - this.hosts = Hosts.getHosts(hosts); + this.hosts = Hosts.readFrom(hosts); } @Override public HostSpec allocateHost(String alias) { - /** - * Some special rules to allow no admin elements as well - * as jdisc element without nodes. - */ + // Some special rules to allow no admin elements as well as jdisc element without nodes. if (alias.equals(IMPLICIT_ADMIN_HOSTALIAS)) { - if (hosts.getHosts().size() > 1) { - throw new IllegalArgumentException("More than 1 host specified (" + hosts.getHosts().size() + ") and <admin> not specified"); + if (hosts.asCollection().size() > 1) { + throw new IllegalArgumentException("More than 1 host specified (" + hosts.asCollection().size() + ") and <admin> not specified"); } else { return host2HostSpec(getFirstHost()); } } else if (alias.equals(Container.SINGLENODE_CONTAINER_SERVICESPEC)) { return host2HostSpec(getFirstHost()); } - for (Host host : hosts.getHosts()) { - if (host.getHostAliases().contains(alias)) { - return new HostSpec(host.getHostname(), host.getHostAliases()); + for (Host host : hosts.asCollection()) { + if (host.aliases().contains(alias)) { + return new HostSpec(host.hostname(), host.aliases()); } } throw new IllegalArgumentException("Unable to find host for alias '" + alias + "'"); @@ -54,11 +51,11 @@ public class HostsXmlProvisioner implements HostProvisioner { } private HostSpec host2HostSpec(Host host) { - return new HostSpec(host.getHostname(), host.getHostAliases()); + return new HostSpec(host.hostname(), host.aliases()); } private Host getFirstHost() { - return hosts.getHosts().iterator().next(); + return hosts.asCollection().iterator().next(); } } diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java index 69054cb7ae6..5c9d03b434f 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java @@ -49,12 +49,12 @@ public class InMemoryProvisioner implements HostProvisioner { /** Creates this with a set of hosts of the flavor 'default' */ public InMemoryProvisioner(Hosts hosts, boolean failOnOutOfCapacity, String ... retiredHostNames) { - this(Collections.singletonMap("default", hosts.getHosts()), failOnOutOfCapacity, 0, retiredHostNames); + this(Collections.singletonMap("default", hosts.asCollection()), failOnOutOfCapacity, 0, retiredHostNames); } /** Creates this with a set of hosts of the flavor 'default' */ public InMemoryProvisioner(Hosts hosts, boolean failOnOutOfCapacity, int startIndexForClusters, String ... retiredHostNames) { - this(Collections.singletonMap("default", hosts.getHosts()), failOnOutOfCapacity, startIndexForClusters, retiredHostNames); + this(Collections.singletonMap("default", hosts.asCollection()), failOnOutOfCapacity, startIndexForClusters, retiredHostNames); } public InMemoryProvisioner(Map<String, Collection<Host>> hosts, boolean failOnOutOfCapacity, int startIndexForClusters, String ... retiredHostNames) { @@ -88,7 +88,7 @@ public class InMemoryProvisioner implements HostProvisioner { List<Host> defaultHosts = freeNodes.get("default"); if (defaultHosts.isEmpty()) throw new IllegalArgumentException("No more hosts of default flavor available"); Host newHost = freeNodes.removeValue("default", 0); - HostSpec hostSpec = new HostSpec(newHost.getHostname(), newHost.getHostAliases()); + HostSpec hostSpec = new HostSpec(newHost.hostname(), newHost.aliases()); legacyMapping.put(alias, hostSpec); return hostSpec; } @@ -141,7 +141,7 @@ public class InMemoryProvisioner implements HostProvisioner { if (freeNodes.get(flavor).isEmpty()) throw new IllegalArgumentException("No nodes of flavor '" + flavor + "' available"); Host newHost = freeNodes.removeValue(flavor, 0); ClusterMembership membership = ClusterMembership.from(clusterGroup, nextIndex++); - allocation.add(new HostSpec(newHost.getHostname(), newHost.getHostAliases(), membership)); + allocation.add(new HostSpec(newHost.hostname(), newHost.aliases(), membership)); } nextIndexInCluster.put(new Pair<>(clusterGroup.type(), clusterGroup.id()), nextIndex); diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java index 67e80ec95d6..1d5544873d9 100644 --- a/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java +++ b/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java @@ -1,7 +1,6 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.provision; -import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.api.HostProvisioner; import com.yahoo.config.provision.*; import com.yahoo.net.HostName; @@ -31,7 +30,7 @@ public class SingleNodeProvisioner implements HostProvisioner { } catch (UnknownHostException e) { throw new RuntimeException(e); } - this.hostSpec = new HostSpec(host.getHostname(), host.getHostAliases()); + this.hostSpec = new HostSpec(host.hostname(), host.aliases()); } @Override @@ -42,7 +41,7 @@ public class SingleNodeProvisioner implements HostProvisioner { @Override public List<HostSpec> prepare(ClusterSpec cluster, Capacity capacity, int groups, ProvisionLogger logger) { // TODO: This should fail if capacity requested is more than 1 List<HostSpec> hosts = new ArrayList<>(); - hosts.add(new HostSpec(host.getHostname(), host.getHostAliases(), ClusterMembership.from(cluster, counter++))); + hosts.add(new HostSpec(host.hostname(), host.aliases(), ClusterMembership.from(cluster, counter++))); return hosts; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java index 08c3db81091..942c972a782 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java @@ -42,6 +42,7 @@ public class VespaDomBuilder extends VespaModelBuilder { public static final String MMAP_NOCORE_LIMIT="mmap-nocore-limit"; private static final String CPU_SOCKET_ATTRIB_NAME = "cpu-socket"; public static final String CPU_SOCKET_AFFINITY_ATTRIB_NAME = "cpu-socket-affinity"; + public static final String Allocated_MEMORY_ATTRIB_NAME = "allocated-memory"; public static final Logger log = Logger.getLogger(VespaDomBuilder.class.getPackage().toString()); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java index bb852d297a3..268f7a87f2c 100755 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java @@ -173,6 +173,7 @@ public final class ContainerCluster private Zone zone; private Optional<String> hostClusterId = Optional.empty(); + private Optional<Integer> memoryPercentage = Optional.empty(); public ContainerCluster(AbstractConfigProducer<?> parent, String subId, String name) { super(parent, subId); @@ -791,6 +792,14 @@ public final class ContainerCluster */ public Optional<String> getHostClusterId() { return hostClusterId; } + public void setMemoryPercentage(Optional<Integer> memoryPercentage) { this.memoryPercentage = memoryPercentage; } + + /** + * Returns the percentage of host physical memory this application has specified for nodes in this cluster, + * or empty if this is not specified by the application. + */ + public Optional<Integer> getMemoryPercentage() { return memoryPercentage; } + @Override public String toString() { return "container cluster '" + getName() + "'"; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java index c52a7375528..ef0f4882f1c 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java @@ -178,4 +178,5 @@ public class ConfigserverCluster extends AbstractConfigProducer public void getConfig(HealthMonitorConfig.Builder builder) { builder.snapshot_interval(60.0); } + } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java index 2e27dda5a62..a473514a344 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java @@ -38,10 +38,11 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains> SemanticRulesConfig.Producer, PageTemplatesConfig.Producer { + private final List<AbstractSearchCluster> systems = new LinkedList<>(); private Options options = null; - //For legacy qrs clusters only. + // For legacy qrs clusters only. private BinaryScaledAmount totalCacheSize = new BinaryScaledAmount(); private QueryProfiles queryProfiles; @@ -49,12 +50,14 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains> private PageTemplates pageTemplates; private final boolean hostedVespa; private final boolean isCombinedCluster; + private final Optional<Integer> memoryPercentage; public ContainerSearch(ContainerCluster cluster, SearchChains chains, Options options) { super(chains); this.options = options; this.hostedVespa = cluster.isHostedVespa(); this.isCombinedCluster = cluster.getHostClusterId().isPresent(); + this.memoryPercentage = cluster.getMemoryPercentage(); cluster.addComponent(getFS4ResourcePool()); } @@ -122,7 +125,10 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains> @Override public void getConfig(QrStartConfig.Builder qsB) { QrStartConfig.Jvm.Builder internalBuilder = new QrStartConfig.Jvm.Builder(); - if (hostedVespa) { + if (memoryPercentage.isPresent()) { + internalBuilder.heapSizeAsPercentageOfPhysicalMemory(memoryPercentage.get()); + } + else if (hostedVespa) { if (isCombinedCluster) internalBuilder.heapSizeAsPercentageOfPhysicalMemory(17); else diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 8c4a451bb13..6d83c614044 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -387,6 +387,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { applyNodesTagJvmArgs(nodes, nodesElement.getAttribute(VespaDomBuilder.JVMARGS_ATTRIB_NAME)); applyRoutingAliasProperties(nodes, cluster); applyDefaultPreload(nodes, nodesElement); + applyMemoryPercentage(cluster, nodesElement.getAttribute(VespaDomBuilder.Allocated_MEMORY_ATTRIB_NAME)); if (useCpuSocketAffinity(nodesElement)) AbstractService.distributeCpuSocketAffinity(nodes); @@ -416,6 +417,24 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { } } + private void applyMemoryPercentage(ContainerCluster cluster, String memoryPercentage) { + if (memoryPercentage == null || memoryPercentage.isEmpty()) return; + memoryPercentage = memoryPercentage.trim(); + + if ( ! memoryPercentage.endsWith("%")) + throw new IllegalArgumentException("The memory percentage given for nodes in " + cluster + + " must be an integer percentage ending by the '%' sign"); + memoryPercentage = memoryPercentage.substring(0, memoryPercentage.length()-1).trim(); + + try { + cluster.setMemoryPercentage(Optional.of(Integer.parseInt(memoryPercentage))); + } + catch (NumberFormatException e) { + throw new IllegalArgumentException("The memory percentage given for nodes in " + cluster + + " must be an integer percentage ending by the '%' sign"); + } + } + private HostResource allocateSingleNodeHost(ContainerCluster cluster, DeployLogger logger) { if (cluster.isHostedVespa()) { ClusterSpec clusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), Optional.empty()); diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc index 287fd9f459e..e878b0faf22 100644 --- a/config-model/src/main/resources/schema/containercluster.rnc +++ b/config-model/src/main/resources/schema/containercluster.rnc @@ -184,6 +184,7 @@ DocumentApi = element document-api { NodesOfContainerCluster = element nodes { attribute jvmargs { text }? & attribute preload { text }? & + attribute allocated-memory { text }? & attribute cpu-socket-affinity { xsd:boolean }? & ( attribute of { xsd:string } diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java index 6d047c66a5a..b588805722f 100644 --- a/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java +++ b/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java @@ -11,11 +11,13 @@ import java.util.*; import static junit.framework.TestCase.assertTrue; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; /** * @author hmusum */ public class HostsXmlProvisionerTest { + private static final String oneHost = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<hosts>\n" + " <host name=\"test1.yahoo.com\">\n" + @@ -71,6 +73,8 @@ public class HostsXmlProvisionerTest { assertThat(map.size(), is(3)); assertCorrectNumberOfHosts(map, 3); assertTrue(map.keySet().containsAll(aliases)); + + assertEquals("", System.getProperty("zookeeper.vespa.clients")); } @Test(expected = IllegalArgumentException.class) diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java index 34f75d46a1c..86fabdf26bc 100644 --- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java +++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.*; import java.io.StringReader; import java.util.Collection; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -57,7 +58,7 @@ public class ModelProvisioningTest { " <handler id='myHandler'>" + " <component id='injected' />" + " </handler>" + - " <nodes count='2' jvmargs='-verbosegc' preload='lib/blablamalloc.so'/>" + + " <nodes count='2' allocated-memory='45%' jvmargs='-verbosegc' preload='lib/blablamalloc.so'/>" + "</jdisc>" + "</services>"; String hosts ="<hosts>" @@ -81,7 +82,7 @@ public class ModelProvisioningTest { + " </host>" + "</hosts>"; VespaModelCreatorWithMockPkg creator = new VespaModelCreatorWithMockPkg(null, services); - VespaModel model = creator.create(new DeployState.Builder().modelHostProvisioner(new InMemoryProvisioner(Hosts.getHosts(new StringReader(hosts)), true))); + VespaModel model = creator.create(new DeployState.Builder().modelHostProvisioner(new InMemoryProvisioner(Hosts.readFrom(new StringReader(hosts)), true))); assertThat(model.getContainerClusters().get("mydisc").getContainers().size(), is(3)); assertThat(model.getContainerClusters().get("mydisc").getContainers().get(0).getConfigId(), is("mydisc/container.0")); assertTrue(model.getContainerClusters().get("mydisc").getContainers().get(0).isInitialized()); @@ -102,12 +103,14 @@ public class ModelProvisioningTest { assertThat(model.getContainerClusters().get("mydisc").getContainers().get(0).getPreLoad(), is(Defaults.getDefaults().vespaHome() + "lib64/vespa/malloc/libvespamalloc.so")); assertThat(model.getContainerClusters().get("mydisc").getContainers().get(1).getPreLoad(), is(Defaults.getDefaults().vespaHome() + "lib64/vespa/malloc/libvespamalloc.so")); assertThat(model.getContainerClusters().get("mydisc").getContainers().get(2).getPreLoad(), is(Defaults.getDefaults().vespaHome() + "lib64/vespa/malloc/libvespamalloc.so")); + assertThat(model.getContainerClusters().get("mydisc").getMemoryPercentage(), is(Optional.empty())); assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(0).getJvmArgs(), is("-verbosegc")); assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(1).getJvmArgs(), is("-verbosegc")); assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(0).getPreLoad(), is("lib/blablamalloc.so")); assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(1).getPreLoad(), is("lib/blablamalloc.so")); - + assertThat(model.getContainerClusters().get("mydisc2").getMemoryPercentage(), is(Optional.of(45))); + HostSystem hostSystem = model.getHostSystem(); assertNotNull(hostSystem.getHostByHostname("myhost0")); assertNotNull(hostSystem.getHostByHostname("myhost1")); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java index b4e366c1609..05f5145cfa7 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java @@ -47,7 +47,7 @@ public class DedicatedAdminV4Test { + " </host>" + "</hosts>"; ApplicationPackage app = new MockApplicationPackage.Builder().withHosts(hosts).withServices(services).build(); - VespaModel model = new VespaModel(new NullConfigModelRegistry(), new DeployState.Builder().applicationPackage(app).modelHostProvisioner(new InMemoryProvisioner(Hosts.getHosts(app.getHosts()), true)).build()); + VespaModel model = new VespaModel(new NullConfigModelRegistry(), new DeployState.Builder().applicationPackage(app).modelHostProvisioner(new InMemoryProvisioner(Hosts.readFrom(app.getHosts()), true)).build()); assertEquals(3, model.getHosts().size()); Set<String> serviceNames0 = serviceNames(model.getConfig(SentinelConfig.class, "hosts/myhost0")); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java index 5efbfe0d0dc..ef99d1a6370 100755 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import java.util.Collections; import java.util.Iterator; +import java.util.Optional; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -82,29 +83,41 @@ public class ContainerClusterTest { } private ContainerCluster createContainerCluster(boolean isHosted, boolean isCombinedCluster) { + return createContainerCluster(isHosted, isCombinedCluster, Optional.empty()); + } + private ContainerCluster createContainerCluster(boolean isHosted, boolean isCombinedCluster, + Optional<Integer> memoryPercentage) { DeployState state = new DeployState.Builder().properties(new DeployProperties.Builder().hostedVespa(isHosted).build()).build(); MockRoot root = new MockRoot("foo", state); ContainerCluster cluster = new ContainerCluster(root, "container0", "container1"); if (isCombinedCluster) cluster.setHostClusterId("test-content-cluster"); + cluster.setMemoryPercentage(memoryPercentage); cluster.setSearch(new ContainerSearch(cluster, new SearchChains(cluster, "search-chain"), new ContainerSearch.Options())); return cluster; } - private void verifyHeapSizeAsPercentageOfPhysicalMemory(boolean isHosted, boolean isCombinedCluster, int percentage) { - ContainerCluster cluster = createContainerCluster(isHosted, isCombinedCluster); + private void verifyHeapSizeAsPercentageOfPhysicalMemory(boolean isHosted, boolean isCombinedCluster, + Optional<Integer> explicitMemoryPercentage, + int expectedMemoryPercentage) { + ContainerCluster cluster = createContainerCluster(isHosted, isCombinedCluster, explicitMemoryPercentage); QrStartConfig.Builder qsB = new QrStartConfig.Builder(); cluster.getSearch().getConfig(qsB); QrStartConfig qsC= new QrStartConfig(qsB); - assertEquals(percentage, qsC.jvm().heapSizeAsPercentageOfPhysicalMemory()); + assertEquals(expectedMemoryPercentage, qsC.jvm().heapSizeAsPercentageOfPhysicalMemory()); } @Test public void requireThatHeapSizeAsPercentageOfPhysicalMemoryForHostedAndNot() { boolean hosted = true; boolean combined = true; // a cluster running on content nodes (only relevant with hosted) - verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, ! combined, 33); - verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, combined, 17); - verifyHeapSizeAsPercentageOfPhysicalMemory(! hosted, ! combined, 0); + verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, ! combined, Optional.empty(), 33); + verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, combined, Optional.empty(), 17); + verifyHeapSizeAsPercentageOfPhysicalMemory(! hosted, ! combined, Optional.empty(), 0); + + // Explicit value overrides all defaults + verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, ! combined, Optional.of(67), 67); + verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, combined, Optional.of(68), 68); + verifyHeapSizeAsPercentageOfPhysicalMemory(! hosted, ! combined, Optional.of(69), 69); } private void verifyJvmArgs(boolean isHosted, boolean hasDocproc, String expectedArgs, String jvmArgs) { diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java index 6eb38dd6f66..0c57d036998 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java @@ -13,9 +13,11 @@ import com.yahoo.vespa.model.VespaModel; import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils; import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -48,11 +50,11 @@ public class VespaModelTester { public Hosts addHosts(int count) { return addHosts("default", count); } /** Adds some hosts to this system */ public Hosts addHosts(String flavor, int count) { - Hosts hosts = new Hosts(); + List<Host> hosts = new ArrayList<>(); for (int i = 0; i < count; i++) - hosts.addHost(new com.yahoo.config.model.provision.Host(flavor + i), Collections.emptyList()); - this.hosts.put(flavor.isEmpty() ? "default" : flavor, hosts.getHosts()); - return hosts; + hosts.add(new com.yahoo.config.model.provision.Host(flavor + i)); + this.hosts.put(flavor.isEmpty() ? "default" : flavor, hosts); + return new Hosts(hosts); } /** Creates a model which uses 0 as start index and fails on out of capacity */ |