diff options
61 files changed, 699 insertions, 814 deletions
diff --git a/cloud-tenant-base-dependencies-enforcer/pom.xml b/cloud-tenant-base-dependencies-enforcer/pom.xml index 2025431d86c..99aa3f9e1b2 100644 --- a/cloud-tenant-base-dependencies-enforcer/pom.xml +++ b/cloud-tenant-base-dependencies-enforcer/pom.xml @@ -246,7 +246,7 @@ <include>org.apache.httpcomponents.client5:httpclient5:${httpclient5.version}:jar:test</include> <include>org.apache.httpcomponents.core5:httpcore5:${httpclient5.version}:jar:test</include> <include>org.apache.httpcomponents.core5:httpcore5-h2:${httpclient5.version}:jar:test</include> - <include>org.apache.httpcomponents:httpclient:4.5.12:jar:test</include> + <include>org.apache.httpcomponents:httpclient:4.5.13:jar:test</include> <include>org.apache.httpcomponents:httpcore:4.4.13:jar:test</include> <include>org.apache.opennlp:opennlp-tools:1.9.3:jar:test</include> <include>org.apiguardian:apiguardian-api:1.1.0:jar:test</include> diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java index 9fef9b4615d..a0dba36fef5 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java @@ -113,6 +113,7 @@ public interface ModelContext { @ModelFeatureFlag(owners = {"baldersheim", "geirst", "toregge"}) default int maxCompactBuffers() { return 1; } @ModelFeatureFlag(owners = {"hmusum"}) default boolean failDeploymentWithInvalidJvmOptions() { return false; } @ModelFeatureFlag(owners = {"baldersheim"}) default double tlsSizeFraction() { throw new UnsupportedOperationException("TODO specify default value"); } + @ModelFeatureFlag(owners = {"arnej", "andreer"}) default List<String> ignoredHttpUserAgents() { return List.of(); } @ModelFeatureFlag(owners = {"bjorncs"}) default boolean enableServerOcspStapling() { return false; } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java index 3ac90673bb6..5c5b065ac29 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java @@ -94,7 +94,7 @@ public abstract class Container extends AbstractService implements this.index = index; dumpHeapOnShutdownTimeout = deployState.featureFlags().containerDumpHeapOnShutdownTimeout(); shutdownTimeoutS = deployState.featureFlags().containerShutdownTimeout(); - this.defaultHttpServer = new JettyHttpServer("DefaultHttpServer", containerClusterOrNull(parent), deployState.isHosted()); + this.defaultHttpServer = new JettyHttpServer("DefaultHttpServer", containerClusterOrNull(parent), deployState); if (getHttp() == null) { addChild(defaultHttpServer); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java index d84884665ef..7b91b4b3244 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/JettyHttpServer.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.container.http; +import com.yahoo.config.model.deploy.DeployState; import com.yahoo.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.container.bundle.BundleInstantiationSpecification; @@ -25,13 +26,16 @@ public class JettyHttpServer extends SimpleComponent implements ServerConfig.Pro private final List<ConnectorFactory> connectorFactories = new ArrayList<>(); private final List<String> ignoredUserAgentsList = new ArrayList<>(); - public JettyHttpServer(String componentId, ContainerCluster<?> cluster, boolean isHostedVespa) { + public JettyHttpServer(String componentId, ContainerCluster<?> cluster, DeployState deployState) { super(new ComponentModel(componentId, com.yahoo.jdisc.http.server.jetty.JettyHttpServer.class.getName(), null)); - this.isHostedVespa = isHostedVespa; + this.isHostedVespa = deployState.isHosted(); this.cluster = cluster; final FilterBindingsProviderComponent filterBindingsProviderComponent = new FilterBindingsProviderComponent(componentId); addChild(filterBindingsProviderComponent); inject(filterBindingsProviderComponent); + for (String agent : deployState.featureFlags().ignoredHttpUserAgents()) { + addIgnoredUserAgent(agent); + } } public void setHostedVespa(boolean isHostedVespa) { this.isHostedVespa = isHostedVespa; } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java index 07f4334b542..1518683908b 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/JettyHttpServerBuilder.java @@ -24,7 +24,7 @@ public class JettyHttpServerBuilder extends VespaDomBuilder.DomConfigProducerBui @Override protected JettyHttpServer doBuild(DeployState deployState, AbstractConfigProducer<?> ancestor, Element http) { - JettyHttpServer jettyHttpServer = new JettyHttpServer("jdisc-jetty", cluster, deployState.isHosted()); + JettyHttpServer jettyHttpServer = new JettyHttpServer("jdisc-jetty", cluster, deployState); for (Element serverSpec: XML.getChildren(http, "server")) { ConnectorFactory connectorFactory = new JettyConnectorBuilder().build(deployState, ancestor, serverSpec); jettyHttpServer.addConnector(connectorFactory); 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 2da68262fe7..7f0948cccda 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 @@ -187,7 +187,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { addConfiguredComponents(deployState, cluster, spec); addSecretStore(cluster, spec, deployState); - addServlets(deployState, spec, cluster); addModelEvaluation(spec, cluster, context); addModelEvaluationBundles(cluster); @@ -426,7 +425,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { cluster.setHttp(buildHttp(deployState, cluster, httpElement)); } if (isHostedTenantApplication(context)) { - addHostedImplicitHttpIfNotPresent(cluster); + addHostedImplicitHttpIfNotPresent(deployState, cluster); addHostedImplicitAccessControlIfNotPresent(deployState, cluster); addDefaultConnectorHostedFilterBinding(cluster); addAdditionalHostedConnector(deployState, cluster, context); @@ -488,13 +487,13 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return deployState.isHosted() && context.getApplicationType() == ApplicationType.DEFAULT && !isTesterApplication; } - private static void addHostedImplicitHttpIfNotPresent(ApplicationContainerCluster cluster) { + private static void addHostedImplicitHttpIfNotPresent(DeployState deployState, ApplicationContainerCluster cluster) { if (cluster.getHttp() == null) { cluster.setHttp(new Http(new FilterChains(cluster))); } JettyHttpServer httpServer = cluster.getHttp().getHttpServer().orElse(null); if (httpServer == null) { - httpServer = new JettyHttpServer("DefaultHttpServer", cluster, cluster.isHostedVespa()); + httpServer = new JettyHttpServer("DefaultHttpServer", cluster, deployState); cluster.getHttp().setHttpServer(httpServer); } int defaultPort = Defaults.getDefaults().vespaWebServicePort(); @@ -527,12 +526,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return http; } - // TODO Vespa 8: Remove - private void addServlets(DeployState deployState, Element spec, ApplicationContainerCluster cluster) { - if (XML.getChildren(spec, "servlet").size() > 0) - throw new IllegalArgumentException("The 'servlet' tag is no longer supported in services.xml. Please use a handler instead."); - } - private void addDocumentApi(Element spec, ApplicationContainerCluster cluster) { ContainerDocumentApi containerDocumentApi = buildDocumentApi(cluster, spec); if (containerDocumentApi == null) return; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/generic/GenericServicesBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/generic/GenericServicesBuilder.java index 77acffe7f9d..7a0278faa48 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/generic/GenericServicesBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/generic/GenericServicesBuilder.java @@ -13,6 +13,8 @@ import java.util.List; /** * @author Ulf Lilleengen * @since 5.1 + * + * TODO: remove in Vespa 8 */ public class GenericServicesBuilder extends ConfigModelBuilder<GenericServicesModel> { @@ -22,7 +24,7 @@ public class GenericServicesBuilder extends ConfigModelBuilder<GenericServicesMo @Override public List<ConfigModelId> handlesElements() { - return Arrays.asList(ConfigModelId.fromName("service")); + return List.of(ConfigModelId.fromName("service")); } @Override diff --git a/config-model/src/main/java/com/yahoo/vespa/model/generic/builder/DomServiceClusterBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/generic/builder/DomServiceClusterBuilder.java index ea2151648cc..1ac668049f0 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/generic/builder/DomServiceClusterBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/generic/builder/DomServiceClusterBuilder.java @@ -8,10 +8,13 @@ import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder; import com.yahoo.vespa.model.generic.service.ServiceCluster; import org.w3c.dom.Element; import java.util.Map; +import java.util.logging.Level; /** -* @author Ulf Lilleengen -*/ + * @author Ulf Lilleengen + * + * TODO: remove in Vespa 8 + */ public class DomServiceClusterBuilder extends VespaDomBuilder.DomConfigProducerBuilder<ServiceCluster> { private final String name; @@ -22,6 +25,9 @@ public class DomServiceClusterBuilder extends VespaDomBuilder.DomConfigProducerB @Override protected ServiceCluster doBuild(DeployState deployState, AbstractConfigProducer<?> ancestor, Element spec) { + deployState.getDeployLogger().logApplicationPackage( + Level.WARNING, "The 'service' element is deprecated and will be removed in Vespa 8, without replacement."); + ServiceCluster cluster = new ServiceCluster(ancestor, name, spec.getAttribute("command")); int nodeIndex = 0; for (Element nodeSpec : XML.getChildren(spec, "node")) { diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc index b06bf0897cf..e8ff1721397 100644 --- a/config-model/src/main/resources/schema/containercluster.rnc +++ b/config-model/src/main/resources/schema/containercluster.rnc @@ -12,7 +12,6 @@ ContainerCluster = element container | jdisc { } ContainerServices = - Servlet* & SearchInContainer? & DocprocInContainer? & ProcessingInContainer? & @@ -136,18 +135,6 @@ Threadpool = element threadpool { element queue-size { xsd:nonNegativeInteger } } -# Servlet: - -Servlet = element servlet { - ComponentDefinition & - ServletConfig? & - element path { xsd:string { pattern = "\w[\w_/\-\.]*(\*)?" } } -} - -ServletConfig = element servlet-config { - anyElement+ -} - # SEARCH: SearchInContainer = element search { diff --git a/config-model/src/test/schema-test-files/services.xml b/config-model/src/test/schema-test-files/services.xml index b477ceef169..9ccf50de906 100644 --- a/config-model/src/test/schema-test-files/services.xml +++ b/config-model/src/test/schema-test-files/services.xml @@ -58,20 +58,6 @@ <group name="foo" environment="aws_stage" /> </secret-store> - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>p/a/t/h</path> - </servlet> - - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>Apps/app_1.3-4/*</path> - <config name="foo"> - <intVal>0</intVal> - </config> - <servlet-config> - <foo>bar</foo> - </servlet-config> - </servlet> - <http> <filtering strict-mode="true"> <access-control domain="my.athens-domain" read="true"> diff --git a/config-model/src/test/schema-test-files/standalone-container.xml b/config-model/src/test/schema-test-files/standalone-container.xml index 85f577882fb..cc34ae43712 100644 --- a/config-model/src/test/schema-test-files/standalone-container.xml +++ b/config-model/src/test/schema-test-files/standalone-container.xml @@ -2,20 +2,6 @@ <!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> <container id='qrsCluster_1' version='1.0'> - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>p/a/t/h</path> - </servlet> - - <servlet id="my-servlet" class="com.yahoo.MyServlet" bundle="my-bundle"> - <path>Apps/app_1.3-4/*</path> - <config name="foo"> - <intVal>0</intVal> - </config> - <servlet-config> - <foo>bar</foo> - </servlet-config> - </servlet> - <http> <filtering> <filter id="com.yahoo.YcaFilter" bundle="mybundle"> diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java index 01008f0a8a2..4bf442a0890 100644 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java @@ -434,8 +434,8 @@ public class ConfigSubscriber implements AutoCloseable { } /** - * Use this convenience method if you only want to subscribe on <em>one</em> config, and want generic error handling. - * Implement {@link SingleSubscriber} and pass to this method. + * Convenience method that can be used if you only want to subscribe to <em>one</em> config, and want generic error handling. + * Implement {@link SingleSubscriber} and pass it to this method. * You will get initial config, and a config thread will be started. The method will throw in your thread if initial * configuration fails, and the config thread will print a generic error message (but continue) if it fails thereafter. The config * thread will stop if you {@link #close()} this {@link ConfigSubscriber}. diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java index 68e22ad5656..a18f1b4b260 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java @@ -36,10 +36,9 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc private Instant lastOK = Instant.MIN; /** - * A queue containing either zero or one (the newest) request that got a callback from JRT, - * but has not yet been handled. + * A queue containing responses (requests that got a callback from JRT) that has not yet been handled. */ - private BlockingQueue<JRTClientConfigRequest> reqQueue = new LinkedBlockingQueue<>(); + private BlockingQueue<JRTClientConfigRequest> responseQueue = new LinkedBlockingQueue<>(); public JRTConfigSubscription(ConfigKey<T> key, JRTConfigRequester requester, TimingValues timingValues) { super(key); @@ -49,31 +48,40 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc @Override public boolean nextConfig(long timeoutMillis) { - // Note: since the JRT callback thread will clear the queue first when it inserts a brand new element, - // (see #updateConfig()) there is a race here. However: the caller will handle it no matter what it gets - // from the queue here, the important part is that local state on the subscription objects is preserved. + JRTClientConfigRequest response = pollForNewConfig(timeoutMillis); + if (response == null) return newConfigOrException(); - // Poll the queue for a next config until timeout - JRTClientConfigRequest jrtReq = pollQueue(timeoutMillis); - if (jrtReq == null) return newConfigOrException(); - - log.log(FINE, () -> "Polled queue and found config " + jrtReq); + log.log(FINE, () -> "Polled queue and found config " + response); // Might set the following (caller must check): // generation, generation changed, config, config changed // Important: it never <em>resets</em> those flags, we must persist that state until the // ConfigSubscriber clears it - if (jrtReq.hasUpdatedGeneration()) { - setApplyOnRestart(jrtReq.responseIsApplyOnRestart()); - if (jrtReq.hasUpdatedConfig()) { - setNewConfig(jrtReq); + if (response.hasUpdatedGeneration()) { + setApplyOnRestart(response.responseIsApplyOnRestart()); + if (response.hasUpdatedConfig()) { + setNewConfig(response); } else { - setNewConfigAndGeneration(jrtReq); + setNewConfigAndGeneration(response); } } return newConfigOrException(); } + private JRTClientConfigRequest pollForNewConfig(long timeoutMillis) { + JRTClientConfigRequest response = pollQueue(timeoutMillis); + // There might be more than one response on the queue, so empty queue by polling with + // 0 timeout until queue is empty (returned value is null) + JRTClientConfigRequest temp; + do { + temp = pollQueue(0); + if (temp != null) + response = temp; + } while (temp != null); + + return response; + } + private boolean newConfigOrException() { // These flags may have been left true from a previous call, since ConfigSubscriber's nextConfig // not necessarily returned true and reset the flags then @@ -89,7 +97,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc private JRTClientConfigRequest pollQueue(long timeoutMillis) { try { // Only valid responses are on queue, no need to validate - return reqQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS); + return responseQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e1) { throw new ConfigInterruptedException(e1); } @@ -133,11 +141,9 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc return configInstance; } - // Will be called by JRTConfigRequester when there is a config with new generation for this subscription + // Called by JRTConfigRequester when there is a config with new generation for this subscription void updateConfig(JRTClientConfigRequest jrtReq) { - // We only want this latest generation to be in the queue, we do not preserve history in this system - reqQueue.clear(); - if ( ! reqQueue.offer(jrtReq)) + if ( ! responseQueue.offer(jrtReq)) setException(new ConfigurationRuntimeException("Failed offering returned request to queue of subscription " + this)); } @@ -145,14 +151,14 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc public boolean subscribe(long timeout) { lastOK = Instant.now(); requester.request(this); - JRTClientConfigRequest req = reqQueue.peek(); + JRTClientConfigRequest req = responseQueue.peek(); while (req == null && (Instant.now().isBefore(lastOK.plus(Duration.ofMillis(timeout))))) { try { Thread.sleep(10); } catch (InterruptedException e) { throw new ConfigInterruptedException(e); } - req = reqQueue.peek(); + req = responseQueue.peek(); } return req != null; } @@ -160,11 +166,11 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc @Override public void close() { super.close(); - reqQueue = new LinkedBlockingQueue<>() { + responseQueue = new LinkedBlockingQueue<>() { @SuppressWarnings("NullableProblems") @Override public void put(JRTClientConfigRequest e) { - // When closed, throw away all requests that callbacks try to put + // When closed, throw away all responses that callbacks try to put on queue } }; } diff --git a/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java b/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java index fc922cc3b07..61573fd19be 100644 --- a/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/GenericConfigSubscriberTest.java @@ -33,7 +33,7 @@ public class GenericConfigSubscriberTest { public void testSubscribeGeneric() throws InterruptedException { JRTConfigRequester requester = new JRTConfigRequester(new MockConnection(), tv); GenericConfigSubscriber sub = new GenericConfigSubscriber(requester); - final List<String> defContent = List.of("myVal int"); + List<String> defContent = List.of("myVal int"); GenericConfigHandle handle = sub.subscribe(new ConfigKey<>("simpletypes", "id", "config"), defContent, tv); @@ -46,9 +46,9 @@ public class GenericConfigSubscriberTest { assertFalse(handle.isChanged()); // Wait some time, config should be the same, but generation should be higher - Thread.sleep(tv.getFixedDelay() * 2); + Thread.sleep(tv.getFixedDelay() * 3); assertEquals("{}", getConfig(handle)); - assertTrue(handle.getRawConfig().getGeneration() > 1); + assertTrue("Unexpected generation (not > 1): " + handle.getRawConfig().getGeneration(), handle.getRawConfig().getGeneration() > 1); assertFalse(sub.nextConfig(false)); assertFalse(handle.isChanged()); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java index d69fe4fba89..a77a8d1b5b8 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java @@ -205,6 +205,7 @@ public class ModelContextImpl implements ModelContext { private final int maxCompactBuffers; private final boolean failDeploymentWithInvalidJvmOptions; private final double tlsSizeFraction; + private final List<String> ignoredHttpUserAgents; private final boolean enableServerOcspStapling; public FeatureFlags(FlagSource source, ApplicationId appId) { @@ -249,6 +250,7 @@ public class ModelContextImpl implements ModelContext { this.maxCompactBuffers = flagValue(source, appId, Flags.MAX_COMPACT_BUFFERS); this.failDeploymentWithInvalidJvmOptions = flagValue(source, appId, Flags.FAIL_DEPLOYMENT_WITH_INVALID_JVM_OPTIONS); this.tlsSizeFraction = flagValue(source, appId, Flags.TLS_SIZE_FRACTION); + this.ignoredHttpUserAgents = flagValue(source, appId, PermanentFlags.IGNORED_HTTP_USER_AGENTS); this.enableServerOcspStapling = flagValue(source, appId, Flags.ENABLE_SERVER_OCSP_STAPLING); } @@ -295,6 +297,7 @@ public class ModelContextImpl implements ModelContext { @Override public boolean failDeploymentWithInvalidJvmOptions() { return failDeploymentWithInvalidJvmOptions; } @Override public int maxCompactBuffers() { return maxCompactBuffers; } @Override public double tlsSizeFraction() { return tlsSizeFraction; } + @Override public List<String> ignoredHttpUserAgents() { return ignoredHttpUserAgents; } @Override public boolean enableServerOcspStapling() { return enableServerOcspStapling; } private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) { diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index 174febca9df..d5be3ab52f2 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -2090,100 +2090,6 @@ "public static final java.lang.String[] CONFIG_DEF_SCHEMA" ] }, - "com.yahoo.jdisc.http.ServletPathsConfig$Builder": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.config.ConfigInstance$Builder" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Builder servlets(java.lang.String, com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Builder servlets(java.util.Map)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Builder servlets(java.lang.String, java.util.function.Consumer)", - "public final boolean dispatchGetConfig(com.yahoo.config.ConfigInstance$Producer)", - "public final java.lang.String getDefMd5()", - "public final java.lang.String getDefName()", - "public final java.lang.String getDefNamespace()", - "public final boolean getApplyOnRestart()", - "public final void setApplyOnRestart(boolean)", - "public com.yahoo.jdisc.http.ServletPathsConfig build()" - ], - "fields": [ - "public java.util.Map servlets" - ] - }, - "com.yahoo.jdisc.http.ServletPathsConfig$Producer": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.config.ConfigInstance$Producer" - ], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract void getConfig(com.yahoo.jdisc.http.ServletPathsConfig$Builder)" - ], - "fields": [] - }, - "com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.config.ConfigBuilder" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig$Servlets)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder path(java.lang.String)", - "public com.yahoo.jdisc.http.ServletPathsConfig$Servlets build()" - ], - "fields": [] - }, - "com.yahoo.jdisc.http.ServletPathsConfig$Servlets": { - "superClass": "com.yahoo.config.InnerNode", - "interfaces": [], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig$Servlets$Builder)", - "public java.lang.String path()" - ], - "fields": [] - }, - "com.yahoo.jdisc.http.ServletPathsConfig": { - "superClass": "com.yahoo.config.ConfigInstance", - "interfaces": [], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public static java.lang.String getDefMd5()", - "public static java.lang.String getDefName()", - "public static java.lang.String getDefNamespace()", - "public static java.lang.String getDefVersion()", - "public void <init>(com.yahoo.jdisc.http.ServletPathsConfig$Builder)", - "public java.util.Map servlets()", - "public com.yahoo.jdisc.http.ServletPathsConfig$Servlets servlets(java.lang.String)" - ], - "fields": [ - "public static final java.lang.String CONFIG_DEF_MD5", - "public static final java.lang.String CONFIG_DEF_NAME", - "public static final java.lang.String CONFIG_DEF_NAMESPACE", - "public static final java.lang.String CONFIG_DEF_VERSION", - "public static final java.lang.String[] CONFIG_DEF_SCHEMA" - ] - }, "com.yahoo.jdisc.http.filter.DiscFilterRequest$ThreadLocalSimpleDateFormat": { "superClass": "java.lang.ThreadLocal", "interfaces": [], diff --git a/container-core/src/main/java/com/yahoo/container/servlet/package-info.java b/container-core/src/main/java/com/yahoo/container/servlet/package-info.java deleted file mode 100644 index 8ecb3cbe827..00000000000 --- a/container-core/src/main/java/com/yahoo/container/servlet/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -// TODO Vespa 8 Remove export package -@ExportPackage -package com.yahoo.container.servlet; - -import com.yahoo.osgi.annotation.ExportPackage; - diff --git a/container-core/src/main/resources/configdefinitions/container.servlet.servlet-config.def b/container-core/src/main/resources/configdefinitions/container.servlet.servlet-config.def deleted file mode 100644 index 3cc65475913..00000000000 --- a/container-core/src/main/resources/configdefinitions/container.servlet.servlet-config.def +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# TODO Vespa 8 Remove config definition -namespace=container.servlet -map{} string - diff --git a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.servlet-paths.def b/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.servlet-paths.def deleted file mode 100644 index af788764364..00000000000 --- a/container-core/src/main/resources/configdefinitions/jdisc.http.jdisc.http.servlet-paths.def +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# TODO Vespa 8 Remove config definition -namespace=jdisc.http - -# path by servlet componentId -servlets{}.path string diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java index d5229add01b..c975f7c17c3 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java @@ -22,7 +22,6 @@ import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.HttpResponse; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.filter.ResponseHeaderFilter; @@ -585,7 +584,6 @@ public class FilterTestCase { bind(FilterBindings.class).toInstance(filterBindings); bind(ServerConfig.class).toInstance(new ServerConfig(new ServerConfig.Builder().strictFiltering(strictFiltering))); bind(ConnectorConfig.class).toInstance(new ConnectorConfig(new ConnectorConfig.Builder())); - bind(ServletPathsConfig.class).toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); bind(ConnectionLog.class).toInstance(new VoidConnectionLog()); bind(RequestLog.class).toInstance(new VoidRequestLog()); } diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java index 613c5e88cf2..baf198dde5d 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java @@ -7,7 +7,6 @@ import com.google.inject.util.Modules; import com.yahoo.container.logging.ConnectionLog; import com.yahoo.container.logging.RequestLog; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.http.server.jetty.testutils.ConnectorFactoryRegistryModule; import com.yahoo.jdisc.test.ServerProviderConformanceTest; import org.apache.http.HttpResponse; @@ -773,8 +772,6 @@ public class HttpServerConformanceTest extends ServerProviderConformanceTest { .toInstance(new FilterBindings.Builder().build()); bind(ServerConfig.class) .toInstance(new ServerConfig(new ServerConfig.Builder())); - bind(ServletPathsConfig.class) - .toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); bind(ConnectionLog.class) .toInstance(new VoidConnectionLog()); bind(RequestLog.class) diff --git a/container-search/pom.xml b/container-search/pom.xml index 67400208db1..14f306983f8 100644 --- a/container-search/pom.xml +++ b/container-search/pom.xml @@ -26,11 +26,6 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest-library</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>com.yahoo.vespa</groupId> <artifactId>provided-dependencies</artifactId> <version>${project.version}</version> diff --git a/container-search/src/test/java/com/yahoo/prelude/test/QueryTestCase.java b/container-search/src/test/java/com/yahoo/prelude/test/QueryTestCase.java index d9e3cf84726..d5efd3992b2 100644 --- a/container-search/src/test/java/com/yahoo/prelude/test/QueryTestCase.java +++ b/container-search/src/test/java/com/yahoo/prelude/test/QueryTestCase.java @@ -14,15 +14,11 @@ import com.yahoo.search.Query; import com.yahoo.search.query.Sorting; import com.yahoo.search.searchchain.Execution; import com.yahoo.yolean.Exceptions; -import org.hamcrest.Matcher; import org.junit.Ignore; import org.junit.Test; import java.util.List; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.anyOf; - import static org.junit.Assert.*; /** @@ -158,21 +154,21 @@ public class QueryTestCase { public void testInvalidSortFunction() { assertQueryError( "?query=test&sortspec=-ucca(name,en_US)", - containsString("Could not set 'ranking.sorting' to '-ucca(name,en_US)': Unknown sort function 'ucca'")); + "Could not set 'ranking.sorting' to '-ucca(name,en_US)': Unknown sort function 'ucca'"); } @Test public void testMissingSortFunction() { assertQueryError( "?query=test&sortspec=-(name)", - containsString("Could not set 'ranking.sorting' to '-(name)': No sort function specified")); + "Could not set 'ranking.sorting' to '-(name)': No sort function specified"); } @Test public void testInvalidUcaStrength() { assertQueryError( "?query=test&sortspec=-uca(name,en_US,tertary)", - containsString("Could not set 'ranking.sorting' to '-uca(name,en_US,tertary)': Unknown collation strength: 'tertary'")); + "Could not set 'ranking.sorting' to '-uca(name,en_US,tertary)': Unknown collation strength: 'tertary'"); } public void checkSortSpecUcaUSOptional(String spec) { @@ -224,60 +220,56 @@ public class QueryTestCase { public void testNegativeHitValue() { assertQueryError( "?query=test&hits=-1", - containsString("Could not set 'hits' to '-1': Must be a positive number")); + "Could not set 'hits' to '-1': Must be a positive number"); } @Test public void testNaNHitValue() { assertQueryError( "?query=test&hits=NaN", - containsString("Could not set 'hits' to 'NaN': 'NaN' is not a valid integer")); + "Could not set 'hits' to 'NaN': 'NaN' is not a valid integer"); } @Test public void testNoneHitValue() { assertQueryError( "?query=test&hits=(none)", - containsString("Could not set 'hits' to '(none)': '(none)' is not a valid integer")); + "Could not set 'hits' to '(none)': '(none)' is not a valid integer"); } @Test public void testNegativeOffsetValue() { assertQueryError( "?query=test&offset=-1", - containsString("Could not set 'offset' to '-1': Must be a positive number")); + "Could not set 'offset' to '-1': Must be a positive number"); } @Test public void testNaNOffsetValue() { assertQueryError( "?query=test&offset=NaN", - containsString("Could not set 'offset' to 'NaN': 'NaN' is not a valid integer")); + "Could not set 'offset' to 'NaN': 'NaN' is not a valid integer"); } @Test public void testNoneOffsetValue() { assertQueryError( "?query=test&offset=(none)", - containsString("Could not set 'offset' to '(none)': '(none)' is not a valid integer")); + "Could not set 'offset' to '(none)': '(none)' is not a valid integer"); } @Test public void testNoneHitsNegativeOffsetValue() { assertQueryError( "?query=test&hits=(none)&offset=-10", - anyOf( - containsString("Could not set 'offset' to '-10': Must be a positive number"), - containsString("Could not set 'hits' to '(none)': '(none)' is not a valid integer"))); + "Could not set 'hits' to '(none)': '(none)' is not a valid integer"); } @Test public void testFeedbackIsTransferredToResult() { assertQueryError( "?query=test&hits=(none)&offset=-10", - anyOf( - containsString("Could not set 'hits' to '(none)': '(none)' is not a valid integer"), - containsString("Could not set 'offset' to '-10': Must be a positive number"))); + "Could not set 'hits' to '(none)': '(none)' is not a valid integer"); } @Test @@ -300,7 +292,7 @@ public class QueryTestCase { @Test @Ignore public void testPrivateUseCharacterParsing() { - Query query=newQuery("?query=%EF%89%AB"); + Query query = newQuery("?query=%EF%89%AB"); assertEquals(Character.UnicodeBlock.PRIVATE_USE_AREA, Character.UnicodeBlock.of(query.getModel().getQueryTree().getRoot().toString().charAt(0))); } @@ -309,7 +301,7 @@ public class QueryTestCase { @Test @Ignore public void testOtherCharactersParsing() { - Query query=newQuery(com.yahoo.search.test.QueryTestCase.httpEncode("?query=\u3007\u2e80\u2eff\u2ed0")); + Query query = newQuery(com.yahoo.search.test.QueryTestCase.httpEncode("?query=\u3007\u2e80\u2eff\u2ed0")); assertEquals(Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION, Character.UnicodeBlock.of(query.getModel().getQueryTree().getRoot().toString().charAt(0))); assertEquals(Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT, @@ -374,13 +366,13 @@ public class QueryTestCase { return query; } - private void assertQueryError(final String queryString, final Matcher<String> expectedErrorMessage) { + private void assertQueryError(String queryString, String expectedErrorMessage) { try { newQuery(queryString); fail("Above statement should throw"); } catch (IllegalArgumentException e) { // As expected. - assertThat(Exceptions.toMessageString(e), expectedErrorMessage); + assertEquals(expectedErrorMessage, Exceptions.toMessageString(e)); } } diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/InterleavedSearchInvokerTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/InterleavedSearchInvokerTest.java index 22044bfb9d9..6e08b1c6fa5 100644 --- a/container-search/src/test/java/com/yahoo/search/dispatch/InterleavedSearchInvokerTest.java +++ b/container-search/src/test/java/com/yahoo/search/dispatch/InterleavedSearchInvokerTest.java @@ -4,14 +4,12 @@ package com.yahoo.search.dispatch; import com.yahoo.document.GlobalId; import com.yahoo.document.idstring.IdString; import com.yahoo.prelude.fastsearch.FastHit; -import com.yahoo.prelude.fastsearch.GroupingListHit; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.dispatch.searchcluster.Group; import com.yahoo.search.dispatch.searchcluster.Node; import com.yahoo.search.dispatch.searchcluster.SearchCluster; import com.yahoo.search.result.Coverage; -import com.yahoo.search.result.DefaultErrorHit; import com.yahoo.search.result.ErrorMessage; import com.yahoo.search.result.Hit; import com.yahoo.search.result.Relevance; @@ -34,8 +32,6 @@ import java.util.stream.StreamSupport; import static com.yahoo.container.handler.Coverage.DEGRADED_BY_MATCH_PHASE; import static com.yahoo.container.handler.Coverage.DEGRADED_BY_TIMEOUT; import static com.yahoo.search.dispatch.MockSearchCluster.createDispatchConfig; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -80,7 +76,7 @@ public class InterleavedSearchInvokerTest { assertTrue("All test scenario events processed", expectedEvents.isEmpty()); assertNull("Result is not marked as an error", result.hits().getErrorHit()); var message = findTrace(result, "Backend communication timeout"); - assertThat("Timeout should be reported in a trace message", message.isPresent()); + assertTrue("Timeout should be reported in a trace message", message.isPresent()); assertTrue("Degradation reason is a normal timeout", result.getCoverage(false).isDegradedByTimeout()); } @@ -99,7 +95,7 @@ public class InterleavedSearchInvokerTest { assertTrue("All test scenario events processed", expectedEvents.isEmpty()); assertNull("Result is not marked as an error", result.hits().getErrorHit()); var message = findTrace(result, "Backend communication timeout"); - assertThat("Timeout should be reported in a trace message", message.isPresent()); + assertTrue("Timeout should be reported in a trace message", message.isPresent()); assertTrue("Degradataion reason is an adaptive timeout", result.getCoverage(false).isDegradedByAdapativeTimeout()); } @@ -116,12 +112,12 @@ public class InterleavedSearchInvokerTest { Result result = invoker.search(query, null); Coverage cov = result.getCoverage(true); - assertThat(cov.getDocs(), is(100000L)); - assertThat(cov.getNodes(), is(2)); - assertThat(cov.getFull(), is(true)); - assertThat(cov.getResultPercentage(), is(100)); - assertThat(cov.getResultSets(), is(1)); - assertThat(cov.getFullResultSets(), is(1)); + assertEquals(100000L, cov.getDocs()); + assertEquals(2, cov.getNodes()); + assertTrue(cov.getFull()); + assertEquals(100, cov.getResultPercentage()); + assertEquals(1, cov.getResultSets()); + assertEquals(1, cov.getFullResultSets()); } @Test @@ -137,13 +133,13 @@ public class InterleavedSearchInvokerTest { Result result = invoker.search(query, null); Coverage cov = result.getCoverage(true); - assertThat(cov.getDocs(), is(23420L)); - assertThat(cov.getNodes(), is(2)); - assertThat(cov.getFull(), is(false)); - assertThat(cov.getResultPercentage(), is(23)); - assertThat(cov.getResultSets(), is(1)); - assertThat(cov.getFullResultSets(), is(0)); - assertThat(cov.isDegradedByMatchPhase(), is(true)); + assertEquals(23420L, cov.getDocs()); + assertEquals(2, cov.getNodes()); + assertFalse(cov.getFull()); + assertEquals(23, cov.getResultPercentage()); + assertEquals(1, cov.getResultSets()); + assertEquals(0, cov.getFullResultSets()); + assertTrue(cov.isDegradedByMatchPhase()); } @Test @@ -159,13 +155,13 @@ public class InterleavedSearchInvokerTest { Result result = invoker.search(query, null); Coverage cov = result.getCoverage(true); - assertThat(cov.getDocs(), is(9900L)); - assertThat(cov.getNodes(), is(2)); - assertThat(cov.getFull(), is(false)); - assertThat(cov.getResultPercentage(), is(10)); - assertThat(cov.getResultSets(), is(1)); - assertThat(cov.getFullResultSets(), is(0)); - assertThat(cov.isDegradedByTimeout(), is(true)); + assertEquals(9900L, cov.getDocs()); + assertEquals(2, cov.getNodes()); + assertFalse(cov.getFull()); + assertEquals(10, cov.getResultPercentage()); + assertEquals(1, cov.getResultSets()); + assertEquals(0, cov.getFullResultSets()); + assertTrue(cov.isDegradedByTimeout()); } @Test @@ -181,14 +177,14 @@ public class InterleavedSearchInvokerTest { Result result = invoker.search(query, null); Coverage cov = result.getCoverage(true); - assertThat(cov.getDocs(), is(50155L)); - assertThat(cov.getNodes(), is(1)); - assertThat(cov.getNodesTried(), is(2)); - assertThat(cov.getFull(), is(false)); - assertThat(cov.getResultPercentage(), is(50)); - assertThat(cov.getResultSets(), is(1)); - assertThat(cov.getFullResultSets(), is(0)); - assertThat(cov.isDegradedByTimeout(), is(true)); + assertEquals(50155L, cov.getDocs()); + assertEquals(1, cov.getNodes()); + assertEquals(2, cov.getNodesTried()); + assertFalse(cov.getFull()); + assertEquals(50, cov.getResultPercentage()); + assertEquals(1, cov.getResultSets()); + assertEquals(0, cov.getFullResultSets()); + assertTrue(cov.isDegradedByTimeout()); } static class MetaHit extends Hit { @@ -365,14 +361,14 @@ public class InterleavedSearchInvokerTest { Result result = invoker.search(query, null); Coverage cov = result.getCoverage(true); - assertThat(cov.getDocs(), is(50155L)); - assertThat(cov.getNodes(), is(1)); - assertThat(cov.getNodesTried(), is(2)); - assertThat(cov.getFull(), is(false)); - assertThat(cov.getResultPercentage(), is(50)); - assertThat(cov.getResultSets(), is(1)); - assertThat(cov.getFullResultSets(), is(0)); - assertThat(cov.isDegradedByTimeout(), is(true)); + assertEquals(50155L, cov.getDocs()); + assertEquals(1, cov.getNodes()); + assertEquals(2, cov.getNodesTried()); + assertFalse(cov.getFull()); + assertEquals(50, cov.getResultPercentage()); + assertEquals(1, cov.getResultSets()); + assertEquals(0, cov.getFullResultSets()); + assertTrue(cov.isDegradedByTimeout()); } private InterleavedSearchInvoker createInterleavedInvoker(SearchCluster searchCluster, Group group, int numInvokers) { @@ -389,9 +385,9 @@ public class InterleavedSearchInvokerTest { @Override protected LinkedBlockingQueue<SearchInvoker> newQueue() { - return new LinkedBlockingQueue<SearchInvoker>() { + return new LinkedBlockingQueue<>() { @Override - public SearchInvoker poll(long timeout, TimeUnit timeUnit) throws InterruptedException { + public SearchInvoker poll(long timeout, TimeUnit timeUnit) { assertFalse(expectedEvents.isEmpty()); Event ev = expectedEvents.removeFirst(); if (ev == null) { @@ -448,7 +444,7 @@ public class InterleavedSearchInvokerTest { } public class TestQuery extends Query { - private long start = clock.millis(); + private final long start = clock.millis(); public TestQuery() { super(); diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java index 7254236319d..e95fbc366a6 100644 --- a/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java +++ b/container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java @@ -16,11 +16,9 @@ import java.util.Optional; import java.util.Random; import static com.yahoo.search.dispatch.MockSearchCluster.createDispatchConfig; -import static org.hamcrest.Matchers.closeTo; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; /** * @author ollivir @@ -37,7 +35,7 @@ public class LoadBalancerTest { Group group = grp.orElseGet(() -> { throw new AssertionFailedError("Expected a SearchCluster.Group"); }); - assertThat(group.nodes().size(), equalTo(1)); + assertEquals(1, group.nodes().size()); } @Test @@ -51,7 +49,7 @@ public class LoadBalancerTest { Group group = grp.orElseGet(() -> { throw new AssertionFailedError("Expected a SearchCluster.Group"); }); - assertThat(group.nodes().size(), equalTo(1)); + assertEquals(1, group.nodes().size()); } @Test @@ -64,7 +62,7 @@ public class LoadBalancerTest { LoadBalancer lb = new LoadBalancer(cluster, true); Optional<Group> grp = lb.takeGroup(null); - assertThat(grp.isPresent(), is(true)); + assertTrue(grp.isPresent()); } @Test @@ -84,36 +82,36 @@ public class LoadBalancerTest { // get second group grp = lb.takeGroup(null); group = grp.get(); - assertThat(group.id(), not(equalTo(id1))); + assertNotEquals(id1, group.id()); } @Test public void requireCorrectAverageSearchTimeDecay() { - final double SMALL = 0.00001; + final double delta = 0.00001; GroupStatus gs = newGroupStatus(1); gs.setQueryStatistics(0, 1.0); updateSearchTime(gs, 1.0); - assertThat(gs.averageSearchTime(), equalTo(1.0)); + assertEquals(1.0, gs.averageSearchTime(), delta); updateSearchTime(gs, 2.0); - assertThat(gs.averageSearchTime(), closeTo(1.02326, SMALL)); + assertEquals(1.02326, gs.averageSearchTime(), delta); updateSearchTime(gs, 2.0); - assertThat(gs.averageSearchTime(), closeTo(1.04545, SMALL)); + assertEquals(1.04545, gs.averageSearchTime(), delta); updateSearchTime(gs, 0.1); updateSearchTime(gs, 0.1); updateSearchTime(gs, 0.1); updateSearchTime(gs, 0.1); - assertThat(gs.averageSearchTime(), closeTo(0.966667, SMALL)); + assertEquals(0.966667, gs.averageSearchTime(), delta); for (int i = 0; i < 10000; i++) { updateSearchTime(gs, 1.0); } - assertThat(gs.averageSearchTime(), closeTo(1.0, SMALL)); + assertEquals(1.0, gs.averageSearchTime(), delta); updateSearchTime(gs, 0.1); - assertThat(gs.averageSearchTime(), closeTo(0.9991, SMALL)); + assertEquals(0.9991, gs.averageSearchTime(), delta); for (int i = 0; i < 10000; i++) { updateSearchTime(gs, 0.0); } - assertThat(gs.averageSearchTime(), closeTo(0.001045, SMALL)); + assertEquals(0.001045, gs.averageSearchTime(), delta); } @Test @@ -125,14 +123,14 @@ public class LoadBalancerTest { Random seq = sequence(0.0, 0.1, 0.2, 0.39, 0.4, 0.6, 0.8, 0.99999); AdaptiveScheduler sched = new AdaptiveScheduler(seq, scoreboard); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(0)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(0)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(1)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(1)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(2)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(3)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(4)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(4)); + assertEquals(0, sched.takeNextGroup(null).get().groupId()); + assertEquals(0, sched.takeNextGroup(null).get().groupId()); + assertEquals(1, sched.takeNextGroup(null).get().groupId()); + assertEquals(1, sched.takeNextGroup(null).get().groupId()); + assertEquals(2, sched.takeNextGroup(null).get().groupId()); + assertEquals(3, sched.takeNextGroup(null).get().groupId()); + assertEquals(4, sched.takeNextGroup(null).get().groupId()); + assertEquals(4, sched.takeNextGroup(null).get().groupId()); } @Test @@ -146,15 +144,15 @@ public class LoadBalancerTest { Random seq = sequence(0.0, 0.4379, 0.4380, 0.6569, 0.6570, 0.8029, 0.8030, 0.9124, 0.9125); AdaptiveScheduler sched = new AdaptiveScheduler(seq, scoreboard); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(0)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(0)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(1)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(1)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(2)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(2)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(3)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(3)); - assertThat(sched.takeNextGroup(null).get().groupId(), equalTo(4)); + assertEquals(0, sched.takeNextGroup(null).get().groupId()); + assertEquals(0, sched.takeNextGroup(null).get().groupId()); + assertEquals(1, sched.takeNextGroup(null).get().groupId()); + assertEquals(1, sched.takeNextGroup(null).get().groupId()); + assertEquals(2, sched.takeNextGroup(null).get().groupId()); + assertEquals(2, sched.takeNextGroup(null).get().groupId()); + assertEquals(3, sched.takeNextGroup(null).get().groupId()); + assertEquals(3, sched.takeNextGroup(null).get().groupId()); + assertEquals(4, sched.takeNextGroup(null).get().groupId()); } private static void updateSearchTime(GroupStatus gs, double time) { @@ -187,4 +185,5 @@ public class LoadBalancerTest { } }; } + } diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/SearchPathTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/SearchPathTest.java index 0366d4873e0..3a1a60df7af 100644 --- a/container-search/src/test/java/com/yahoo/search/dispatch/SearchPathTest.java +++ b/container-search/src/test/java/com/yahoo/search/dispatch/SearchPathTest.java @@ -3,9 +3,7 @@ package com.yahoo.search.dispatch; import com.yahoo.search.dispatch.SearchPath.InvalidSearchPathException; import com.yahoo.search.dispatch.searchcluster.Node; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import java.util.Collection; import java.util.Set; @@ -14,6 +12,7 @@ import java.util.stream.Collectors; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * @author ollivir @@ -52,28 +51,40 @@ public class SearchPathTest { assertFalse(SearchPath.fromString("//").isPresent()); } - @Rule - public final ExpectedException exception = ExpectedException.none(); - @Test public void invalidRangeMustThrowException() { - exception.expect(InvalidSearchPathException.class); - SearchPath.fromString("[p,0>/0"); + try { + SearchPath.fromString("[p,0>/0"); + fail("Expected exception"); + } + catch (InvalidSearchPathException e) { + // success + } } @Test public void invalidPartMustThrowException() { - exception.expect(InvalidSearchPathException.class); - SearchPath.fromString("p/0"); + try { + SearchPath.fromString("p/0"); + fail("Expected exception"); + } + catch (InvalidSearchPathException e) { + // success + } } @Test public void invalidRowMustThrowException() { - exception.expect(InvalidSearchPathException.class); - SearchPath.fromString("1,2,3/r"); + try { + SearchPath.fromString("1,2,3/r"); + fail("Expected exception"); + } + catch (InvalidSearchPathException e) { + // success + } } - private void verifyRandomGroup(MockSearchCluster cluster, String searchPath, Set possibleSolutions) { + private void verifyRandomGroup(MockSearchCluster cluster, String searchPath, Set<?> possibleSolutions) { for (int i=0; i < 100; i++) { String nodes = distKeysAsString(SearchPath.selectNodes(searchPath, cluster)); assertTrue(possibleSolutions.contains(nodes)); diff --git a/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java b/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java index 0d67c4d6ddc..0867366303b 100644 --- a/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java +++ b/container-search/src/test/java/com/yahoo/search/dispatch/rpc/ProtobufSerializationTest.java @@ -16,10 +16,8 @@ import java.io.IOException; import java.util.Collections; import java.util.List; -import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** @@ -37,7 +35,7 @@ public class ProtobufSerializationTest { hit.setGlobalId(new GlobalId(IdString.createIdString("id:ns:type::id")).getRawId()); var bytes = ProtobufSerialization.serializeDocsumRequest(builder, Collections.singletonList(hit)); - assertThat(bytes.length, equalTo(41)); + assertEquals(41, bytes.length); } SearchProtocol.SearchReply createSearchReply(int numHits, boolean useSorting) { diff --git a/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SearchChainResolverTestCase.java b/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SearchChainResolverTestCase.java index 2d7e1c0ab5c..34224721487 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SearchChainResolverTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SearchChainResolverTestCase.java @@ -16,9 +16,8 @@ import java.util.Collections; import java.util.Iterator; import java.util.SortedSet; -import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; /** @@ -55,11 +54,11 @@ public class SearchChainResolverTestCase { @Test public void check_default_search_chains() { - assertThat(searchChainResolver.defaultTargets().size(), is(2)); + assertEquals(2, searchChainResolver.defaultTargets().size()); Iterator<Target> iterator = searchChainResolver.defaultTargets().iterator(); - assertThat(iterator.next().searchRefDescription(), is(searchChainId.toString())); - assertThat(iterator.next().searchRefDescription(), is(sourceChainInProviderId.toString())); + assertEquals(searchChainId.toString(), iterator.next().searchRefDescription()); + assertEquals(sourceChainInProviderId.toString(), iterator.next().searchRefDescription()); } @Test @@ -68,22 +67,22 @@ public class SearchChainResolverTestCase { resolve("no-such-source"); fail("Expected exception."); } catch (UnresolvedSearchChainException e) { - assertThat(e.getMessage(), is("Could not resolve source ref 'no-such-source'.")); + assertEquals("Could not resolve source ref 'no-such-source'.", e.getMessage()); } } @Test public void lookup_search_chain() throws Exception { SearchChainInvocationSpec res = resolve(searchChainId.getName()); - assertThat(res.searchChainId, is(searchChainId)); + assertEquals(searchChainId, res.searchChainId); } //TODO: TVT: @Test() public void lookup_provider() throws Exception { SearchChainInvocationSpec res = resolve(providerId.getName()); - assertThat(res.provider, is(providerId)); + assertEquals(providerId, res.provider); assertNull(res.source); - assertThat(res.searchChainId, is(providerId)); + assertEquals(providerId, res.searchChainId); } @Test @@ -99,23 +98,23 @@ public class SearchChainResolverTestCase { } private void assertIsSourceInProvider(SearchChainInvocationSpec res) { - assertThat(res.provider, is(providerId)); - assertThat(res.source, is(sourceId)); - assertThat(res.searchChainId, is(sourceChainInProviderId)); + assertEquals(providerId, res.provider); + assertEquals(sourceId, res.source); + assertEquals(sourceChainInProviderId, res.searchChainId); } @Test public void lookup_source_for_provider2() throws Exception { SearchChainInvocationSpec res = resolve(sourceId.getName(), provider2Id.getName()); - assertThat(res.provider, is(provider2Id)); - assertThat(res.source, is(sourceId)); - assertThat(res.searchChainId, is(sourceChainInProvider2Id)); + assertEquals(provider2Id, res.provider); + assertEquals(sourceId, res.source); + assertEquals(sourceChainInProvider2Id, res.searchChainId); } @Test public void lists_source_ref_description_for_top_level_targets() { SortedSet<Target> topLevelTargets = searchChainResolver.allTopLevelTargets(); - assertThat(topLevelTargets.size(), is(3)); + assertEquals(3, topLevelTargets.size()); Iterator<Target> i = topLevelTargets.iterator(); assertSearchRefDescriptionIs(i.next(), providerId.toString()); @@ -124,7 +123,7 @@ public class SearchChainResolverTestCase { } private void assertSearchRefDescriptionIs(Target target, String expected) { - assertThat(target.searchRefDescription(), is(expected)); + assertEquals(expected, target.searchRefDescription()); } static Properties emptySourceToProviderMap() { @@ -146,7 +145,7 @@ public class SearchChainResolverTestCase { throws UnresolvedSearchChainException { SearchChainInvocationSpec res = searchChainResolver.resolve( ComponentSpecification.fromString(sourceSpecification), sourceToProviderMap); - assertThat(res.federationOptions, is(federationOptions)); + assertEquals(federationOptions, res.federationOptions); return res; } diff --git a/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SourceRefResolverTestCase.java b/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SourceRefResolverTestCase.java index 27412eb6c3f..acb68175921 100644 --- a/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SourceRefResolverTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/federation/sourceref/test/SourceRefResolverTestCase.java @@ -13,25 +13,23 @@ import com.yahoo.search.searchchain.model.federation.FederationOptions; import org.junit.Test; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.TreeMap; import static com.yahoo.search.federation.sourceref.test.SearchChainResolverTestCase.emptySourceToProviderMap; -import static org.hamcrest.CoreMatchers.hasItem; -import static org.hamcrest.CoreMatchers.hasItems; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; - /** * Test for SourceRefResolver. + * * @author Tony Vaagenes */ public class SourceRefResolverTestCase { + private static final String cluster1 = "cluster1"; private static final String cluster2 = "cluster2"; private static final String cluster3 = "cluster3"; @@ -55,29 +53,29 @@ public class SourceRefResolverTestCase { private static void setupIndexFacts() { TreeMap<String, List<String>> masterClusters = new TreeMap<>(); - masterClusters.put(cluster1, Arrays.asList("document1", "document2")); - masterClusters.put(cluster2, Arrays.asList("document1")); - masterClusters.put(cluster3, Arrays.asList("document3")); + masterClusters.put(cluster1, List.of("document1", "document2")); + masterClusters.put(cluster2, List.of("document1")); + masterClusters.put(cluster3, List.of("document3")); indexFacts = new IndexFacts(new IndexModel(masterClusters, Collections.emptyList())); } @Test public void check_test_assumptions() { - assertThat(indexFacts.clustersHavingSearchDefinition("document1"), hasItems("cluster1", "cluster2")); + assertTrue(indexFacts.clustersHavingSearchDefinition("document1").containsAll(List.of("cluster1", "cluster2"))); } @Test public void lookup_search_chain() throws Exception { Set<SearchChainInvocationSpec> searchChains = resolve(cluster1); - assertThat(searchChains.size(), is(1)); - assertThat(searchChainIds(searchChains), hasItem(cluster1)); + assertEquals(1, searchChains.size()); + assertTrue(searchChainIds(searchChains).contains(cluster1)); } @Test public void lookup_search_chains_for_document1() throws Exception { Set<SearchChainInvocationSpec> searchChains = resolve("document1"); - assertThat(searchChains.size(), is(2)); - assertThat(searchChainIds(searchChains), hasItems(cluster1, cluster2)); + assertEquals(2, searchChains.size()); + assertTrue(searchChainIds(searchChains).containsAll(List.of(cluster1, cluster2))); } @Test @@ -86,8 +84,9 @@ public class SourceRefResolverTestCase { resolve("document3"); fail("Expected exception"); } catch (UnresolvedSearchChainException e) { - assertThat(e.getMessage(), is("Failed to resolve cluster search chain 'cluster3' " + - "when using source ref 'document3' as a document name.")); + assertEquals("Failed to resolve cluster search chain 'cluster3' " + + "when using source ref 'document3' as a document name.", + e.getMessage()); } } @@ -97,7 +96,7 @@ public class SourceRefResolverTestCase { resolve("document4"); fail("Expected exception"); } catch (UnresolvedSearchChainException e) { - assertThat(e.getMessage(), is("Could not resolve source ref 'document4'.")); + assertEquals("Could not resolve source ref 'document4'.", e.getMessage()); } } @@ -112,4 +111,5 @@ public class SourceRefResolverTestCase { private Set<SearchChainInvocationSpec> resolve(String documentName) throws UnresolvedSearchChainException { return sourceRefResolver.resolve(ComponentSpecification.fromString(documentName), emptySourceToProviderMap(), indexFacts); } + } diff --git a/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java b/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java index 8f757a0dd49..4f473b29918 100644 --- a/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/grouping/GroupingValidatorTestCase.java @@ -7,117 +7,142 @@ import com.yahoo.search.Query; import com.yahoo.search.config.ClusterConfig; import com.yahoo.search.grouping.request.GroupingOperation; import com.yahoo.search.searchchain.Execution; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; -import java.util.Arrays; import java.util.Collection; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * @author Simon Thoresen Hult */ public class GroupingValidatorTestCase { - @Rule - public ExpectedException thrown = ExpectedException.none(); - @Test public void requireThatAvailableAttributesDoNotThrow() { - validateGrouping(Arrays.asList("foo", "bar"), + validateGrouping(List.of("foo", "bar"), "all(group(foo) each(output(max(bar))))");; } @Test public void requireThatUnavailableAttributesThrow() { - thrown.expect(UnavailableAttributeException.class); - thrown.expectMessage(createMessage("bar")); - validateGrouping(Arrays.asList("foo"), - "all(group(foo) each(output(max(bar))))"); + try { + validateGrouping(List.of("foo"), "all(group(foo) each(output(max(bar))))"); + fail("Excpected exception"); + } + catch (UnavailableAttributeException e) { + assertEquals(createMessage("bar"), e.getMessage()); + } } @Test public void requireThatEnableFlagPreventsThrow() { Query query = createQuery("all(group(foo) each(output(max(bar))))"); query.properties().set(GroupingValidator.PARAM_ENABLED, "false"); - validateGrouping(Arrays.asList("foo"), query); + validateGrouping(List.of("foo"), query); } @Test public void available_primitive_map_attribute_does_not_throw() { - validateGrouping(Arrays.asList("map.key", "map.value"), + validateGrouping(List.of("map.key", "map.value"), "all(group(map{\"foo\"}) each(output(count())))"); } @Test public void unavailable_primitive_map_key_attribute_throws() { - thrown.expect(UnavailableAttributeException.class); - thrown.expectMessage(createMessage("map.key")); - validateGrouping(Arrays.asList("null"), - "all(group(map{\"foo\"}) each(output(count())))"); + try { + validateGrouping(List.of("null"), "all(group(map{\"foo\"}) each(output(count())))"); + fail("Expected exception"); + } + catch (UnavailableAttributeException e) { + assertEquals(createMessage("map.key"), e.getMessage()); + } } @Test public void unavailable_primitive_map_value_attribute_throws() { - thrown.expect(UnavailableAttributeException.class); - thrown.expectMessage(createMessage("map.value")); - validateGrouping(Arrays.asList("map.key"), - "all(group(map{\"foo\"}) each(output(count())))"); + try { + validateGrouping(List.of("map.key"), "all(group(map{\"foo\"}) each(output(count())))"); + fail("Expected exception"); + } + catch (UnavailableAttributeException e) { + assertEquals(createMessage("map.value"), e.getMessage()); + } } @Test public void available_struct_map_attribute_does_not_throw() { - validateGrouping(Arrays.asList("map.key", "map.value.name"), + validateGrouping(List.of("map.key", "map.value.name"), "all(group(map{\"foo\"}.name) each(output(count())))"); } @Test public void unavailable_struct_map_key_attribute_throws() { - thrown.expect(UnavailableAttributeException.class); - thrown.expectMessage(createMessage("map.key")); - validateGrouping(Arrays.asList("null"), - "all(group(map{\"foo\"}.name) each(output(count())))"); + try { + validateGrouping(List.of("null"), "all(group(map{\"foo\"}.name) each(output(count())))"); + fail("Expected exception"); + } + catch (UnavailableAttributeException e) { + assertEquals(createMessage("map.key"), e.getMessage()); + } } @Test public void unavailable_struct_map_value_attribute_throws() { - thrown.expect(UnavailableAttributeException.class); - thrown.expectMessage(createMessage("map.value.name")); - validateGrouping(Arrays.asList("map.key"), - "all(group(map{\"foo\"}.name) each(output(count())))"); + try { + validateGrouping(List.of("map.key"), "all(group(map{\"foo\"}.name) each(output(count())))"); + fail("Expected exception"); + } + catch (UnavailableAttributeException e) { + assertEquals(createMessage("map.value.name"), e.getMessage()); + } } @Test public void available_key_source_attribute_does_not_throw() { - validateGrouping(Arrays.asList("map.key", "map.value", "key_source"), + validateGrouping(List.of("map.key", "map.value", "key_source"), "all(group(map{attribute(key_source)}) each(output(count())))"); } @Test public void unavailable_key_source_attribute_throws() { - thrown.expect(UnavailableAttributeException.class); - thrown.expectMessage(createMessage("key_source")); - validateGrouping(Arrays.asList("map.key", "map.value"), - "all(group(map{attribute(key_source)}) each(output(count())))"); + try { + validateGrouping(List.of("map.key", "map.value"), + "all(group(map{attribute(key_source)}) each(output(count())))"); + fail("Expected exception"); + } + catch (UnavailableAttributeException e) { + assertEquals(createMessage("key_source"), e.getMessage()); + } } @Test public void key_source_attribute_with_mismatching_data_type_throws() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Grouping request references key source attribute 'key_source' with data type 'INT32' " + - "that is different than data type 'STRING' of key attribute 'map.key'"); - - validateGrouping(setupMismatchingKeySourceAttribute(false), - "all(group(map{attribute(key_source)}) each(output(count())))"); + try { + validateGrouping(setupMismatchingKeySourceAttribute(false), + "all(group(map{attribute(key_source)}) each(output(count())))"); + fail("Expected exception"); + } + catch (IllegalArgumentException e) { + assertEquals("Grouping request references key source attribute 'key_source' with data type 'INT32' " + + "that is different than data type 'STRING' of key attribute 'map.key'", + e.getMessage()); + } } @Test public void key_source_attribute_with_multi_value_collection_type_throws() { - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Grouping request references key source attribute 'key_source' which is not of single value type"); - - validateGrouping(setupMismatchingKeySourceAttribute(true), - "all(group(map{attribute(key_source)}) each(output(count())))"); + try { + validateGrouping(setupMismatchingKeySourceAttribute(true), + "all(group(map{attribute(key_source)}) each(output(count())))"); + fail("Expected exception"); + } + catch (IllegalArgumentException e) { + assertEquals("Grouping request references key source attribute 'key_source' which is not of single value type", + e.getMessage()); + } } private static AttributesConfig setupMismatchingKeySourceAttribute(boolean matchingDataType) { diff --git a/container-search/src/test/java/com/yahoo/search/grouping/UniqueGroupingSearcherTestCase.java b/container-search/src/test/java/com/yahoo/search/grouping/UniqueGroupingSearcherTestCase.java index c5b608db4e2..bcade5aa1cc 100644 --- a/container-search/src/test/java/com/yahoo/search/grouping/UniqueGroupingSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/grouping/UniqueGroupingSearcherTestCase.java @@ -17,9 +17,8 @@ import com.yahoo.search.searchchain.Execution; import com.yahoo.yolean.Exceptions; import org.junit.Test; -import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** @@ -49,11 +48,9 @@ public class UniqueGroupingSearcherTestCase { fail("Above statement should throw"); } catch (IllegalArgumentException e) { // As expected. - assertThat( - Exceptions.toMessageString(e), - containsString( - "Could not set 'ranking.sorting' to '-1': " + - "Illegal attribute name '1' for sorting. Requires '[\\[]*[a-zA-Z_][\\.a-zA-Z0-9_-]*[\\]]*'")); + assertTrue(Exceptions.toMessageString(e).contains("Could not set 'ranking.sorting' to '-1': " + + "Illegal attribute name '1' for sorting. " + + "Requires '[\\[]*[a-zA-Z_][\\.a-zA-Z0-9_-]*[\\]]*'")); } } diff --git a/container-search/src/test/java/com/yahoo/search/grouping/request/MathFunctionsTestCase.java b/container-search/src/test/java/com/yahoo/search/grouping/request/MathFunctionsTestCase.java index 522e72d31b9..d22c2dee7b6 100644 --- a/container-search/src/test/java/com/yahoo/search/grouping/request/MathFunctionsTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/grouping/request/MathFunctionsTestCase.java @@ -3,65 +3,63 @@ package com.yahoo.search.grouping.request; import org.junit.Test; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.sameInstance; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; /** - * @author <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a> - * @since 5.1.9 + * @author Einar M R Rosenvinge */ public class MathFunctionsTestCase { + @Test public void testMathFunctions() { //if this fails, update the count AND add a test in each of the two blocks below - assertThat(MathFunctions.Function.values().length, is(21)); + assertEquals(21, MathFunctions.Function.values().length); + assertSame(MathFunctions.Function.create(0), MathFunctions.Function.EXP); + assertSame(MathFunctions.Function.create(1), MathFunctions.Function.POW); + assertSame(MathFunctions.Function.create(2), MathFunctions.Function.LOG); + assertSame(MathFunctions.Function.create(3), MathFunctions.Function.LOG1P); + assertSame(MathFunctions.Function.create(4), MathFunctions.Function.LOG10); + assertSame(MathFunctions.Function.create(5), MathFunctions.Function.SIN); + assertSame(MathFunctions.Function.create(6), MathFunctions.Function.ASIN); + assertSame(MathFunctions.Function.create(7), MathFunctions.Function.COS); + assertSame(MathFunctions.Function.create(8), MathFunctions.Function.ACOS); + assertSame(MathFunctions.Function.create(9), MathFunctions.Function.TAN); + assertSame(MathFunctions.Function.create(10), MathFunctions.Function.ATAN); + assertSame(MathFunctions.Function.create(11), MathFunctions.Function.SQRT); + assertSame(MathFunctions.Function.create(12), MathFunctions.Function.SINH); + assertSame(MathFunctions.Function.create(13), MathFunctions.Function.ASINH); + assertSame(MathFunctions.Function.create(14), MathFunctions.Function.COSH); + assertSame(MathFunctions.Function.create(15), MathFunctions.Function.ACOSH); + assertSame(MathFunctions.Function.create(16), MathFunctions.Function.TANH); + assertSame(MathFunctions.Function.create(17), MathFunctions.Function.ATANH); + assertSame(MathFunctions.Function.create(18), MathFunctions.Function.CBRT); + assertSame(MathFunctions.Function.create(19), MathFunctions.Function.HYPOT); + assertSame(MathFunctions.Function.create(20), MathFunctions.Function.FLOOR); - assertThat(MathFunctions.Function.create(0), sameInstance(MathFunctions.Function.EXP)); - assertThat(MathFunctions.Function.create(1), sameInstance(MathFunctions.Function.POW)); - assertThat(MathFunctions.Function.create(2), sameInstance(MathFunctions.Function.LOG)); - assertThat(MathFunctions.Function.create(3), sameInstance(MathFunctions.Function.LOG1P)); - assertThat(MathFunctions.Function.create(4), sameInstance(MathFunctions.Function.LOG10)); - assertThat(MathFunctions.Function.create(5), sameInstance(MathFunctions.Function.SIN)); - assertThat(MathFunctions.Function.create(6), sameInstance(MathFunctions.Function.ASIN)); - assertThat(MathFunctions.Function.create(7), sameInstance(MathFunctions.Function.COS)); - assertThat(MathFunctions.Function.create(8), sameInstance(MathFunctions.Function.ACOS)); - assertThat(MathFunctions.Function.create(9), sameInstance(MathFunctions.Function.TAN)); - assertThat(MathFunctions.Function.create(10), sameInstance(MathFunctions.Function.ATAN)); - assertThat(MathFunctions.Function.create(11), sameInstance(MathFunctions.Function.SQRT)); - assertThat(MathFunctions.Function.create(12), sameInstance(MathFunctions.Function.SINH)); - assertThat(MathFunctions.Function.create(13), sameInstance(MathFunctions.Function.ASINH)); - assertThat(MathFunctions.Function.create(14), sameInstance(MathFunctions.Function.COSH)); - assertThat(MathFunctions.Function.create(15), sameInstance(MathFunctions.Function.ACOSH)); - assertThat(MathFunctions.Function.create(16), sameInstance(MathFunctions.Function.TANH)); - assertThat(MathFunctions.Function.create(17), sameInstance(MathFunctions.Function.ATANH)); - assertThat(MathFunctions.Function.create(18), sameInstance(MathFunctions.Function.CBRT)); - assertThat(MathFunctions.Function.create(19), sameInstance(MathFunctions.Function.HYPOT)); - assertThat(MathFunctions.Function.create(20), sameInstance(MathFunctions.Function.FLOOR)); - - - assertThat(MathFunctions.newInstance(MathFunctions.Function.EXP, null, null), instanceOf(MathExpFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.POW, null, null), instanceOf(MathPowFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.LOG, null, null), instanceOf(MathLogFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.LOG1P, null, null), instanceOf(MathLog1pFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.LOG10, null, null), instanceOf(MathLog10Function.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.SIN, null, null), instanceOf(MathSinFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.ASIN, null, null), instanceOf(MathASinFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.COS, null, null), instanceOf(MathCosFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.ACOS, null, null), instanceOf(MathACosFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.TAN, null, null), instanceOf(MathTanFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.ATAN, null, null), instanceOf(MathATanFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.SQRT, null, null), instanceOf(MathSqrtFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.SINH, null, null), instanceOf(MathSinHFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.ASINH, null, null), instanceOf(MathASinHFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.COSH, null, null), instanceOf(MathCosHFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.ACOSH, null, null), instanceOf(MathACosHFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.TANH, null, null), instanceOf(MathTanHFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.ATANH, null, null), instanceOf(MathATanHFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.CBRT, null, null), instanceOf(MathCbrtFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.HYPOT, null, null), instanceOf(MathHypotFunction.class)); - assertThat(MathFunctions.newInstance(MathFunctions.Function.FLOOR, null, null), instanceOf(MathFloorFunction.class)); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.EXP, null, null) instanceof MathExpFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.POW, null, null) instanceof MathPowFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.LOG, null, null) instanceof MathLogFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.LOG1P, null, null) instanceof MathLog1pFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.LOG10, null, null) instanceof MathLog10Function); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.SIN, null, null) instanceof MathSinFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.ASIN, null, null) instanceof MathASinFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.COS, null, null) instanceof MathCosFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.ACOS, null, null) instanceof MathACosFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.TAN, null, null) instanceof MathTanFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.ATAN, null, null) instanceof MathATanFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.SQRT, null, null) instanceof MathSqrtFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.SINH, null, null) instanceof MathSinHFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.ASINH, null, null) instanceof MathASinHFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.COSH, null, null) instanceof MathCosHFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.ACOSH, null, null) instanceof MathACosHFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.TANH, null, null) instanceof MathTanHFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.ATANH, null, null) instanceof MathATanHFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.CBRT, null, null) instanceof MathCbrtFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.HYPOT, null, null) instanceof MathHypotFunction); + assertTrue(MathFunctions.newInstance(MathFunctions.Function.FLOOR, null, null) instanceof MathFloorFunction); } + } diff --git a/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java b/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java index e1987aa50ca..b1354106f19 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java +++ b/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java @@ -37,14 +37,11 @@ import java.net.URI; import java.util.concurrent.Executors; import static com.yahoo.yolean.Exceptions.uncheckInterrupted; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; 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; @@ -222,9 +219,9 @@ public class SearchHandlerTest { RequestHandlerTestDriver.MockResponseHandler responseHandler = testDriver.sendRequest("http://localhost/search/?query=status_code%3A0&hits=20&offset=-20"); String response = responseHandler.readAll(); - assertThat(responseHandler.getStatus(), is(400)); - assertThat(response, containsString("offset")); - assertThat(response, containsString("\"code\":" + com.yahoo.container.protect.Error.ILLEGAL_QUERY.code)); + assertEquals(400, responseHandler.getStatus()); + assertTrue(response.contains("offset")); + assertTrue(response.contains("\"code\":" + com.yahoo.container.protect.Error.ILLEGAL_QUERY.code)); } @Test @@ -246,7 +243,7 @@ public class SearchHandlerTest { driver.sendRequest("http://localhost/search/?query=web_service_status_code"); String response = responseHandler.readAll(); assertEquals(406, responseHandler.getStatus()); - assertThat(response, containsString("\"code\":" + 406)); + assertTrue(response.contains("\"code\":" + 406)); } @Test diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java index 48dfa98768a..7811336823d 100644 --- a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java @@ -31,13 +31,10 @@ import java.util.HashMap; import java.util.Map; import static com.yahoo.jdisc.http.HttpRequest.Method.GET; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** @@ -102,9 +99,9 @@ public class JSONSearchHandlerTestCase { String json = "Not a valid JSON-string"; RequestHandlerTestDriver.MockResponseHandler responseHandler = driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json, JSON_CONTENT_TYPE); String response = responseHandler.readAll(); - assertThat(responseHandler.getStatus(), is(400)); - assertThat(response, containsString("errors")); - assertThat(response, containsString("\"code\":" + Error.ILLEGAL_QUERY.code)); + assertEquals(400, responseHandler.getStatus()); + assertTrue(response.contains("errors")); + assertTrue(response.contains("\"code\":" + Error.ILLEGAL_QUERY.code)); } @Test @@ -158,7 +155,7 @@ public class JSONSearchHandlerTestCase { json.put("yql", "selectz * from foo where bar > 1453501295"); RequestHandlerTestDriver.MockResponseHandler responseHandler = newDriver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE); responseHandler.readAll(); - assertThat(responseHandler.getStatus(), is(400)); + assertEquals(400, responseHandler.getStatus()); } } @@ -178,9 +175,9 @@ public class JSONSearchHandlerTestCase { RequestHandlerTestDriver.MockResponseHandler responseHandler = testDriver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE); String response = responseHandler.readAll(); - assertThat(responseHandler.getStatus(), is(400)); - assertThat(response, containsString("offset")); - assertThat(response, containsString("\"code\":" + com.yahoo.container.protect.Error.ILLEGAL_QUERY.code)); + assertEquals(400, responseHandler.getStatus()); + assertTrue(response.contains("offset")); + assertTrue(response.contains("\"code\":" + com.yahoo.container.protect.Error.ILLEGAL_QUERY.code)); } @Test @@ -212,8 +209,8 @@ public class JSONSearchHandlerTestCase { RequestHandlerTestDriver.MockResponseHandler responseHandler = driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE); String response = responseHandler.readAll(); - assertThat(responseHandler.getStatus(), is(406)); - assertThat(response, containsString("\"code\":" + 406)); + assertEquals(406, responseHandler.getStatus()); + assertTrue(response.contains("\"code\":" + 406)); } @Test diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/types/test/NativePropertiesTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/types/test/NativePropertiesTestCase.java index 85015bee851..6f884650b5d 100644 --- a/container-search/src/test/java/com/yahoo/search/query/profile/types/test/NativePropertiesTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/profile/types/test/NativePropertiesTestCase.java @@ -9,8 +9,7 @@ import com.yahoo.search.query.profile.types.QueryProfileType; import com.yahoo.yolean.Exceptions; import org.junit.Test; -import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** @@ -39,9 +38,7 @@ public class NativePropertiesTestCase { fail("Above statement should throw"); } catch (IllegalArgumentException e) { // As expected. - assertThat( - Exceptions.toMessageString(e), - containsString( + assertTrue(Exceptions.toMessageString(e).contains( "Could not set 'notnative' to '5':" + " 'notnative' is not declared in query profile type 'strict', and the type is strict")); } diff --git a/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java b/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java index 44e8147c09b..2e88c9fd0a4 100644 --- a/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/profile/types/test/QueryProfileTypeTestCase.java @@ -26,10 +26,8 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.List; -import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -96,13 +94,13 @@ public class QueryProfileTypeTestCase { @Test public void testTypedOfPrimitivesAssignmentNonStrict() { - QueryProfile profile=new QueryProfile("test"); + QueryProfile profile = new QueryProfile("test"); profile.setType(testtype); registry.register(profile); - profile.set("myString","anyValue", registry); + profile.set("myString", "anyValue", registry); profile.set("nontypedString", "anyValueToo", registry); // legal because this is not strict - assertWrongType(profile,"integer","myInteger","notInteger"); + assertWrongType(profile,"integer", "myInteger","notInteger"); assertWrongType(profile, "integer", "myInteger", "1.5"); profile.set("myInteger", 3, registry); assertWrongType(profile,"long","myLong","notLong"); @@ -137,7 +135,7 @@ public class QueryProfileTypeTestCase { assertEquals("anyValueToo", properties.get("nontypedString")); assertEquals(3, properties.get("myInteger")); assertEquals(3, properties.get("Int")); - assertEquals(4000000000000l, properties.get("myLong")); + assertEquals(4000000000000L, properties.get("myLong")); assertEquals(3.14f, properties.get("myFloat")); assertEquals(2.18, properties.get("myDouble")); assertEquals(true, properties.get("myBoolean")); @@ -163,7 +161,7 @@ public class QueryProfileTypeTestCase { @Test public void testTypedOfPrimitivesAssignmentStrict() { - QueryProfile profile=new QueryProfile("test"); + QueryProfile profile = new QueryProfile("test"); profile.setType(testtypeStrict); profile.set("myString", "anyValue", registry); @@ -173,13 +171,13 @@ public class QueryProfileTypeTestCase { profile.set("myInteger", 3, registry); assertWrongType(profile,"long","myLong","notLong"); assertWrongType(profile, "long", "myLong", "1.5"); - profile.set("myLong", 4000000000000l, registry); + profile.set("myLong", 4000000000000L, registry); assertWrongType(profile, "float", "myFloat", "notFloat"); profile.set("myFloat", 3.14f, registry); assertWrongType(profile, "double", "myDouble", "notDouble"); profile.set("myDouble",2.18, registry); - profile.set("myQueryProfile.anyString","value1", registry); - profile.set("myQueryProfile.anyDouble",8.76, registry); + profile.set("myQueryProfile.anyString", "value1", registry); + profile.set("myQueryProfile.anyDouble", 8.76, registry); profile.set("myUserQueryProfile.myUserString", "value2", registry); assertNotPermitted(profile, "myUserQueryProfile.anyString", "value3"); // Illegal because this is strict assertWrongType(profile, "integer", "myUserQueryProfile.myUserInteger", "notInteger"); @@ -191,7 +189,7 @@ public class QueryProfileTypeTestCase { assertEquals("anyValue", cprofile.get("myString")); assertNull(cprofile.get("nontypedString")); assertEquals(3, cprofile.get("myInteger")); - assertEquals(4000000000000l, cprofile.get("myLong")); + assertEquals(4000000000000L, cprofile.get("myLong")); assertEquals(3.14f, cprofile.get("myFloat")); assertEquals(2.18, cprofile.get("myDouble")); assertEquals("value1", cprofile.get("myQueryProfile.anyString")); @@ -205,25 +203,25 @@ public class QueryProfileTypeTestCase { /** Tests assigning a subprofile directly */ @Test public void testTypedAssignmentOfQueryProfilesNonStrict() { - QueryProfile profile=new QueryProfile("test"); + QueryProfile profile = new QueryProfile("test"); profile.setType(testtype); QueryProfile map1=new QueryProfile("myMap1"); - map1.set("key1","value1", registry); + map1.set("key1", "value1", registry); QueryProfile map2=new QueryProfile("myMap2"); - map2.set("key2","value2", registry); + map2.set("key2", "value2", registry); QueryProfile myUser=new QueryProfile("myUser"); myUser.setType(user); - myUser.set("myUserString","userValue1", registry); - myUser.set("myUserInteger",442, registry); + myUser.set("myUserString", "userValue1", registry); + myUser.set("myUserInteger", 442, registry); assertWrongType(profile,"reference to a query profile","myQueryProfile","aString"); - profile.set("myQueryProfile",map1, registry); - profile.set("someMap",map2, registry); // Legal because this is not strict - assertWrongType(profile,"reference to a query profile of type 'user'","myUserQueryProfile",map1); - profile.set("myUserQueryProfile",myUser, registry); + profile.set("myQueryProfile", map1, registry); + profile.set("someMap", map2, registry); // Legal because this is not strict + assertWrongType(profile, "reference to a query profile of type 'user'", "myUserQueryProfile", map1); + profile.set("myUserQueryProfile", myUser, registry); CompiledQueryProfile cprofile = profile.compile(null); @@ -236,25 +234,25 @@ public class QueryProfileTypeTestCase { /** Tests assigning a subprofile directly */ @Test public void testTypedAssignmentOfQueryProfilesStrict() { - QueryProfile profile=new QueryProfile("test"); + QueryProfile profile = new QueryProfile("test"); profile.setType(testtypeStrict); QueryProfile map1=new QueryProfile("myMap1"); - map1.set("key1","value1", registry); + map1.set("key1", "value1", registry); QueryProfile map2=new QueryProfile("myMap2"); - map2.set("key2","value2", registry); + map2.set("key2", "value2", registry); - QueryProfile myUser=new QueryProfile("myUser"); + QueryProfile myUser = new QueryProfile("myUser"); myUser.setType(userStrict); - myUser.set("myUserString","userValue1", registry); - myUser.set("myUserInteger",442, registry); + myUser.set("myUserString", "userValue1", registry); + myUser.set("myUserInteger", 442, registry); assertWrongType(profile,"reference to a query profile","myQueryProfile","aString"); - profile.set("myQueryProfile",map1, registry); - assertNotPermitted(profile,"someMap",map2); - assertWrongType(profile,"reference to a query profile of type 'userStrict'","myUserQueryProfile",map1); - profile.set("myUserQueryProfile",myUser, registry); + profile.set("myQueryProfile", map1, registry); + assertNotPermitted(profile,"someMap", map2); + assertWrongType(profile,"reference to a query profile of type 'userStrict'", "myUserQueryProfile", map1); + profile.set("myUserQueryProfile", myUser, registry); CompiledQueryProfile cprofile = profile.compile(null); @@ -271,15 +269,15 @@ public class QueryProfileTypeTestCase { profile.setType(testtype); QueryProfile map1 = new QueryProfile("myMap1"); - map1.set("key1","value1", registry); + map1.set("key1", "value1", registry); QueryProfile map2 = new QueryProfile("myMap2"); - map2.set("key2","value2", registry); + map2.set("key2", "value2", registry); QueryProfile myUser = new QueryProfile("myUser"); myUser.setType(user); - myUser.set("myUserString","userValue1", registry); - myUser.set("myUserInteger",442, registry); + myUser.set("myUserString", "userValue1", registry); + myUser.set("myUserInteger", 442, registry); registry.register(profile); registry.register(map1); @@ -311,18 +309,18 @@ public class QueryProfileTypeTestCase { */ @Test public void testTypedOverridingOfQueryProfileReferencesNonStrictThroughQuery() { - QueryProfile profile=new QueryProfile("test"); + QueryProfile profile = new QueryProfile("test"); profile.setType(testtype); QueryProfile myUser=new QueryProfile("myUser"); myUser.setType(user); - myUser.set("myUserString","userValue1", registry); - myUser.set("myUserInteger",442, registry); + myUser.set("myUserString", "userValue1", registry); + myUser.set("myUserInteger", 442, registry); - QueryProfile newUser=new QueryProfile("newUser"); + QueryProfile newUser = new QueryProfile("newUser"); newUser.setType(user); - newUser.set("myUserString","newUserValue1", registry); - newUser.set("myUserInteger",845, registry); + newUser.set("myUserString", "newUserValue1", registry); + newUser.set("myUserInteger", 845, registry); QueryProfileRegistry registry = new QueryProfileRegistry(); registry.register(profile); @@ -331,7 +329,9 @@ public class QueryProfileTypeTestCase { CompiledQueryProfileRegistry cRegistry = registry.compile(); CompiledQueryProfile cprofile = cRegistry.getComponent("test"); - Query query = new Query(HttpRequest.createTestRequest("?myUserQueryProfile=newUser", com.yahoo.jdisc.http.HttpRequest.Method.GET), cprofile); + Query query = new Query(HttpRequest.createTestRequest("?myUserQueryProfile=newUser", + com.yahoo.jdisc.http.HttpRequest.Method.GET), + cprofile); assertEquals(0, query.errors().size()); @@ -500,8 +500,8 @@ public class QueryProfileTypeTestCase { fail("Above statement should throw"); } catch (IllegalArgumentException e) { // As expected. - assertThat(Exceptions.toMessageString(e), - containsString("Could not set 'myUserQueryProfile.nondeclared' to 'someValue': 'nondeclared' is not declared in query profile type 'userStrict', and the type is strict")); + assertTrue(Exceptions.toMessageString(e).contains( + "Could not set 'myUserQueryProfile.nondeclared' to 'someValue': 'nondeclared' is not declared in query profile type 'userStrict', and the type is strict")); } } @@ -615,8 +615,8 @@ public class QueryProfileTypeTestCase { fail("Above statement should throw"); } catch (IllegalArgumentException e) { // As expected. - assertThat(Exceptions.toMessageString(e), - containsString("Could not set 'subMap.typeProfile.someValue' to 'value': 'someValue' is not declared in query profile type 'testtypeStrict', and the type is strict")); + assertTrue(Exceptions.toMessageString(e).contains( + "Could not set 'subMap.typeProfile.someValue' to 'value': 'someValue' is not declared in query profile type 'testtypeStrict', and the type is strict")); } } diff --git a/container-search/src/test/java/com/yahoo/search/query/textserialize/item/test/ParseItemTestCase.java b/container-search/src/test/java/com/yahoo/search/query/textserialize/item/test/ParseItemTestCase.java index 4da2edf8306..aa0d692ec92 100644 --- a/container-search/src/test/java/com/yahoo/search/query/textserialize/item/test/ParseItemTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/textserialize/item/test/ParseItemTestCase.java @@ -1,7 +1,19 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.query.textserialize.item.test; -import com.yahoo.prelude.query.*; +import com.yahoo.prelude.query.AndItem; +import com.yahoo.prelude.query.ExactStringItem; +import com.yahoo.prelude.query.IntItem; +import com.yahoo.prelude.query.NearItem; +import com.yahoo.prelude.query.NotItem; +import com.yahoo.prelude.query.ONearItem; +import com.yahoo.prelude.query.OrItem; +import com.yahoo.prelude.query.PhraseItem; +import com.yahoo.prelude.query.PrefixItem; +import com.yahoo.prelude.query.RankItem; +import com.yahoo.prelude.query.SubstringItem; +import com.yahoo.prelude.query.SuffixItem; +import com.yahoo.prelude.query.WordItem; import com.yahoo.search.query.textserialize.item.ItemContext; import com.yahoo.search.query.textserialize.item.ItemFormHandler; import com.yahoo.search.query.textserialize.parser.ParseException; @@ -10,10 +22,9 @@ import org.junit.Test; import java.io.StringReader; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsInstanceOf.instanceOf; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; /** * @author Tony Vaagenes @@ -29,50 +40,50 @@ public class ParseItemTestCase { @Test public void parse_and() throws ParseException { - assertThat(parse("(AND)"), instanceOf(AndItem.class)); + assertTrue(parse("(AND)") instanceof AndItem); } @Test public void parse_and_with_children() throws ParseException { AndItem andItem = (AndItem) parse("(AND (WORD 'first') (WORD 'second'))"); - assertThat(andItem.getItemCount(), is(2)); - assertThat(getWord(andItem.getItem(0)), is("first")); + assertEquals(2, andItem.getItemCount()); + assertEquals("first", getWord(andItem.getItem(0))); } @Test public void parse_or() throws ParseException { - assertThat(parse("(OR)"), instanceOf(OrItem.class)); + assertTrue(parse("(OR)") instanceof OrItem); } @Test public void parse_and_not_rest() throws ParseException { - assertThat(parse("(AND-NOT-REST)"), instanceOf(NotItem.class)); + assertTrue(parse("(AND-NOT-REST)") instanceof NotItem); } @Test public void parse_and_not_rest_with_children() throws ParseException { NotItem notItem = (NotItem) parse("(AND-NOT-REST (WORD 'positive') (WORD 'negative'))"); - assertThat(getWord(notItem.getPositiveItem()), is("positive")); - assertThat(getWord(notItem.getItem(1)), is("negative")); + assertEquals("positive", getWord(notItem.getPositiveItem())); + assertEquals("negative", getWord(notItem.getItem(1))); } @Test public void parse_and_not_rest_with_only_negated_children() throws ParseException { NotItem notItem = (NotItem) parse("(AND-NOT-REST null (WORD 'negated-item'))"); assertNull(notItem.getPositiveItem()); - assertThat(notItem.getItem(1), instanceOf(WordItem.class)); + assertTrue(notItem.getItem(1) instanceof WordItem); } @Test public void parse_rank() throws ParseException { - assertThat(parse("(RANK (WORD 'first'))"), instanceOf(RankItem.class)); + assertTrue(parse("(RANK (WORD 'first'))") instanceof RankItem); } @Test public void parse_word() throws ParseException { WordItem wordItem = (WordItem) parse("(WORD 'text')"); - assertThat(wordItem.getWord(), is("text")); + assertEquals("text", wordItem.getWord()); } @Test(expected = IllegalArgumentException.class) @@ -88,65 +99,65 @@ public class ParseItemTestCase { @Test public void parse_int() throws ParseException { IntItem intItem = (IntItem) parse("(INT '[42;]')"); - assertThat(intItem.getNumber(), is("[42;]")); + assertEquals("[42;]", intItem.getNumber()); } @Test public void parse_range() throws ParseException { IntItem intItem = (IntItem) parse("(INT '[42;73]')"); - assertThat(intItem.getNumber(), is("[42;73]")); + assertEquals("[42;73]", intItem.getNumber()); } @Test public void parse_range_withlimit() throws ParseException { IntItem intItem = (IntItem) parse("(INT '[42;73;32]')"); - assertThat(intItem.getNumber(), is("[42;73;32]")); + assertEquals("[42;73;32]", intItem.getNumber()); } @Test public void parse_prefix() throws ParseException { PrefixItem prefixItem = (PrefixItem) parse("(PREFIX 'word')"); - assertThat(prefixItem.getWord(), is("word")); + assertEquals("word", prefixItem.getWord()); } @Test public void parse_subString() throws ParseException { SubstringItem subStringItem = (SubstringItem) parse("(SUBSTRING 'word')"); - assertThat(subStringItem.getWord(), is("word")); + assertEquals("word", subStringItem.getWord()); } @Test public void parse_exactString() throws ParseException { ExactStringItem subStringItem = (ExactStringItem) parse("(EXACT 'word')"); - assertThat(subStringItem.getWord(), is("word")); + assertEquals("word", subStringItem.getWord()); } @Test public void parse_suffix() throws ParseException { SuffixItem suffixItem = (SuffixItem) parse("(SUFFIX 'word')"); - assertThat(suffixItem.getWord(), is("word")); + assertEquals("word", suffixItem.getWord()); } @Test public void parse_phrase() throws ParseException { PhraseItem phraseItem = (PhraseItem) parse("(PHRASE (WORD 'word'))"); - assertThat(phraseItem.getItem(0), instanceOf(WordItem.class)); + assertTrue(phraseItem.getItem(0) instanceof WordItem); } @Test public void parse_near() throws ParseException { - assertThat(parse("(NEAR)"), instanceOf(NearItem.class)); + assertTrue(parse("(NEAR)") instanceof NearItem); } @Test public void parse_onear() throws ParseException { - assertThat(parse("(ONEAR)"), instanceOf(ONearItem.class)); + assertTrue(parse("(ONEAR)") instanceof ONearItem); } @Test public void parse_near_with_distance() throws ParseException { NearItem nearItem = (NearItem) parse("(NEAR {'distance' 42} (WORD 'first'))"); - assertThat(nearItem.getDistance(), is(42)); + assertEquals(42, nearItem.getDistance()); } @Test @@ -154,23 +165,24 @@ public class ParseItemTestCase { AndItem andItem = (AndItem) parse("(AND (WORD {'id' '1'} 'first') (WORD {'connectivity' ['1' 23.5]} 'second'))"); WordItem secondItem = (WordItem) andItem.getItem(1); - assertThat(secondItem.getConnectedItem(), is(andItem.getItem(0))); - assertThat(secondItem.getConnectivity(), is(23.5)); + assertEquals(andItem.getItem(0), secondItem.getConnectedItem()); + assertEquals(23.5, secondItem.getConnectivity(), 0.000001); } @Test public void parse_word_with_index() throws ParseException { WordItem wordItem = (WordItem) parse("(WORD {'index' 'someIndex'} 'text')"); - assertThat(wordItem.getIndexName(), is("someIndex")); + assertEquals("someIndex", wordItem.getIndexName()); } @Test public void parse_unicode_word() throws ParseException { WordItem wordItem = (WordItem) parse("(WORD 'trăm')"); - assertThat(wordItem.getWord(), is("trăm")); + assertEquals("trăm", wordItem.getWord()); } public static String getWord(Object item) { return ((WordItem)item).getWord(); } + } diff --git a/container-search/src/test/java/com/yahoo/search/query/textserialize/serializer/test/SerializeItemTestCase.java b/container-search/src/test/java/com/yahoo/search/query/textserialize/serializer/test/SerializeItemTestCase.java index c73ec4db588..133382cbe91 100644 --- a/container-search/src/test/java/com/yahoo/search/query/textserialize/serializer/test/SerializeItemTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/query/textserialize/serializer/test/SerializeItemTestCase.java @@ -15,44 +15,43 @@ import org.junit.Test; import static com.yahoo.search.query.textserialize.item.test.ParseItemTestCase.parse; import static com.yahoo.search.query.textserialize.item.test.ParseItemTestCase.getWord; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsInstanceOf.instanceOf; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * @author Tony Vaagenes */ public class SerializeItemTestCase { + @Test public void serialize_word_item() { WordItem item = new WordItem("test that \" and \\ works"); item.setIndexName("index\"Name"); WordItem deSerialized = serializeThenParse(item); - assertThat(deSerialized.getWord(), is(item.getWord())); - assertThat(deSerialized.getIndexName(), is(item.getIndexName())); + assertEquals(item.getWord(), deSerialized.getWord()); + assertEquals(item.getIndexName(), deSerialized.getIndexName()); } @Test - public void serialize_and_item() throws ParseException { + public void serialize_and_item() { AndItem andItem = new AndItem(); andItem.addItem(new WordItem("first")); andItem.addItem(new WordItem("second")); AndItem deSerialized = serializeThenParse(andItem); - assertThat(getWord(deSerialized.getItem(0)), is("first")); - assertThat(getWord(deSerialized.getItem(1)), is("second")); - assertThat(deSerialized.getItemCount(), is(2)); + assertEquals("first", getWord(deSerialized.getItem(0))); + assertEquals("second", getWord(deSerialized.getItem(1))); + assertEquals(2, deSerialized.getItemCount()); } @Test - public void serialize_or_item() throws ParseException { - assertThat(serializeThenParse(new OrItem()), - instanceOf(OrItem.class)); + public void serialize_or_item() { + assertTrue(serializeThenParse(new OrItem()) instanceof OrItem); } @Test - public void serialize_not_item() throws ParseException { + public void serialize_not_item() { NotItem notItem = new NotItem(); { notItem.addItem(new WordItem("first")); @@ -63,7 +62,7 @@ public class SerializeItemTestCase { } @Test - public void serialize_near_item() throws ParseException { + public void serialize_near_item() { int distance = 23; NearItem nearItem = new NearItem(distance); { @@ -73,8 +72,8 @@ public class SerializeItemTestCase { NearItem deSerialized = serializeThenParse(nearItem); - assertThat(deSerialized.getDistance(), is(distance)); - assertThat(deSerialized.getItemCount(), is(2)); + assertEquals(distance, deSerialized.getDistance()); + assertEquals(2, deSerialized.getItemCount()); } @Test @@ -83,22 +82,22 @@ public class SerializeItemTestCase { phraseItem.setIndexName("indexName"); PhraseItem deSerialized = serializeThenParse(phraseItem); - assertThat(deSerialized.getItem(0), is(phraseItem.getItem(0))); - assertThat(deSerialized.getItem(1), is(phraseItem.getItem(1))); - assertThat(deSerialized.getIndexName(), is(phraseItem.getIndexName())); + assertEquals(phraseItem.getItem(0), deSerialized.getItem(0)); + assertEquals(phraseItem.getItem(1), deSerialized.getItem(1)); + assertEquals(phraseItem.getIndexName(), deSerialized.getIndexName()); } @Test - public void serialize_equiv_item() throws ParseException { + public void serialize_equiv_item() { EquivItem equivItem = new EquivItem(); equivItem.addItem(new WordItem("first")); EquivItem deSerialized = serializeThenParse(equivItem); - assertThat(deSerialized.getItemCount(), is(1)); + assertEquals(1, deSerialized.getItemCount()); } @Test - public void serialize_connectivity() throws ParseException { + public void serialize_connectivity() { OrItem orItem = new OrItem(); { WordItem first = new WordItem("first"); @@ -113,35 +112,35 @@ public class SerializeItemTestCase { WordItem first = (WordItem) deSerialized.getItem(0); Item second = deSerialized.getItem(1); - assertThat(first.getConnectedItem(), is(second)); - assertThat(first.getConnectivity(), is(3.14)); + assertEquals(second, first.getConnectedItem()); + assertEquals(3.14, first.getConnectivity(), 0.0000001); } @Test - public void serialize_significance() throws ParseException { + public void serialize_significance() { EquivItem equivItem = new EquivItem(); equivItem.setSignificance(24.2); EquivItem deSerialized = serializeThenParse(equivItem); - assertThat(deSerialized.getSignificance(), is(24.2)); + assertEquals(24.2, deSerialized.getSignificance(), 0.00000001); } @Test - public void serialize_unique_id() throws ParseException { + public void serialize_unique_id() { EquivItem equivItem = new EquivItem(); equivItem.setUniqueID(42); EquivItem deSerialized = serializeThenParse(equivItem); - assertThat(deSerialized.getUniqueID(), is(42)); + assertEquals(42, deSerialized.getUniqueID()); } @Test - public void serialize_weight() throws ParseException { + public void serialize_weight() { EquivItem equivItem = new EquivItem(); equivItem.setWeight(42); EquivItem deSerialized = serializeThenParse(equivItem); - assertThat(deSerialized.getWeight(), is(42)); + assertEquals(42, deSerialized.getWeight()); } private static String serialize(Item item) { @@ -156,4 +155,5 @@ public class SerializeItemTestCase { throw new RuntimeException(e); } } + } diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java b/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java index d6e99ec3a44..0f1f77d66b4 100644 --- a/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java @@ -5,7 +5,6 @@ import com.yahoo.config.search.IntConfig; import com.yahoo.config.search.StringConfig; import com.yahoo.container.core.config.HandlersConfigurerDi; import com.yahoo.container.core.config.testutil.HandlersConfigurerTestWrapper; -import com.yahoo.lang.MutableInteger; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; @@ -31,18 +30,19 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertThat; /** * @author bratseth @@ -84,18 +84,18 @@ public class SearchChainConfigurerTestCase { public synchronized void testConfiguration() { HandlersConfigurerTestWrapper configurer = new HandlersConfigurerTestWrapper("dir:" + testDir); - SearchChain simple=getSearchChainRegistryFrom(configurer).getComponent("simple"); + SearchChain simple = getSearchChainRegistryFrom(configurer).getComponent("simple"); assertNotNull(simple); - assertThat(getSearcherNumbers(simple), is(Arrays.asList(1, 2, 3))); + assertEquals(List.of(1, 2, 3), getSearcherNumbers(simple)); - SearchChain child1=getSearchChainRegistryFrom(configurer).getComponent("child:1"); - assertThat(getSearcherNumbers(child1), is(Arrays.asList(1, 2, 4, 5, 7, 8))); + SearchChain child1 = getSearchChainRegistryFrom(configurer).getComponent("child:1"); + assertEquals(List.of(1, 2, 4, 5, 7, 8), getSearcherNumbers(child1)); - SearchChain child2=getSearchChainRegistryFrom(configurer).getComponent("child"); - assertThat(getSearcherNumbers(child2), is(Arrays.asList(3, 6, 7, 9))); + SearchChain child2 = getSearchChainRegistryFrom(configurer).getComponent("child"); + assertEquals(List.of(3, 6, 7, 9), getSearcherNumbers(child2)); // Verify successful loading of an explicitly declared searcher that takes no user-defined configs. - //assertNotNull(SearchChainRegistry.get().getSearcherRegistry().getComponent + // assertNotNull(SearchChainRegistry.get().getSearcherRegistry().getComponent // ("com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase$DeclaredTestSearcher")); configurer.shutdown(); } @@ -137,7 +137,7 @@ public class SearchChainConfigurerTestCase { assertNotNull(configurable); Searcher s = configurable.searchers().get(0); - assertThat(s, instanceOf(ConfigurableSearcher.class)); + assertTrue(s instanceof ConfigurableSearcher); ConfigurableSearcher searcher = (ConfigurableSearcher)s; assertEquals("Value from int.cfg file", 7, searcher.intConfig.intVal()); assertEquals("Value from string.cfg file", "com.yahoo.search.searchchain.config.test", searcher.stringConfig.stringVal()); @@ -164,10 +164,10 @@ public class SearchChainConfigurerTestCase { HandlersConfigurerTestWrapper configurer = new HandlersConfigurerTestWrapper("dir:" + cfgDir); SearcherRegistry searchers = getSearchChainRegistryFrom(configurer).getSearcherRegistry(); - assertThat(searchers.getComponentCount(), is(3)); + assertEquals(3, searchers.getComponentCount()); IntSearcher intSearcher = (IntSearcher)searchers.getComponent(IntSearcher.class.getName()); - assertThat(intSearcher.intConfig.intVal(), is(16)); + assertEquals(16, intSearcher.intConfig.intVal()); StringSearcher stringSearcher = (StringSearcher)searchers.getComponent(StringSearcher.class.getName()); DeclaredTestSearcher noConfigSearcher = (DeclaredTestSearcher)searchers.getComponent(DeclaredTestSearcher.class.getName()); @@ -177,20 +177,20 @@ public class SearchChainConfigurerTestCase { configurer.reloadConfig(); // Registry is rebuilt - assertThat(getSearchChainRegistryFrom(configurer).getSearcherRegistry(), not(searchers)); + assertNotEquals(searchers, getSearchChainRegistryFrom(configurer).getSearcherRegistry()); searchers = getSearchChainRegistryFrom(configurer).getSearcherRegistry(); - assertThat(searchers.getComponentCount(), is(3)); + assertEquals(3, searchers.getComponentCount()); // Searcher with updated config is re-instantiated. IntSearcher intSearcher2 = (IntSearcher)searchers.getComponent(IntSearcher.class.getName()); - assertThat(intSearcher2, not(sameInstance(intSearcher))); - assertThat(intSearcher2.intConfig.intVal(), is(17)); + assertNotSame(intSearcher, intSearcher2); + assertEquals(17, intSearcher2.intConfig.intVal()); // Searchers with unchanged config (or that takes no config) are the same as before. Searcher s = searchers.getComponent(DeclaredTestSearcher.class.getName()); - assertThat(s, sameInstance(noConfigSearcher)); + assertSame(noConfigSearcher, s); s = searchers.getComponent(StringSearcher.class.getName()); - assertThat(s, sameInstance(stringSearcher)); + assertSame(stringSearcher, s); configurer.shutdown(); cleanup(cfgDir); @@ -217,11 +217,11 @@ public class SearchChainConfigurerTestCase { SearchChainRegistry scReg = getSearchChainRegistryFrom(configurer); SearcherRegistry searchers = scReg.getSearcherRegistry(); - assertThat(searchers.getComponentCount(), is(2)); - assertThat(searchers.getComponent(IntSearcher.class.getName()), instanceOf(IntSearcher.class)); - assertThat(searchers.getComponent(StringSearcher.class.getName()), instanceOf(StringSearcher.class)); - assertThat(searchers.getComponent(ConfigurableSearcher.class.getName()), nullValue()); - assertThat(searchers.getComponent(DeclaredTestSearcher.class.getName()), nullValue()); + assertEquals(2, searchers.getComponentCount()); + assertTrue(searchers.getComponent(IntSearcher.class.getName()) instanceof IntSearcher); + assertTrue(searchers.getComponent(StringSearcher.class.getName()) instanceof StringSearcher); + assertNull(searchers.getComponent(ConfigurableSearcher.class.getName())); + assertNull(searchers.getComponent(DeclaredTestSearcher.class.getName())); IntSearcher intSearcher = (IntSearcher)searchers.getComponent(IntSearcher.class.getName()); @@ -230,16 +230,16 @@ public class SearchChainConfigurerTestCase { createComponentsConfig(testDir + "chainsConfigUpdate_2.cfg", testDir + "handlers.cfg", cfgDir + "/components.cfg"); configurer.reloadConfig(); - assertThat(getSearchChainRegistryFrom(configurer), not(scReg)); + assertNotEquals(scReg, getSearchChainRegistryFrom(configurer)); // In the new registry, the correct searchers are removed and added - assertThat(getSearchChainRegistryFrom(configurer).getSearcherRegistry(), not(searchers)); + assertNotEquals(searchers, getSearchChainRegistryFrom(configurer).getSearcherRegistry()); searchers = getSearchChainRegistryFrom(configurer).getSearcherRegistry(); - assertThat(searchers.getComponentCount(), is(3)); - assertThat(searchers.getComponent(IntSearcher.class.getName()), sameInstance(intSearcher)); - assertThat(searchers.getComponent(ConfigurableSearcher.class.getName()), instanceOf(ConfigurableSearcher.class)); - assertThat(searchers.getComponent(DeclaredTestSearcher.class.getName()), instanceOf(DeclaredTestSearcher.class)); - assertThat(searchers.getComponent(StringSearcher.class.getName()), nullValue()); + assertEquals(3, searchers.getComponentCount()); + assertSame(intSearcher, searchers.getComponent(IntSearcher.class.getName())); + assertTrue(searchers.getComponent(ConfigurableSearcher.class.getName()) instanceof ConfigurableSearcher); + assertTrue(searchers.getComponent(DeclaredTestSearcher.class.getName()) instanceof DeclaredTestSearcher); + assertNull(searchers.getComponent(StringSearcher.class.getName())); configurer.shutdown(); cleanup(cfgDir); } @@ -297,8 +297,8 @@ public class SearchChainConfigurerTestCase { * Copies src file to dst file. If the dst file does not exist, it is created. */ public static void copyFile(String srcName, String dstName) throws IOException { - InputStream src = new FileInputStream(new File(srcName)); - OutputStream dst = new FileOutputStream(new File(dstName)); + InputStream src = new FileInputStream(srcName); + OutputStream dst = new FileOutputStream(dstName); byte[] buf = new byte[1024]; int len; while ((len = src.read(buf)) > 0) { diff --git a/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java b/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java index abea2b0f259..f6273fdf723 100644 --- a/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/test/QueryTestCase.java @@ -45,6 +45,7 @@ import org.junit.Test; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -76,7 +77,6 @@ public class QueryTestCase { assertEquals("", q.properties().get("aParameter")); assertNull(q.properties().get("notSetParameter")); - Query query = q; String body = "a bb. ccc??!"; Linguistics linguistics = new SimpleLinguistics(); @@ -85,7 +85,7 @@ public class QueryTestCase { if (token.isIndexable()) and.addItem(new WordItem(token.getTokenString(), "body")); } - query.getModel().getQueryTree().setRoot(and); + q.getModel().getQueryTree().setRoot(and); } // TODO: YQL work in progress (jon) @@ -142,15 +142,11 @@ public class QueryTestCase { @Test public void testCloneWithConnectivity() { - List<String> l = new ArrayList(); - l.add("a"); - l.add("b"); - l.add("c"); - l.add("a"); + List<String> l = List.of("a", "b", "c", "a"); printIt(l.stream().filter(i -> isA(i)).collect(Collectors.toList())); printIt(l.stream().filter(i -> ! isA(i)).collect(Collectors.toList())); - Query q = new Query(); + Query q = new Query(); WordItem a = new WordItem("a"); WordItem b = new WordItem("b"); WordItem c = new WordItem("c"); @@ -497,7 +493,7 @@ public class QueryTestCase { assertTrue(q.getGroupingSessionCache()); } - public class TestClass { + public static class TestClass { private int testInt = 0; @@ -1157,17 +1153,12 @@ public class QueryTestCase { * be written as a single string. */ public static String httpEncode(String s) { - try { - if (s == null) return null; - String encoded = URLEncoder.encode(s, "utf-8"); - encoded = encoded.replaceAll("%3F", "?"); - encoded = encoded.replaceAll("%3D", "="); - encoded = encoded.replaceAll("%26", "&"); - return encoded; - } - catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } + if (s == null) return null; + String encoded = URLEncoder.encode(s, StandardCharsets.UTF_8); + encoded = encoded.replaceAll("%3F", "?"); + encoded = encoded.replaceAll("%3D", "="); + encoded = encoded.replaceAll("%26", "&"); + return encoded; } } diff --git a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java index c652c299b08..55fb53b4460 100644 --- a/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/yql/YqlParserTestCase.java @@ -329,6 +329,13 @@ public class YqlParserTestCase { } @Test + public void testValuesCanBeQuoted() { + assertEquals("merkelapp", + getRootWord("select foo from bar where baz contains " + + "( {label: \"merkelapp\"} \"colors\");").getLabel()); + } + + @Test public void testSameElement() { assertParse("select foo from bar where baz contains sameElement(f1 contains \"a\", f2 contains \"b\")", "baz:{f1:a f2:b}"); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java index 9fb6fa1501b..4679f660319 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/athenz/ZmsClientMock.java @@ -40,7 +40,7 @@ public class ZmsClientMock implements ZmsClient { private final AthenzDbMock athenz; private final AthenzIdentity controllerIdentity; private static final Pattern TENANT_RESOURCE_PATTERN = Pattern.compile("service\\.hosting\\.tenant\\.(?<tenantDomain>[\\w\\-_]+)\\..*"); - private static final Pattern APPLICATION_RESOURCE_PATTERN = Pattern.compile("service\\.hosting\\.tenant\\.[\\w\\-_]+\\.res_group\\.(?<resourceGroup>[\\w\\-_]+)\\.(?<environment>[.*]+)"); + private static final Pattern APPLICATION_RESOURCE_PATTERN = Pattern.compile("service\\.hosting\\.tenant\\.[\\w\\-_]+\\.res_group\\.(?<resourceGroup>[\\w\\-_]+)\\.wildcard"); public ZmsClientMock(AthenzDbMock athenz, AthenzIdentity controllerIdentity) { this.athenz = athenz; diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java index c40c2d4db01..5cdd12ecb1c 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/Role.java @@ -52,11 +52,6 @@ public abstract class Role { return new TenantRole(RoleDefinition.developer, tenant); } - /** Returns a {@link RoleDefinition#hostedDeveloper} for the current system and given tenant. */ - public static TenantRole hostedDeveloper(TenantName tenant) { - return new TenantRole(RoleDefinition.hostedDeveloper, tenant); - } - /** Returns a {@link RoleDefinition#administrator} for the current system and given tenant. */ public static TenantRole administrator(TenantName tenant) { return new TenantRole(RoleDefinition.administrator, tenant); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java index aed5c08f0db..eeb3bae4431 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/role/RoleDefinition.java @@ -60,9 +60,6 @@ public enum RoleDefinition { Policy.billingInformationRead, Policy.secretStoreOperations), - /** Developer for manual deployments for a tenant */ - hostedDeveloper(Policy.developmentDeployment), - /** Admin — the administrative function for user management etc. */ administrator(Policy.tenantUpdate, Policy.tenantManager, diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java index 28cf132af90..d116ef3333c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/athenz/impl/AthenzFacade.java @@ -5,9 +5,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.inject.Inject; import com.yahoo.config.provision.ApplicationName; -import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.TenantName; -import com.yahoo.config.provision.Zone; import com.yahoo.text.Text; import com.yahoo.vespa.athenz.api.AthenzDomain; import com.yahoo.vespa.athenz.api.AthenzIdentity; @@ -250,9 +248,9 @@ public class AthenzFacade implements AccessControl { } public boolean hasApplicationAccess( - AthenzIdentity identity, ApplicationAction action, AthenzDomain tenantDomain, ApplicationName applicationName, Optional<Zone> zone) { + AthenzIdentity identity, ApplicationAction action, AthenzDomain tenantDomain, ApplicationName applicationName) { return hasAccess( - action.name(), applicationResourceString(tenantDomain, applicationName, zone), identity); + action.name(), applicationResourceString(tenantDomain, applicationName), identity); } public boolean hasTenantAdminAccess(AthenzIdentity identity, AthenzDomain tenantDomain) { @@ -327,9 +325,8 @@ public class AthenzFacade implements AccessControl { return resourceStringPrefix(tenantDomain) + ".wildcard"; } - private String applicationResourceString(AthenzDomain tenantDomain, ApplicationName applicationName, Optional<Zone> zone) { - String environment = zone.map(Zone::environment).map(Environment::value).orElse("*"); - return resourceStringPrefix(tenantDomain) + "." + "res_group" + "." + applicationName.value() + "." + environment; + private String applicationResourceString(AthenzDomain tenantDomain, ApplicationName applicationName) { + return resourceStringPrefix(tenantDomain) + "." + "res_group" + "." + applicationName.value() + ".wildcard"; } private enum TenantAction { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java index 7ab3b75a758..c685390c7ed 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/filter/AthenzRoleFilter.java @@ -4,10 +4,7 @@ package com.yahoo.vespa.hosted.controller.restapi.filter; import com.auth0.jwt.JWT; import com.google.inject.Inject; import com.yahoo.config.provision.ApplicationName; -import com.yahoo.config.provision.Environment; -import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.TenantName; -import com.yahoo.config.provision.Zone; import com.yahoo.jdisc.http.filter.DiscFilterRequest; import com.yahoo.jdisc.http.filter.security.base.JsonSecurityRequestFilterBase; @@ -19,7 +16,6 @@ import com.yahoo.restapi.Path; import com.yahoo.vespa.athenz.api.AthenzDomain; import com.yahoo.vespa.athenz.api.AthenzIdentity; import com.yahoo.vespa.athenz.api.AthenzPrincipal; -import com.yahoo.vespa.athenz.api.AthenzUser; import com.yahoo.vespa.athenz.client.zms.ZmsClientException; import com.yahoo.vespa.hosted.controller.Controller; import com.yahoo.vespa.hosted.controller.TenantController; @@ -98,15 +94,6 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { path.matches("/application/v4/tenant/{tenant}/application/{application}/{*}"); Optional<ApplicationName> application = Optional.ofNullable(path.get("application")).map(ApplicationName::from); - final Optional<Zone> zone; - if(path.matches("/application/v4/tenant/{tenant}/application/{application}/{*}/instance/{*}/environment/{environment}/region/{region}/{*}")) { - zone = Optional.of(new Zone(Environment.from(path.get("environment")), RegionName.from(path.get("region")))); - } else if(path.matches("/application/v4/tenant/{tenant}/application/{application}/{*}/environment/{environment}/region/{region}/{*}")) { - zone = Optional.of(new Zone(Environment.from(path.get("environment")), RegionName.from(path.get("region")))); - } else { - zone = Optional.empty(); - } - AthenzIdentity identity = principal.getIdentity(); Set<Role> roleMemberships = new CopyOnWriteArraySet<>(); @@ -134,18 +121,10 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { && ! tenant.get().name().value().equals("sandbox")) futures.add(executor.submit(() -> { if ( tenant.get().type() == Tenant.Type.athenz - && hasDeployerAccess(identity, ((AthenzTenant) tenant.get()).domain(), application.get(), zone)) + && hasDeployerAccess(identity, ((AthenzTenant) tenant.get()).domain(), application.get())) roleMemberships.add(Role.buildService(tenant.get().name(), application.get())); })); - if (identity instanceof AthenzUser && zone.isPresent()) { - Zone z = zone.get(); - futures.add(executor.submit(() -> { - if (canDeployToManualZones(identity, ((AthenzTenant) tenant.get()).domain(), application.get(), z)) - roleMemberships.add(Role.hostedDeveloper(tenant.get().name())); - })); - } - futures.add(executor.submit(() -> { if (athenz.hasSystemFlagsAccess(identity, /*dryrun*/false)) roleMemberships.add(Role.systemFlagsDeployer()); @@ -188,22 +167,12 @@ public class AthenzRoleFilter extends JsonSecurityRequestFilterBase { } } - private boolean hasDeployerAccess(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application, Optional<Zone> zone) { + private boolean hasDeployerAccess(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application) { try { return athenz.hasApplicationAccess(identity, ApplicationAction.deploy, tenantDomain, - application, - zone); - } catch (ZmsClientException e) { - throw new RuntimeException("Failed to authorize operation: (" + e.getMessage() + ")", e); - } - } - - private boolean canDeployToManualZones(AthenzIdentity identity, AthenzDomain tenantDomain, ApplicationName application, Zone zone) { - if (! zone.environment().isManuallyDeployed()) return false; - try { - return athenz.hasApplicationAccess(identity, ApplicationAction.deploy, tenantDomain, application, Optional.of(zone)); + application); } catch (ZmsClientException e) { throw new RuntimeException("Failed to authorize operation: (" + e.getMessage() + ")", e); } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java index eab3a37a9c3..9e17b44c9a6 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/ControllerAuthorizationFilterTest.java @@ -4,7 +4,6 @@ package com.yahoo.vespa.hosted.controller.restapi.filter; import com.fasterxml.jackson.databind.ObjectMapper; import com.yahoo.application.container.handler.Request; import com.yahoo.config.provision.SystemName; -import com.yahoo.config.provision.TenantName; import com.yahoo.jdisc.http.HttpRequest.Method; import com.yahoo.jdisc.http.filter.DiscFilterRequest; import com.yahoo.vespa.hosted.controller.ControllerTester; @@ -76,18 +75,6 @@ public class ControllerAuthorizationFilterTest { assertIsAllowed(invokeFilter(filter, createRequest(Method.GET, "/zone/v1/path", securityContext))); } - @Test - public void hostedDeveloper() { - ControllerTester tester = new ControllerTester(); - TenantName tenantName = TenantName.defaultName(); - SecurityContext securityContext = new SecurityContext(() -> "user", Set.of(Role.hostedDeveloper(tenantName))); - - ControllerAuthorizationFilter filter = createFilter(tester); - assertIsAllowed(invokeFilter(filter, createRequest(Method.POST, "/application/v4/tenant/" + tenantName.value() + "/application/app/instance/default/environment/dev/region/region/deploy", securityContext))); - assertIsForbidden(invokeFilter(filter, createRequest(Method.POST, "/application/v4/tenant/" + tenantName.value() + "/application/app/instance/default/environment/prod/region/region/deploy", securityContext))); - assertIsForbidden(invokeFilter(filter, createRequest(Method.POST, "/application/v4/tenant/" + tenantName.value() + "/application/app/submit", securityContext))); - } - private static void assertIsAllowed(Optional<AuthorizationResponse> response) { assertFalse("Expected no response from filter, but got \"" + response.map(r -> r.message + "\" (" + r.statusCode + ")").orElse(""), diff --git a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java index b39a3309ad9..75d6cab273a 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java @@ -226,6 +226,12 @@ public class PermanentFlags { "Takes effect on next redeployment", APPLICATION_ID); + public static final UnboundListFlag<String> IGNORED_HTTP_USER_AGENTS = defineListFlag( + "ignored-http-user-agents", List.of(), String.class, + "List of user agents to ignore (crawlers etc)", + "Takes effect immediately.", + ZONE_ID, APPLICATION_ID); + private PermanentFlags() {} private static UnboundBooleanFlag defineFeatureFlag( diff --git a/juniper/src/vespa/juniper/sumdesc.cpp b/juniper/src/vespa/juniper/sumdesc.cpp index 1a27ffaefb0..969616423e8 100644 --- a/juniper/src/vespa/juniper/sumdesc.cpp +++ b/juniper/src/vespa/juniper/sumdesc.cpp @@ -18,6 +18,17 @@ LOG_SETUP(".juniper.sumdesc"); namespace { +static constexpr char replacement_char = '.'; + +char printable_char(char c) +{ + unsigned char uc = (unsigned char) c; + if (uc >= 0x80 || uc < (unsigned char) ' ') { + return replacement_char; + } + return c; +} + bool wordchar(const unsigned char* s) { unsigned char c = *s; @@ -98,7 +109,7 @@ int complete_word(unsigned char* start, ssize_t length, // the read: for (;;) { LOG(spam, "[%s%d%s%c]", (whitespace_elim ? "^" : ""), - moved, (increment > 0 ? "+" : "-"), *ptr); + moved, (increment > 0 ? "+" : "-"), printable_char(*ptr)); int cur_move = Fast_UnicodeUtil::UTF8move(start, length, ptr, increment); @@ -114,11 +125,11 @@ int complete_word(unsigned char* start, ssize_t length, // Give up if we found a split of a word if (cur_move <= 0) // == 0 to avoid UTF8move bug in fastlib 1.3.3.. { - LOG(spam, "complete_word: Failing at char %c/0x%x", *ptr, *ptr); + LOG(spam, "complete_word: Failing at char %c/0x%x", printable_char(*ptr), *ptr); break; } if (chartest(ptr)) { - LOG(spam, "complete_word: Breaking at char %c/0x%x (%d)", *ptr, + LOG(spam, "complete_word: Breaking at char %c/0x%x (%d)", printable_char(*ptr), *ptr, cur_move); // count this character (it is the first blank/wordchar) // only if we are going forward and it is a word character @@ -459,12 +470,12 @@ int SummaryDesc::complete_extended_token(unsigned char* start, ssize_t length, // Handle default case ("ordinary" space) if (!word_connector(preptr)) { - LOG(spam, "Not a word connector case (%c)", *preptr); + LOG(spam, "Not a word connector case (%c)", printable_char(*preptr)); return moved; } char wconn = *preptr; (void) wconn; - LOG(spam, "Found word connector case candidate (%c)", wconn); + LOG(spam, "Found word connector case candidate (%c)", printable_char(wconn)); // Read the character before/after the connector character: int addlen = Fast_UnicodeUtil::UTF8move(start, length, @@ -498,7 +509,7 @@ int SummaryDesc::complete_extended_token(unsigned char* start, ssize_t length, ptr = preptr; LOG(spam, "Found proper word connector case (%c,%c) yet moved %d", - wconn, *preptr, moved); + printable_char(wconn), printable_char(*preptr), moved); } } @@ -590,7 +601,7 @@ std::string SummaryDesc::get_summary(const char* buffer, size_t bytes, } else if (!d._highlight) { LOG(spam, "Not completing word at " "char %c/0x%x, prev_end %" PRId64 ", pos %" PRId64, - *ptr, *ptr, static_cast<int64_t>(prev_end), static_cast<int64_t>(pos)); + printable_char(*ptr), *ptr, static_cast<int64_t>(prev_end), static_cast<int64_t>(pos)); } /* Point to "current" endpos to check for split word/ending @@ -616,7 +627,7 @@ std::string SummaryDesc::get_summary(const char* buffer, size_t bytes, } else if (!d._highlight) { LOG(spam, "Not completing word at " "char %c/0x%x, next_pos %" PRId64, - *ptr, *ptr, static_cast<int64_t>(next_pos)); + printable_char(*ptr), *ptr, static_cast<int64_t>(next_pos)); } JD_INVAR(JD_DESC, len >= 0, len = 0, diff --git a/searchlib/src/vespa/searchlib/attribute/changevector.h b/searchlib/src/vespa/searchlib/attribute/changevector.h index 271497398a8..d929e8615a9 100644 --- a/searchlib/src/vespa/searchlib/attribute/changevector.h +++ b/searchlib/src/vespa/searchlib/attribute/changevector.h @@ -25,7 +25,7 @@ struct ChangeBase { DIV, CLEARDOC }; - enum {UNSET_ENTRY_REF = 0xffffffffu}; + enum {UNSET_ENTRY_REF = 0}; ChangeBase() : _type(NOOP), diff --git a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp index 79957217267..f9301557c0c 100644 --- a/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp +++ b/searchsummary/src/vespa/searchsummary/docsummary/dynamicteaserdfw.cpp @@ -392,7 +392,7 @@ DynamicTeaserDFW::makeDynamicTeaser(uint32_t docid, vespalib::stringref input, G std::ostringstream hexDump; hexDump << vespalib::HexDump(input.data(), input.length()); LOG(spam, "makeDynamicTeaser: docid=%d, input='%s', hexdump:\n%s", - docid, input.data(), hexDump.str().c_str()); + docid, std::string(input.data(), input.length()).c_str(), hexDump.str().c_str()); } auto langid = static_cast<uint32_t>(-1); diff --git a/storage/src/tests/distributor/top_level_distributor_test.cpp b/storage/src/tests/distributor/top_level_distributor_test.cpp index 548f0f6be2c..a0477e352d1 100644 --- a/storage/src/tests/distributor/top_level_distributor_test.cpp +++ b/storage/src/tests/distributor/top_level_distributor_test.cpp @@ -90,6 +90,10 @@ struct TopLevelDistributorTest : Test, TopLevelDistributorTestUtil { return _distributor->getBucketSpacesStats(); } + std::unordered_map<uint16_t, uint32_t> distributor_min_replica_stats() { + return _distributor->getMinReplica(); + } + uint64_t db_sample_interval_sec() const noexcept { // Sampling interval is equal across stripes, so just grab the first one and go with it. return std::chrono::duration_cast<std::chrono::seconds>( @@ -471,7 +475,7 @@ TEST_F(TopLevelDistributorTest, host_info_reporter_config_is_propagated_to_repor namespace { -void assert_invalid_stats_for_all_spaces( +void assert_invalid_bucket_stats_for_all_spaces( const BucketSpacesStatsProvider::PerNodeBucketSpacesStats& stats, uint16_t node_index) { @@ -486,9 +490,15 @@ void assert_invalid_stats_for_all_spaces( ASSERT_FALSE(space_iter->second.valid()); } +void assert_min_replica_stats_zeroed(const std::unordered_map<uint16_t, uint32_t>& stats, uint16_t node_index) { + auto iter = stats.find(node_index); + ASSERT_TRUE(iter != stats.cend()); + EXPECT_EQ(iter->second, 0); } -TEST_F(TopLevelDistributorTest, entering_recovery_mode_resets_bucket_space_stats_across_all_stripes) { +} + +TEST_F(TopLevelDistributorTest, entering_recovery_mode_resets_bucket_space_and_min_replica_stats_across_all_stripes) { // Set up a cluster state + DB contents which implies merge maintenance ops setup_distributor(Redundancy(2), NodeCount(2), "version:1 distributor:1 storage:2"); add_nodes_to_stripe_bucket_db(document::BucketId(16, 1), "0=1/1/1/t/a"); @@ -503,10 +513,18 @@ TEST_F(TopLevelDistributorTest, entering_recovery_mode_resets_bucket_space_stats // from state version 2. Exposing stats from version 1 risks reporting stale // information back to the cluster controller. const auto stats = distributor_bucket_spaces_stats(); - ASSERT_EQ(2, stats.size()); - - assert_invalid_stats_for_all_spaces(stats, 0); - assert_invalid_stats_for_all_spaces(stats, 2); + ASSERT_EQ(stats.size(), 2); + + assert_invalid_bucket_stats_for_all_spaces(stats, 0); + assert_invalid_bucket_stats_for_all_spaces(stats, 2); + + auto min_replica_stats = distributor_min_replica_stats(); + ASSERT_EQ(min_replica_stats.size(), 2); + assert_min_replica_stats_zeroed(min_replica_stats, 0); + // Even though we don't have any replicas on node 2 in the DB, we don't know this until + // we've completed a full DB scan and updated the stats. Until that point in time we + // have to assume we _do_ have replicas with an unknown replication factor. + assert_min_replica_stats_zeroed(min_replica_stats, 2); } TEST_F(TopLevelDistributorTest, leaving_recovery_mode_immediately_sends_getnodestate_replies) { diff --git a/storage/src/tests/storageserver/statemanagertest.cpp b/storage/src/tests/storageserver/statemanagertest.cpp index fc22759139b..729976d2dce 100644 --- a/storage/src/tests/storageserver/statemanagertest.cpp +++ b/storage/src/tests/storageserver/statemanagertest.cpp @@ -43,6 +43,8 @@ struct StateManagerTest : Test { std::string get_node_info() const { return _manager->getNodeInfo(); } + + void extract_cluster_state_version_from_host_info(uint32_t& version_out); }; StateManagerTest::StateManagerTest() @@ -54,8 +56,8 @@ StateManagerTest::StateManagerTest() } void -StateManagerTest::SetUp() { - vdstestlib::DirConfig config(getStandardConfig(true)); +StateManagerTest::SetUp() +{ _node = std::make_unique<TestServiceLayerApp>(NodeIndex(2)); // Clock will increase 1 sec per call. _node->getClock().setAbsoluteTimeInSeconds(1); @@ -85,12 +87,39 @@ StateManagerTest::TearDown() { _metricManager.reset(); } -void StateManagerTest::force_current_cluster_state_version(uint32_t version) { +void +StateManagerTest::force_current_cluster_state_version(uint32_t version) +{ ClusterState state(*_manager->getClusterStateBundle()->getBaselineClusterState()); state.setVersion(version); _manager->setClusterStateBundle(lib::ClusterStateBundle(state)); } +void +StateManagerTest::extract_cluster_state_version_from_host_info(uint32_t& version_out) +{ + std::string nodeInfoString = get_node_info(); + vespalib::Slime nodeInfo; + vespalib::slime::JsonFormat::decode(nodeInfoString, nodeInfo); + + vespalib::slime::Symbol lookupSymbol = nodeInfo.lookup("cluster-state-version"); + if (lookupSymbol.undefined()) { + FAIL() << "No cluster-state-version was found in the node info"; + } + + auto& cursor = nodeInfo.get(); + auto& clusterStateVersionCursor = cursor["cluster-state-version"]; + if (!clusterStateVersionCursor.valid()) { + FAIL() << "No cluster-state-version was found in the node info"; + } + + if (clusterStateVersionCursor.type().getId() != vespalib::slime::LONG::ID) { + FAIL() << "No cluster-state-version was found in the node info"; + } + + version_out = clusterStateVersionCursor.asLong(); +} + #define GET_ONLY_OK_REPLY(varname) \ { \ ASSERT_EQ(size_t(1), _upper->getNumReplies()); \ @@ -214,29 +243,9 @@ TEST_F(StateManagerTest, reported_node_state) { TEST_F(StateManagerTest, current_cluster_state_version_is_included_in_host_info_json) { force_current_cluster_state_version(123); - - std::string nodeInfoString = get_node_info(); - vespalib::Memory goldenMemory(nodeInfoString); - vespalib::Slime nodeInfo; - vespalib::slime::JsonFormat::decode(nodeInfoString, nodeInfo); - - vespalib::slime::Symbol lookupSymbol = nodeInfo.lookup("cluster-state-version"); - if (lookupSymbol.undefined()) { - FAIL() << "No cluster-state-version was found in the node info"; - } - - auto& cursor = nodeInfo.get(); - auto& clusterStateVersionCursor = cursor["cluster-state-version"]; - if (!clusterStateVersionCursor.valid()) { - FAIL() << "No cluster-state-version was found in the node info"; - } - - if (clusterStateVersionCursor.type().getId() != vespalib::slime::LONG::ID) { - FAIL() << "No cluster-state-version was found in the node info"; - } - - int version = clusterStateVersionCursor.asLong(); - EXPECT_EQ(123, version); + uint32_t version; + ASSERT_NO_FATAL_FAILURE(extract_cluster_state_version_from_host_info(version)); + EXPECT_EQ(version, 123); } void StateManagerTest::mark_reported_node_state_up() { @@ -349,4 +358,42 @@ TEST_F(StateManagerTest, activation_command_is_bounced_with_current_cluster_stat EXPECT_EQ(12345, activate_reply.actualVersion()); } +TEST_F(StateManagerTest, non_deferred_cluster_state_sets_reported_cluster_state_version) { + auto cmd = std::make_shared<api::SetSystemStateCommand>(lib::ClusterState("version:1234 distributor:1 storage:1")); + cmd->setTimeout(1000s); + cmd->setSourceIndex(0); + _upper->sendDown(cmd); + std::shared_ptr<api::StorageReply> reply; + GET_ONLY_OK_REPLY(reply); + + uint32_t version; + ASSERT_NO_FATAL_FAILURE(extract_cluster_state_version_from_host_info(version)); + EXPECT_EQ(version, 1234); +} + +TEST_F(StateManagerTest, deferred_cluster_state_does_not_update_state_until_activation_edge) { + force_current_cluster_state_version(100); + + lib::ClusterStateBundle deferred_bundle(lib::ClusterState("version:101 distributor:1 storage:1"), {}, true); + auto state_cmd = std::make_shared<api::SetSystemStateCommand>(deferred_bundle); + state_cmd->setTimeout(1000s); + state_cmd->setSourceIndex(0); + _upper->sendDown(state_cmd); + std::shared_ptr<api::StorageReply> reply; + GET_ONLY_OK_REPLY(reply); + + uint32_t version; + ASSERT_NO_FATAL_FAILURE(extract_cluster_state_version_from_host_info(version)); + EXPECT_EQ(version, 100); // Not yet updated to version 101 + + auto activation_cmd = std::make_shared<api::ActivateClusterStateVersionCommand>(101); + activation_cmd->setTimeout(1000s); + activation_cmd->setSourceIndex(0); + _upper->sendDown(activation_cmd); + GET_ONLY_OK_REPLY(reply); + + ASSERT_NO_FATAL_FAILURE(extract_cluster_state_version_from_host_info(version)); + EXPECT_EQ(version, 101); +} + } // storage diff --git a/storage/src/vespa/storage/common/hostreporter/hostinfo.cpp b/storage/src/vespa/storage/common/hostreporter/hostinfo.cpp index f15885769e6..7ff999735c0 100644 --- a/storage/src/vespa/storage/common/hostreporter/hostinfo.cpp +++ b/storage/src/vespa/storage/common/hostreporter/hostinfo.cpp @@ -9,8 +9,7 @@ HostInfo::HostInfo() { registerReporter(&versionReporter); } -HostInfo::~HostInfo() { -} +HostInfo::~HostInfo() = default; void HostInfo::printReport(vespalib::JsonStream& report) { for (HostReporter* reporter : customReporters) { diff --git a/storage/src/vespa/storage/common/hostreporter/hostreporter.h b/storage/src/vespa/storage/common/hostreporter/hostreporter.h index 115115328cc..6ce6bd803df 100644 --- a/storage/src/vespa/storage/common/hostreporter/hostreporter.h +++ b/storage/src/vespa/storage/common/hostreporter/hostreporter.h @@ -11,7 +11,7 @@ namespace storage { class HostReporter { public: virtual void report(vespalib::JsonStream& jsonreport) = 0; - virtual ~HostReporter() {} + virtual ~HostReporter() = default; }; } diff --git a/storage/src/vespa/storage/distributor/distributor_stripe.cpp b/storage/src/vespa/storage/distributor/distributor_stripe.cpp index 50c70306d92..bcba976f2c3 100644 --- a/storage/src/vespa/storage/distributor/distributor_stripe.cpp +++ b/storage/src/vespa/storage/distributor/distributor_stripe.cpp @@ -316,9 +316,12 @@ DistributorStripe::enterRecoveryMode() LOG(debug, "Entering recovery mode"); _schedulingMode = MaintenanceScheduler::RECOVERY_SCHEDULING_MODE; _scanner->reset(); - _bucketDBMetricUpdater.reset(); - // TODO reset _bucketDbStats? - invalidate_bucket_spaces_stats(); + // We enter recovery mode due to cluster state or distribution config changes. + // Until we have completed a new DB scan round, we don't know the state of our + // newly owned buckets and must not report stats for these out to the cluster + // controller as they will be stale (valid only for the _previous_ state/config). + // As a consequence, we must explicitly invalidate all such statistics in this edge. + invalidate_internal_db_dependent_stats(); _recoveryTimeStarted = framework::MilliSecTimer(_component.getClock()); } @@ -337,6 +340,17 @@ DistributorStripe::leaveRecoveryMode() _schedulingMode = MaintenanceScheduler::NORMAL_SCHEDULING_MODE; } +void +DistributorStripe::invalidate_internal_db_dependent_stats() +{ + _bucketDBMetricUpdater.reset(); + { + std::lock_guard guard(_metricLock); + invalidate_bucket_spaces_stats(guard); + invalidate_min_replica_stats(guard); + } +} + template <typename NodeFunctor> void DistributorStripe::for_each_available_content_node_in(const lib::ClusterState& state, NodeFunctor&& func) { const auto node_count = state.getNodeCount(lib::NodeType::STORAGE); @@ -357,8 +371,9 @@ BucketSpacesStatsProvider::BucketSpacesStats DistributorStripe::make_invalid_sta return invalid_space_stats; } -void DistributorStripe::invalidate_bucket_spaces_stats() { - std::lock_guard guard(_metricLock); +void +DistributorStripe::invalidate_bucket_spaces_stats([[maybe_unused]] std::lock_guard<std::mutex>& held_metric_lock) +{ _bucketSpacesStats = BucketSpacesStatsProvider::PerNodeBucketSpacesStats(); auto invalid_space_stats = make_invalid_stats_per_configured_space(); @@ -369,6 +384,17 @@ void DistributorStripe::invalidate_bucket_spaces_stats() { } void +DistributorStripe::invalidate_min_replica_stats([[maybe_unused]] std::lock_guard<std::mutex>& held_metric_lock) +{ + _bucketDbStats._minBucketReplica.clear(); + // Insert an explicit zero value for all nodes that are up in the pending/current cluster state + const auto& baseline = *_clusterStateBundle.getBaselineClusterState(); + for_each_available_content_node_in(baseline, [this](const lib::Node& node) { + _bucketDbStats._minBucketReplica[node.getIndex()] = 0; + }); +} + +void DistributorStripe::recheckBucketInfo(uint16_t nodeIdx, const document::Bucket &bucket) { _bucketDBUpdater.recheckBucketInfo(nodeIdx, bucket); } diff --git a/storage/src/vespa/storage/distributor/distributor_stripe.h b/storage/src/vespa/storage/distributor/distributor_stripe.h index ce6a2071efd..809b4dd0e41 100644 --- a/storage/src/vespa/storage/distributor/distributor_stripe.h +++ b/storage/src/vespa/storage/distributor/distributor_stripe.h @@ -259,7 +259,9 @@ private: BucketSpacesStatsProvider::BucketSpacesStats make_invalid_stats_per_configured_space() const; template <typename NodeFunctor> void for_each_available_content_node_in(const lib::ClusterState&, NodeFunctor&&); - void invalidate_bucket_spaces_stats(); + void invalidate_internal_db_dependent_stats(); + void invalidate_bucket_spaces_stats(std::lock_guard<std::mutex>& held_metric_lock); + void invalidate_min_replica_stats(std::lock_guard<std::mutex>& held_metric_lock); void send_updated_host_info_if_required(); void propagate_config_snapshot_to_internal_components(); diff --git a/storage/src/vespa/storage/distributor/min_replica_provider.h b/storage/src/vespa/storage/distributor/min_replica_provider.h index 56fd1e8fc81..a4374b906fe 100644 --- a/storage/src/vespa/storage/distributor/min_replica_provider.h +++ b/storage/src/vespa/storage/distributor/min_replica_provider.h @@ -9,7 +9,7 @@ namespace storage::distributor { class MinReplicaProvider { public: - virtual ~MinReplicaProvider() {} + virtual ~MinReplicaProvider() = default; /** * Get a snapshot of the minimum bucket replica for each of the nodes. diff --git a/storage/src/vespa/storage/storageserver/statemanager.cpp b/storage/src/vespa/storage/storageserver/statemanager.cpp index 7d08f738abe..7cb66ab447f 100644 --- a/storage/src/vespa/storage/storageserver/statemanager.cpp +++ b/storage/src/vespa/storage/storageserver/statemanager.cpp @@ -39,6 +39,7 @@ StateManager::StateManager(StorageComponentRegister& compReg, _nextNodeState(), _systemState(std::make_shared<const ClusterStateBundle>(lib::ClusterState())), _nextSystemState(), + _reported_host_info_cluster_state_version(0), _stateListeners(), _queuedStateRequests(), _threadLock(), @@ -94,58 +95,11 @@ StateManager::print(std::ostream& out, bool verbose, out << "StateManager()"; } -#ifdef ENABLE_BUCKET_OPERATION_LOGGING -namespace { - -vespalib::string -escapeHtml(vespalib::stringref str) -{ - vespalib::asciistream ss; - for (size_t i = 0; i < str.size(); ++i) { - switch (str[i]) { - case '<': - ss << "<"; - break; - case '>': - ss << ">"; - break; - case '&': - ss << "&"; - break; - default: - ss << str[i]; - } - } - return ss.str(); -} - -} -#endif - void StateManager::reportHtmlStatus(std::ostream& out, const framework::HttpUrlPath& path) const { (void) path; -#ifdef ENABLE_BUCKET_OPERATION_LOGGING - if (path.hasAttribute("history")) { - std::istringstream iss(path.getAttribute("history"), std::istringstream::in); - uint64_t rawId; - iss >> std::hex >> rawId; - document::BucketId bid(rawId); - out << "<h3>History for " << bid << "</h3>\n"; - vespalib::string history( - debug::BucketOperationLogger::getInstance().getHistory(bid)); - out << "<pre>" << escapeHtml(history) << "</pre>\n"; - return; - } else if (path.hasAttribute("search")) { - vespalib::string substr(path.getAttribute("search")); - out << debug::BucketOperationLogger::getInstance() - .searchBucketHistories(substr, "/systemstate?history="); - return; - } -#endif - { std::lock_guard lock(_stateLock); const auto &baseLineClusterState = _systemState->getBaselineClusterState(); @@ -342,6 +296,9 @@ StateManager::enableNextClusterState() // overwritten by a non-null pending cluster state afterwards. logNodeClusterStateTransition(*_systemState, *_nextSystemState); _systemState = _nextSystemState; + if (!_nextSystemState->deferredActivation()) { + _reported_host_info_cluster_state_version = _systemState->getVersion(); + } // else: reported version updated upon explicit activation edge _nextSystemState.reset(); _systemStateHistory.emplace_back(_component.getClock().getTimeInMillis(), _systemState); } @@ -511,7 +468,10 @@ StateManager::onActivateClusterStateVersion( auto reply = std::make_shared<api::ActivateClusterStateVersionReply>(*cmd); { std::lock_guard lock(_stateLock); - reply->setActualVersion(_systemState ? _systemState->getVersion() : 0); + reply->setActualVersion(_systemState->getVersion()); + if (cmd->version() == _systemState->getVersion()) { + _reported_host_info_cluster_state_version = _systemState->getVersion(); + } } sendUp(reply); return true; @@ -610,7 +570,7 @@ StateManager::getNodeInfo() const // _systemLock. // - getNodeInfo() (this function) always acquires the same lock. std::lock_guard guard(_stateLock); - stream << "cluster-state-version" << _systemState->getVersion(); + stream << "cluster-state-version" << _reported_host_info_cluster_state_version; _hostInfo->printReport(stream); stream << End(); diff --git a/storage/src/vespa/storage/storageserver/statemanager.h b/storage/src/vespa/storage/storageserver/statemanager.h index 7f8320567bf..194991723f4 100644 --- a/storage/src/vespa/storage/storageserver/statemanager.h +++ b/storage/src/vespa/storage/storageserver/statemanager.h @@ -51,6 +51,7 @@ class StateManager : public NodeStateUpdater, using ClusterStateBundle = lib::ClusterStateBundle; std::shared_ptr<const ClusterStateBundle> _systemState; std::shared_ptr<const ClusterStateBundle> _nextSystemState; + uint32_t _reported_host_info_cluster_state_version; std::list<StateListener*> _stateListeners; typedef std::pair<framework::MilliSecTime, api::GetNodeStateCommand::SP> TimeStatePair; std::list<TimeStatePair> _queuedStateRequests; diff --git a/vespajlib/src/main/java/com/yahoo/io/IOUtils.java b/vespajlib/src/main/java/com/yahoo/io/IOUtils.java index df432e4f787..54cdf5c7b40 100644 --- a/vespajlib/src/main/java/com/yahoo/io/IOUtils.java +++ b/vespajlib/src/main/java/com/yahoo/io/IOUtils.java @@ -227,7 +227,9 @@ public abstract class IOUtils { * @throws IOException if copying any file fails. This will typically result in some files being copied and * others not, i.e this method is not exception safe */ - public static void copyDirectory(File sourceLocation , File targetLocation, int maxRecurseLevel, FilenameFilter filter) throws IOException { + public static void copyDirectory(File sourceLocation, File targetLocation, int maxRecurseLevel, FilenameFilter filter) throws IOException { + if ( ! sourceLocation.exists()) throw new IllegalArgumentException(sourceLocation.getAbsolutePath() + " does not exist"); + if ( ! sourceLocation.isDirectory()) { // copy file InputStream in=null; OutputStream out=null; |