diff options
Diffstat (limited to 'config-model/src/test/java')
9 files changed, 227 insertions, 193 deletions
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/SummaryTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/SummaryTestCase.java index bfc738a4f87..ef7da4f23d0 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/SummaryTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/SummaryTestCase.java @@ -6,6 +6,7 @@ import com.yahoo.searchdefinition.Search; import com.yahoo.searchdefinition.SearchBuilder; import com.yahoo.searchdefinition.SchemaTestCase; import com.yahoo.searchdefinition.parser.ParseException; +import com.yahoo.vespa.config.search.SummaryConfig; import org.junit.Test; import java.io.IOException; @@ -14,6 +15,7 @@ import java.util.Iterator; import static com.yahoo.config.model.test.TestUtil.joinLines; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * Tests summary extraction @@ -151,4 +153,30 @@ public class SummaryTestCase extends SchemaTestCase { return builder.getSearch("ad"); } + @Test + public void omit_summary_features_specified_for_document_summary() throws ParseException { + String sd = joinLines( + "schema test {", + " document test {", + " field foo type string { indexing: summary }", + " }", + " document-summary bar {", + " summary foo type string {}", + " omit-summary-features", + " }", + " document-summary baz {", + " summary foo type string {}", + " }", + "}"); + var search = SearchBuilder.createFromString(sd).getSearch(); + assertOmitSummaryFeatures(true, search, "bar"); + assertOmitSummaryFeatures(false, search, "baz"); + } + + private void assertOmitSummaryFeatures(boolean expected, Search search, String summaryName) { + var summary = new SummaryClass(search, search.getSummary(summaryName), new BaseDeployLogger()); + var config = new SummaryConfig.Classes(summary.getSummaryClassConfig()); + assertEquals(expected, config.omitsummaryfeatures()); + } + } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/TokenizationTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/TokenizationTestCase.java new file mode 100755 index 00000000000..6fe367ef6d1 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/TokenizationTestCase.java @@ -0,0 +1,19 @@ +// Copyright Verizon media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.derived; + +import com.yahoo.searchdefinition.parser.ParseException; +import org.junit.Test; + +import java.io.IOException; + +/** + * @author bratseh + */ +public class TokenizationTestCase extends AbstractExportingTestCase { + + @Test + public void testTokenizationScripts() throws IOException, ParseException { + assertCorrectDeriving("tokenization"); + } + +} diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/BoolAttributeValidatorTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/BoolAttributeValidatorTestCase.java new file mode 100644 index 00000000000..663aace7b79 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/BoolAttributeValidatorTestCase.java @@ -0,0 +1,49 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.searchdefinition.processing; + +import com.yahoo.searchdefinition.parser.ParseException; +import org.junit.Test; + +import static com.yahoo.searchdefinition.SearchBuilder.createFromString; +import static com.yahoo.config.model.test.TestUtil.joinLines; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * @author geirst + */ +public class BoolAttributeValidatorTestCase { + + @Test + public void array_of_bool_attribute_is_not_supported() throws ParseException { + try { + createFromString(getSd("field b type array<bool> { indexing: attribute }")); + fail("Expected exception"); + } + catch (IllegalArgumentException e) { + assertEquals("For search 'test', field 'b': Only single value bool attribute fields are supported", + e.getMessage()); + } + } + + @Test + public void weigtedset_of_bool_attribute_is_not_supported() throws ParseException { + try { + createFromString(getSd("field b type weightedset<bool> { indexing: attribute }")); + fail("Expected exception"); + } + catch (IllegalArgumentException e) { + assertEquals("For search 'test', field 'b': Only single value bool attribute fields are supported", + e.getMessage()); + } + } + + private String getSd(String field) { + return joinLines("search test {", + " document test {", + " " + field, + " }", + "}"); + } + +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/configserver/ConfigserverClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/configserver/ConfigserverClusterTest.java index 2b55d7a3948..2144c3c9a66 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/configserver/ConfigserverClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/configserver/ConfigserverClusterTest.java @@ -9,6 +9,7 @@ import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.producer.AbstractConfigProducerRoot; import com.yahoo.config.model.test.MockRoot; import com.yahoo.container.StatisticsConfig; +import com.yahoo.container.di.config.PlatformBundlesConfig; import com.yahoo.container.jdisc.config.HealthMonitorConfig; import com.yahoo.net.HostName; import com.yahoo.text.XML; @@ -16,6 +17,7 @@ import com.yahoo.vespa.defaults.Defaults; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.container.Container; import com.yahoo.vespa.model.container.ContainerModel; +import com.yahoo.vespa.model.container.ContainerModelEvaluation; import com.yahoo.vespa.model.container.configserver.option.CloudConfigOptions; import com.yahoo.vespa.model.container.xml.ConfigServerContainerModelBuilder; import org.junit.Test; @@ -27,6 +29,8 @@ import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -124,6 +128,14 @@ public class ConfigserverClusterTest { assertTrue(config.zookeeperLocalhostAffinity()); } + @Test + public void model_evaluation_bundles_are_not_installed_via_config() { + // These bundles must be pre-installed because they are used by config-model. + PlatformBundlesConfig config = getConfig(PlatformBundlesConfig.class); + assertThat(config.bundlePaths(), not(hasItem(ContainerModelEvaluation.MODEL_INTEGRATION_BUNDLE_FILE.toString()))); + assertThat(config.bundlePaths(), not(hasItem(ContainerModelEvaluation.MODEL_EVALUATION_BUNDLE_FILE.toString()))); + } + @SuppressWarnings("varargs") private static <T> void assertZookeeperServerProperty( List<ZookeeperServerConfig.Server> zkServers, Function<ZookeeperServerConfig.Server, T> propertyMapper, T... expectedProperties) { diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/jersey/xml/RestApiTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/jersey/xml/RestApiTest.java deleted file mode 100644 index c858024f749..00000000000 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/jersey/xml/RestApiTest.java +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.container.jersey.xml; - -import com.yahoo.component.ComponentId; -import com.yahoo.config.model.test.TestUtil; -import com.yahoo.container.ComponentsConfig; -import com.yahoo.container.di.config.JerseyBundlesConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; -import com.yahoo.vespa.model.container.component.Component; -import com.yahoo.vespa.model.container.jersey.Jersey2Servlet; -import com.yahoo.vespa.model.container.jersey.RestApi; -import com.yahoo.vespa.model.container.jersey.RestApiContext; -import com.yahoo.vespa.model.container.xml.ContainerModelBuilderTestBase; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.w3c.dom.Element; - -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; - -/** - * @author gjoranv - * @author bjorncs - */ -@Ignore // TODO: remove test -public class RestApiTest extends ContainerModelBuilderTestBase { - private static final String PATH = "rest/api"; - private static final String REST_API_CONTEXT_ID = RestApiContext.CONTAINER_CLASS + "-" + RestApi.idFromPath(PATH); - private static final String INJECTED_COMPONENT_ID = "injectedHandler"; - private static final String CLUSTER_ID = "container"; - - private static final Element restApiXml = TestUtil.parse( - "<container version=\"1.0\" id=\"" + CLUSTER_ID + "\">", - " <rest-api path=\"" + PATH + "\">", - " <components bundle=\"my-jersey-bundle:1.0\">", - " <package>com.yahoo.foo</package>", - " </components>", - " </rest-api>", - " <handler id=\"" + INJECTED_COMPONENT_ID + "\" />", - "</container>"); - - private RestApi restApi; - private Jersey2Servlet servlet; - private RestApiContext context; - - @Before - public void setup() throws Exception { - createModel(root, restApiXml); - root.validate(); - getContainerCluster(CLUSTER_ID).prepare(root.getDeployState()); - restApi = getContainerCluster(CLUSTER_ID).getRestApiMap().values().iterator().next(); - servlet = restApi.getJersey2Servlet(); - context = restApi.getContext(); - } - - @Test - public void jersey2_servlet_has_correct_binding_path() { - assertThat(servlet, not(nullValue())); - assertThat(servlet.bindingPath, is(PATH + "/*")); - } - - @Test - public void jersey2_servlet_has_correct_bundle_spec() { - assertThat(servlet.model.bundleInstantiationSpec.bundle.stringValue(), is(Jersey2Servlet.BUNDLE)); - } - - @Test - public void rest_api_path_is_included_in_servlet_config() { - ServletPathsConfig config = root.getConfig(ServletPathsConfig.class, servlet.getConfigId()); - assertThat(config.servlets(servlet.getComponentId().stringValue()).path(), is(PATH + "/*")); - } - - @Test - public void resource_bundles_are_included_in_config() { - JerseyBundlesConfig config = root.getConfig(JerseyBundlesConfig.class, context.getConfigId()); - assertThat(config.bundles().size(), is(1)); - assertThat(config.bundles(0).spec(), is("my-jersey-bundle:1.0")); - } - - @Test - public void packages_to_scan_are_included_in_config() { - JerseyBundlesConfig config = root.getConfig(JerseyBundlesConfig.class, context.getConfigId()); - assertThat(config.bundles(0).packages(), contains("com.yahoo.foo")); - } - - @Test - public void jersey2_servlet_is_included_in_components_config() { - ComponentsConfig config = root.getConfig(ComponentsConfig.class, CLUSTER_ID); - assertThat(config.toString(), containsString(".id \"" + servlet.getComponentId().stringValue() + "\"")); - } - - @Test - public void restApiContext_is_included_in_components_config() { - ComponentsConfig config = root.getConfig(ComponentsConfig.class, CLUSTER_ID); - assertThat(config.toString(), containsString(".id \"" + REST_API_CONTEXT_ID + "\"")); - } - - @Test - public void all_non_restApi_components_are_injected_to_RestApiContext() { - ComponentsConfig componentsConfig = root.getConfig(ComponentsConfig.class, CLUSTER_ID); - - Set<ComponentId> clusterChildrenComponentIds = getContainerCluster(CLUSTER_ID).getAllComponents().stream() - .map(Component::getComponentId) - .collect(Collectors.toSet()); - - Set<ComponentId> restApiChildrenComponentIds = restApi.getChildren().values().stream() - .map(child -> ((Component<?, ?>) child).getComponentId()) - .collect(Collectors.toSet()); - - //TODO: try replacing with filtering against RestApiContext.isCycleGeneratingComponent - ComponentId cycleInducingComponents = ComponentId.fromString("com.yahoo.container.handler.observability.ApplicationStatusHandler"); - - Set<ComponentId> expectedInjectedConfigIds = new HashSet<>(clusterChildrenComponentIds); - expectedInjectedConfigIds.removeAll(restApiChildrenComponentIds); - expectedInjectedConfigIds.remove(cycleInducingComponents); - - Set<ComponentId> injectedConfigIds = restApiContextConfig(componentsConfig).inject().stream() - .map(inject -> ComponentId.fromString(inject.id())) - .collect(Collectors.toSet()); - - // Verify that the two sets are equal. Split in two asserts to get decent failure messages. - assertThat( - "Not all required components are injected", - injectedConfigIds, - containsInAnyOrder(expectedInjectedConfigIds.toArray())); - assertThat( - "We inject some components that should not be injected", - expectedInjectedConfigIds, - containsInAnyOrder(injectedConfigIds.toArray())); - } - - private static ComponentsConfig.Components restApiContextConfig(ComponentsConfig config) { - return config.components().stream() - .filter(component -> component.classId().equals(RestApiContext.CONTAINER_CLASS)) - .findFirst() - .get(); - } - -} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java index 543318f9224..1af89626199 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java @@ -16,7 +16,6 @@ import com.yahoo.config.model.provision.InMemoryProvisioner; import com.yahoo.config.model.provision.SingleNodeProvisioner; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.model.test.MockRoot; -import com.yahoo.config.provision.Cloud; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.Flavor; import com.yahoo.config.provision.RegionName; @@ -27,6 +26,7 @@ import com.yahoo.container.ComponentsConfig; import com.yahoo.container.QrConfig; import com.yahoo.container.core.ChainsConfig; import com.yahoo.container.core.VipStatusConfig; +import com.yahoo.container.di.config.PlatformBundlesConfig; import com.yahoo.container.handler.VipStatusHandler; import com.yahoo.container.handler.metrics.MetricsV2Handler; import com.yahoo.container.handler.observability.ApplicationStatusHandler; @@ -40,10 +40,6 @@ import com.yahoo.net.HostName; import com.yahoo.path.Path; import com.yahoo.prelude.cluster.QrMonitorConfig; import com.yahoo.search.config.QrStartConfig; -import com.yahoo.security.KeyAlgorithm; -import com.yahoo.security.KeyUtils; -import com.yahoo.security.SignatureAlgorithm; -import com.yahoo.security.X509CertificateBuilder; import com.yahoo.security.X509CertificateUtils; import com.yahoo.security.tls.TlsContext; import com.yahoo.vespa.defaults.Defaults; @@ -52,32 +48,23 @@ import com.yahoo.vespa.model.VespaModel; import com.yahoo.vespa.model.container.ApplicationContainer; import com.yahoo.vespa.model.container.ApplicationContainerCluster; import com.yahoo.vespa.model.container.ContainerCluster; +import com.yahoo.vespa.model.container.ContainerModelEvaluation; import com.yahoo.vespa.model.container.SecretStore; import com.yahoo.vespa.model.container.component.Component; import com.yahoo.vespa.model.container.http.ConnectorFactory; import com.yahoo.vespa.model.content.utils.ContentClusterUtils; import com.yahoo.vespa.model.test.VespaModelTester; import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithFilePkg; -import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; -import org.hamcrest.core.IsEqual; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.w3c.dom.Element; import org.xml.sax.SAXException; -import javax.security.auth.x500.X500Principal; import java.io.IOException; import java.io.StringReader; -import java.math.BigInteger; -import java.security.KeyPair; -import java.security.cert.X509Certificate; import java.time.Duration; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -95,7 +82,6 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; @@ -106,7 +92,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -124,6 +109,14 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase { public TemporaryFolder applicationFolder = new TemporaryFolder(); @Test + public void model_evaluation_bundles_are_deployed() { + createBasicContainerModel(); + PlatformBundlesConfig config = root.getConfig(PlatformBundlesConfig.class, "default"); + assertThat(config.bundlePaths(), hasItem(ContainerModelEvaluation.MODEL_EVALUATION_BUNDLE_FILE.toString())); + assertThat(config.bundlePaths(), hasItem(ContainerModelEvaluation.MODEL_INTEGRATION_BUNDLE_FILE.toString())); + } + + @Test public void deprecated_jdisc_tag_is_allowed() { Element clusterElem = DomBuilderTest.parse( "<jdisc version='1.0'>", @@ -244,10 +237,7 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase { @Test public void verify_bindings_for_builtin_handlers() { - Element clusterElem = DomBuilderTest.parse( - "<container id='default' version='1.0' />" - ); - createModel(root, clusterElem); + createBasicContainerModel(); JdiscBindingsConfig config = root.getConfig(JdiscBindingsConfig.class, "default/container.0"); JdiscBindingsConfig.Handlers defaultRootHandler = config.handlers(BindingsOverviewHandler.class.getName()); @@ -1014,11 +1004,8 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase { tlsPort.getConfig(builder); ConnectorConfig connectorConfig = new ConnectorConfig(builder); - Set<String> expectedCiphers = new HashSet<>(); - expectedCiphers.add("TLS_RSA_WITH_AES_256_GCM_SHA384"); - expectedCiphers.addAll(TlsContext.ALLOWED_CIPHER_SUITES); - assertThat(connectorConfig.ssl().enabledCipherSuites(), containsInAnyOrder(expectedCiphers.toArray())); + assertThat(connectorConfig.ssl().enabledCipherSuites(), containsInAnyOrder(TlsContext.ALLOWED_CIPHER_SUITES.toArray())); } @Test diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java index 9e02572737e..7034176da14 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.model.container.xml; import com.yahoo.collections.Pair; import com.yahoo.component.ComponentId; import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.config.model.builder.xml.test.DomBuilderTest; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.test.MockRoot; import com.yahoo.container.ComponentsConfig; @@ -51,6 +52,11 @@ public abstract class ContainerModelBuilderTestBase { protected MockRoot root; + protected void createBasicContainerModel() { + Element clusterElem = DomBuilderTest.parse("<container id='default' version='1.0' />"); + createModel(root, clusterElem); + } + public static void createModel(MockRoot root, DeployState deployState, VespaModel vespaModel, Element... containerElems) { for (Element containerElem : containerElems) { ContainerModel model = new ContainerModelBuilder(false, ContainerModelBuilder.Networking.enable) diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterResourceLimitsTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterResourceLimitsTest.java index 4324f257922..c0b1a64bace 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterResourceLimitsTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ClusterResourceLimitsTest.java @@ -2,10 +2,13 @@ package com.yahoo.vespa.model.content; import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.application.provider.BaseDeployLogger; +import com.yahoo.config.model.deploy.TestProperties; import com.yahoo.searchdefinition.derived.TestableDeployLogger; import com.yahoo.text.XML; import com.yahoo.vespa.model.builder.xml.dom.ModelElement; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -24,15 +27,23 @@ public class ClusterResourceLimitsTest { private static class Fixture { private final boolean enableFeedBlockInDistributor; + private final boolean hostedVespa; + private final boolean throwIfSpecified; private final ResourceLimits.Builder ctrlBuilder = new ResourceLimits.Builder(); private final ResourceLimits.Builder nodeBuilder = new ResourceLimits.Builder(); public Fixture() { - this.enableFeedBlockInDistributor = false; + this(false); } public Fixture(boolean enableFeedBlockInDistributor) { + this(enableFeedBlockInDistributor, false, false); + } + + public Fixture(boolean enableFeedBlockInDistributor, boolean hostedVespa, boolean throwIfSpecified) { this.enableFeedBlockInDistributor = enableFeedBlockInDistributor; + this.hostedVespa = hostedVespa; + this.throwIfSpecified = throwIfSpecified; } public Fixture ctrlDisk(double limit) { @@ -52,10 +63,13 @@ public class ClusterResourceLimitsTest { return this; } public ClusterResourceLimits build() { + ModelContext.FeatureFlags featureFlags = new TestProperties(); var builder = new ClusterResourceLimits.Builder(enableFeedBlockInDistributor, - false, - false, - new BaseDeployLogger()); + hostedVespa, + throwIfSpecified, + new BaseDeployLogger(), + featureFlags.resourceLimitDisk(), + featureFlags.resourceLimitMemory()); builder.setClusterControllerBuilder(ctrlBuilder); builder.setContentNodeBuilder(nodeBuilder); return builder.build(); @@ -130,27 +144,86 @@ public class ClusterResourceLimitsTest { } @Test - public void exception_is_thrown_when_resource_limits_are_specified() { + @Ignore // TODO: Remove hosted_limits_are_used_if_app_is_allowed_to_set_limits and enable this when code is fixed to do so + public void hosted_log_when_resource_limits_are_specified() { TestableDeployLogger logger = new TestableDeployLogger(); - buildClusterResourceLimitsAndLogIfSpecified(logger); + var limits = hostedBuildAndLogIfSpecified(logger); assertEquals(1, logger.warnings.size()); assertEquals("Element 'resource-limits' is not allowed to be set", logger.warnings.get(0)); + // Verify that default limits are used + assertLimits(0.8, 0.8, limits.getClusterControllerLimits()); + assertLimits(0.9, 0.9, limits.getContentNodeLimits()); + } + + @Test + public void hosted_exception_is_thrown_when_resource_limits_are_specified() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage(containsString("Element 'resource-limits' is not allowed to be set")); - buildClusterResourceLimitsAndThrowIfSpecified(logger); + hostedBuildAndThrowIfSpecified(); + } + + @Test + // TODO: Remove this and enable hosted_log_when_resource_limits_are_specified when code is fixed to do so + public void hosted_limits_are_used_if_app_is_allowed_to_set_limits() { + TestableDeployLogger logger = new TestableDeployLogger(); + + var limits = hostedBuildAndLogIfSpecified(logger); + assertEquals(1, logger.warnings.size()); + assertEquals("Element 'resource-limits' is not allowed to be set", logger.warnings.get(0)); + + // Verify that limits in XML are used + assertLimits(0.8, 0.92, limits.getClusterControllerLimits()); + assertLimits(0.9, 0.96, limits.getContentNodeLimits()); + } + + @Test + public void hosted_limits_from_feature_flag_are_used() { + TestableDeployLogger logger = new TestableDeployLogger(); + + TestProperties featureFlags = new TestProperties(); + featureFlags.setResourceLimitDisk(0.85); + featureFlags.setResourceLimitMemory(0.90); + var limits = hostedBuild(false, logger, featureFlags, false); + + // Verify that limits from feature flags are used + assertLimits(0.85, 0.90, limits.getClusterControllerLimits()); + assertLimits(0.925, 0.95, limits.getContentNodeLimits()); } - private void buildClusterResourceLimitsAndThrowIfSpecified(DeployLogger deployLogger) { - buildClusterResourceLimits(true, deployLogger); + @Test + public void exception_is_thrown_when_resource_limits_are_out_of_range() { + TestableDeployLogger logger = new TestableDeployLogger(); + + TestProperties featureFlags = new TestProperties(); + featureFlags.setResourceLimitDisk(1.1); + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(containsString("Resource limit for disk is set to illegal value 1.1, but must be in the range [0.0, 1.0]")); + hostedBuild(false, logger, featureFlags, false); + + featureFlags = new TestProperties(); + featureFlags.setResourceLimitDisk(-0.1); + expectedException.expectMessage(containsString("Resource limit for disk is set to illegal value -0.1, but must be in the range [0.0, 1.0]")); + hostedBuild(false, logger, featureFlags, false); + } + + private void hostedBuildAndThrowIfSpecified() { + hostedBuild(true, new TestableDeployLogger(), new TestProperties(), true); } - private void buildClusterResourceLimitsAndLogIfSpecified(DeployLogger deployLogger) { - buildClusterResourceLimits(false, deployLogger); + private ClusterResourceLimits hostedBuildAndLogIfSpecified(DeployLogger deployLogger) { + return hostedBuild(false, deployLogger); } - private void buildClusterResourceLimits(boolean throwIfSpecified, DeployLogger deployLogger) { + private ClusterResourceLimits hostedBuild(boolean throwIfSpecified, DeployLogger deployLogger) { + return hostedBuild(throwIfSpecified, deployLogger, new TestProperties(), true); + } + + private ClusterResourceLimits hostedBuild(boolean throwIfSpecified, + DeployLogger deployLogger, + ModelContext.FeatureFlags featureFlags, + boolean limitsInXml) { Document clusterXml = XML.getDocument("<cluster id=\"test\">" + " <tuning>\n" + " <resource-limits>\n" + @@ -159,11 +232,16 @@ public class ClusterResourceLimitsTest { " </tuning>\n" + "</cluster>"); + Document noLimitsXml = XML.getDocument("<cluster id=\"test\">" + + "</cluster>"); + ClusterResourceLimits.Builder builder = new ClusterResourceLimits.Builder(true, true, throwIfSpecified, - deployLogger); - builder.build(new ModelElement(clusterXml.getDocumentElement())); + deployLogger, + featureFlags.resourceLimitDisk(), + featureFlags.resourceLimitMemory()); + return builder.build(new ModelElement((limitsInXml ? clusterXml : noLimitsXml).getDocumentElement())); } private void assertLimits(Double expCtrlDisk, Double expCtrlMemory, Double expNodeDisk, Double expNodeMemory, Fixture f) { @@ -173,15 +251,15 @@ public class ClusterResourceLimitsTest { } private void assertLimits(Double expDisk, Double expMemory, ResourceLimits limits) { - assertLimit(expDisk, limits.getDiskLimit()); - assertLimit(expMemory, limits.getMemoryLimit()); + assertLimit(expDisk, limits.getDiskLimit(), "disk"); + assertLimit(expMemory, limits.getMemoryLimit(), "memory"); } - private void assertLimit(Double expLimit, Optional<Double> actLimit) { + private void assertLimit(Double expLimit, Optional<Double> actLimit, String limitType) { if (expLimit == null) { assertFalse(actLimit.isPresent()); } else { - assertEquals(expLimit, actLimit.get(), 0.00001); + assertEquals(limitType + " limit not as expected", expLimit, actLimit.get(), 0.00001); } } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/FleetControllerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/FleetControllerClusterTest.java index 10bb00168bb..dedf344c546 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/FleetControllerClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/FleetControllerClusterTest.java @@ -1,6 +1,7 @@ // Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.content; +import com.yahoo.config.model.api.ModelContext; import com.yahoo.config.model.application.provider.BaseDeployLogger; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.deploy.TestProperties; @@ -22,12 +23,15 @@ public class FleetControllerClusterTest { new TestProperties().enableFeedBlockInDistributor(enableFeedBlockInDistributor)).build(); MockRoot root = new MockRoot("", deployState); var clusterElement = new ModelElement(doc.getDocumentElement()); + ModelContext.FeatureFlags featureFlags = new TestProperties(); return new ClusterControllerConfig.Builder("storage", clusterElement, new ClusterResourceLimits.Builder(enableFeedBlockInDistributor, false, false, - new BaseDeployLogger()) + new BaseDeployLogger(), + featureFlags.resourceLimitDisk(), + featureFlags.resourceLimitMemory()) .build(clusterElement).getClusterControllerLimits()) .build(root.getDeployState(), root, clusterElement.getXml()); } |