aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src')
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/ReconfigurableDispatcher.java27
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java2
-rw-r--r--container-search/src/main/java/com/yahoo/search/logging/AbstractSpoolingLogger.java12
-rw-r--r--container-search/src/main/java/com/yahoo/search/logging/AbstractThreadedLogger.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java2
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java3
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java5
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java16
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java4
-rw-r--r--container-search/src/test/java/com/yahoo/search/dispatch/LoadBalancerTest.java5
-rw-r--r--container-search/src/test/java/com/yahoo/search/grouping/vespa/RequestBuilderTestCase.java30
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java135
-rw-r--r--container-search/src/test/java/com/yahoo/search/logging/LocalDiskLoggerTest.java12
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java6
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/SortingTestCase.java4
15 files changed, 157 insertions, 117 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/ReconfigurableDispatcher.java b/container-search/src/main/java/com/yahoo/search/dispatch/ReconfigurableDispatcher.java
index 625a8bcb6da..c86c21d677f 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/ReconfigurableDispatcher.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/ReconfigurableDispatcher.java
@@ -1,20 +1,17 @@
package com.yahoo.search.dispatch;
import com.yahoo.component.ComponentId;
+import com.yahoo.component.annotation.Inject;
import com.yahoo.config.subscription.ConfigSubscriber;
+import com.yahoo.container.QrConfig;
import com.yahoo.container.handler.VipStatus;
-import com.yahoo.messagebus.network.rpc.SlobrokConfigSubscriber;
import com.yahoo.vespa.config.search.DispatchConfig;
import com.yahoo.vespa.config.search.DispatchNodesConfig;
import com.yahoo.yolean.UncheckedInterruptedException;
-import java.util.Objects;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import static java.util.Objects.requireNonNull;
-
/**
* @author jonmv
*/
@@ -22,10 +19,20 @@ public class ReconfigurableDispatcher extends Dispatcher {
private final ConfigSubscriber subscriber;
- public ReconfigurableDispatcher(ComponentId clusterId, DispatchConfig dispatchConfig, VipStatus vipStatus) {
+ @Inject
+ public ReconfigurableDispatcher(ComponentId clusterId, DispatchConfig dispatchConfig, QrConfig qrConfig, VipStatus vipStatus) {
super(clusterId, dispatchConfig, new DispatchNodesConfig.Builder().build(), vipStatus);
this.subscriber = new ConfigSubscriber();
- this.subscriber.subscribe(this::updateWithNewConfig, DispatchNodesConfig.class, clusterId.stringValue());
+ CountDownLatch configured = new CountDownLatch(1);
+ this.subscriber.subscribe(config -> { updateWithNewConfig(config); configured.countDown(); },
+ DispatchNodesConfig.class, configId(clusterId, qrConfig));
+ try {
+ if ( ! configured.await(1, TimeUnit.MINUTES))
+ throw new IllegalStateException("timed out waiting for initial dispatch nodes config for " + clusterId.getName());
+ }
+ catch (InterruptedException e) {
+ throw new UncheckedInterruptedException("interrupted waiting for initial dispatch nodes config for " + clusterId.getName(), e);
+ }
}
@Override
@@ -34,4 +41,8 @@ public class ReconfigurableDispatcher extends Dispatcher {
super.deconstruct();
}
+ private static String configId(ComponentId clusterId, QrConfig qrConfig) {
+ return qrConfig.clustername() + "/component/" + clusterId.getName();
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java b/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java
index c931c6a356f..45a0c606584 100644
--- a/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java
+++ b/container-search/src/main/java/com/yahoo/search/handler/Json2SingleLevelMap.java
@@ -77,7 +77,7 @@ class Json2SingleLevelMap {
} else if (token == JsonToken.START_ARRAY) {
map.put(fieldName, skipChildren(parser, buf));
} else if (token == JsonToken.START_OBJECT) {
- if (fieldName.equals("select.where") || fieldName.equals("select.grouping")) {
+ if (fieldName.startsWith("input.") || fieldName.equals("select.where") || fieldName.equals("select.grouping")) {
map.put(fieldName, skipChildren(parser, buf));
} else {
parse(map, fieldName + ".");
diff --git a/container-search/src/main/java/com/yahoo/search/logging/AbstractSpoolingLogger.java b/container-search/src/main/java/com/yahoo/search/logging/AbstractSpoolingLogger.java
index 601da11ab33..ec8e7dd3a79 100644
--- a/container-search/src/main/java/com/yahoo/search/logging/AbstractSpoolingLogger.java
+++ b/container-search/src/main/java/com/yahoo/search/logging/AbstractSpoolingLogger.java
@@ -3,7 +3,6 @@ package com.yahoo.search.logging;
import com.yahoo.concurrent.DaemonThreadFactory;
-import java.io.IOException;
import java.time.Clock;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
@@ -54,8 +53,15 @@ public abstract class AbstractSpoolingLogger extends AbstractThreadedLogger impl
return true;
}
- // TODO Call from a component or make this class a component
- public void shutdown() {
+ @Deprecated
+ /*
+ @deprecated use {@link #deconstruct()} instead
+ */
+ public void shutdown() { deconstruct(); }
+
+ @Override
+ public void deconstruct() {
+ super.deconstruct();
executorService.shutdown();
try {
if ( ! executorService.awaitTermination(10, TimeUnit.SECONDS))
diff --git a/container-search/src/main/java/com/yahoo/search/logging/AbstractThreadedLogger.java b/container-search/src/main/java/com/yahoo/search/logging/AbstractThreadedLogger.java
index ffc916bad65..db5d0494822 100644
--- a/container-search/src/main/java/com/yahoo/search/logging/AbstractThreadedLogger.java
+++ b/container-search/src/main/java/com/yahoo/search/logging/AbstractThreadedLogger.java
@@ -2,6 +2,8 @@
package com.yahoo.search.logging;
+import com.yahoo.component.AbstractComponent;
+
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
@@ -10,7 +12,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
-abstract class AbstractThreadedLogger implements Logger {
+abstract class AbstractThreadedLogger extends AbstractComponent implements Logger {
private final static java.util.logging.Logger log = java.util.logging.Logger.getLogger(AbstractThreadedLogger.class.getName());
@@ -51,10 +53,15 @@ abstract class AbstractThreadedLogger implements Logger {
}
/**
- * Actually transports the entry to it's destination
+ * Actually transports the entry to its destination
*/
public abstract boolean transport(LoggerEntry entry);
+ /** Synchronously shuts down and waits for enqueued entries to be sent. */
+ @Override
+ public void deconstruct() {
+ executor.close();
+ }
private static class WorkerThread extends Thread {
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java
index f73ed52246c..7b9fe7da7a2 100644
--- a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileProperties.java
@@ -108,7 +108,7 @@ public class QueryProfileProperties extends Properties {
/**
* Sets a value in this query profile
*
- * @throws IllegalArgumentException if this property cannot be set in the wrapped query profile
+ * @throws IllegalInputException if this property cannot be set in the wrapped query profile
*/
@Override
public void set(CompoundName name, Object value, Map<String, String> context) {
diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
index 896a916aa50..99d6959441a 100644
--- a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
+++ b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
@@ -91,6 +91,7 @@ public class QueryProperties extends Properties {
addDualCasedRM(map, Matching.MINHITSPERTHREAD, GetterSetter.of(query -> query.getRanking().getMatching().getMinHitsPerThread(), (query, value) -> query.getRanking().getMatching().setMinHitsPerThread(asInteger(value, 0))));
addDualCasedRM(map, Matching.POST_FILTER_THRESHOLD, GetterSetter.of(query -> query.getRanking().getMatching().getPostFilterThreshold(), (query, value) -> query.getRanking().getMatching().setPostFilterThreshold(asDouble(value, 1.0))));
addDualCasedRM(map, Matching.APPROXIMATE_THRESHOLD, GetterSetter.of(query -> query.getRanking().getMatching().getApproximateThreshold(), (query, value) -> query.getRanking().getMatching().setApproximateThreshold(asDouble(value, 0.05))));
+ addDualCasedRM(map, Matching.TARGET_HITS_MAX_ADJUSTMENT_FACTOR, GetterSetter.of(query -> query.getRanking().getMatching().getTargetHitsMaxAdjustmentFactor(), (query, value) -> query.getRanking().getMatching().setTargetHitsMaxAdjustmentFactor(asDouble(value, 20.0))));
map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.MATCH_PHASE, MatchPhase.ATTRIBUTE), GetterSetter.of(query -> query.getRanking().getMatchPhase().getAttribute(), (query, value) -> query.getRanking().getMatchPhase().setAttribute(asString(value, null))));
map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.MATCH_PHASE, MatchPhase.ASCENDING), GetterSetter.of(query -> query.getRanking().getMatchPhase().getAscending(), (query, value) -> query.getRanking().getMatchPhase().setAscending(asBoolean(value, false))));
@@ -169,7 +170,6 @@ public class QueryProperties extends Properties {
return;
}
- //TODO Why is there error handling in set path and not in get path ?
if (key.first().equals(Ranking.RANKING)) {
if (key.size() > 2) {
String restKey = key.rest().rest().toString();
@@ -189,6 +189,7 @@ public class QueryProperties extends Properties {
}
}
if (reservedPrefix.contains(key.first())) {
+ // Setting a property under the reserved paths are illegal, while retrieving(get) one is not.
throwIllegalParameter(key.rest().toString(), key.first());
} else {
super.set(key, value, context);
diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java
index 6c65a5e898a..6203eadffad 100644
--- a/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java
+++ b/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java
@@ -3,6 +3,7 @@ package com.yahoo.search.query.properties;
import com.yahoo.api.annotations.Beta;
import com.yahoo.language.process.Embedder;
+import com.yahoo.processing.IllegalInputException;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.schema.SchemaInfo;
@@ -46,7 +47,7 @@ public class RankProfileInputProperties extends Properties {
query.getModel().getLanguage());
}
catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Could not set '" + name + "' to '" + value + "'", e);
+ throw new IllegalInputException("Could not set '" + name + "' to '" + value + "'", e);
}
}
}
@@ -84,7 +85,7 @@ public class RankProfileInputProperties extends Properties {
}
private void throwIllegalInput(CompoundName name, Object value, TensorType expectedType) {
- throw new IllegalArgumentException("Could not set '" + name + "' to '" + value + "': " +
+ throw new IllegalInputException("Could not set '" + name + "' to '" + value + "': " +
"This input is declared in rank profile '" + query.getRanking().getProfile() +
"' as " + expectedType);
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
index 35fbd52f967..4d21f32d16d 100644
--- a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
+++ b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
@@ -24,6 +24,7 @@ public class Matching implements Cloneable {
public static final String MINHITSPERTHREAD = "minHitsPerThread";
public static final String POST_FILTER_THRESHOLD = "postFilterThreshold";
public static final String APPROXIMATE_THRESHOLD = "approximateThreshold";
+ public static final String TARGET_HITS_MAX_ADJUSTMENT_FACTOR = "targetHitsMaxAdjustmentFactor";
static {
argumentType =new QueryProfileType(Ranking.MATCHING);
@@ -35,6 +36,7 @@ public class Matching implements Cloneable {
argumentType.addField(new FieldDescription(MINHITSPERTHREAD, "integer"));
argumentType.addField(new FieldDescription(POST_FILTER_THRESHOLD, "double"));
argumentType.addField(new FieldDescription(APPROXIMATE_THRESHOLD, "double"));
+ argumentType.addField(new FieldDescription(TARGET_HITS_MAX_ADJUSTMENT_FACTOR, "double"));
argumentType.freeze();
}
@@ -46,6 +48,7 @@ public class Matching implements Cloneable {
private Integer minHitsPerThread = null;
private Double postFilterThreshold = null;
private Double approximateThreshold = null;
+ private Double targetHitsMaxAdjustmentFactor = null;
public Double getTermwiseLimit() { return termwiseLimit; }
public Integer getNumThreadsPerSearch() { return numThreadsPerSearch; }
@@ -53,6 +56,7 @@ public class Matching implements Cloneable {
public Integer getMinHitsPerThread() { return minHitsPerThread; }
public Double getPostFilterThreshold() { return postFilterThreshold; }
public Double getApproximateThreshold() { return approximateThreshold; }
+ public Double getTargetHitsMaxAdjustmentFactor() { return targetHitsMaxAdjustmentFactor; }
public void setTermwiselimit(double value) {
if ((value < 0.0) || (value > 1.0)) {
@@ -75,6 +79,9 @@ public class Matching implements Cloneable {
public void setApproximateThreshold(double threshold) {
approximateThreshold = threshold;
}
+ public void setTargetHitsMaxAdjustmentFactor(double factor) {
+ targetHitsMaxAdjustmentFactor = factor;
+ }
/** Internal operation - DO NOT USE */
public void prepare(RankProperties rankProperties) {
@@ -97,6 +104,9 @@ public class Matching implements Cloneable {
if (approximateThreshold != null) {
rankProperties.put("vespa.matching.global_filter.lower_limit", String.valueOf(approximateThreshold));
}
+ if (targetHitsMaxAdjustmentFactor != null) {
+ rankProperties.put("vespa.matching.nns.target_hits_max_adjustment_factor", String.valueOf(targetHitsMaxAdjustmentFactor));
+ }
}
@Override
@@ -119,12 +129,14 @@ public class Matching implements Cloneable {
Objects.equals(numSearchPartitions, matching.numSearchPartitions) &&
Objects.equals(minHitsPerThread, matching.minHitsPerThread) &&
Objects.equals(postFilterThreshold, matching.postFilterThreshold) &&
- Objects.equals(approximateThreshold, matching.approximateThreshold);
+ Objects.equals(approximateThreshold, matching.approximateThreshold) &&
+ Objects.equals(targetHitsMaxAdjustmentFactor, matching.targetHitsMaxAdjustmentFactor);
}
@Override
public int hashCode() {
- return Objects.hash(termwiseLimit, numThreadsPerSearch, numSearchPartitions, minHitsPerThread, postFilterThreshold, approximateThreshold);
+ return Objects.hash(termwiseLimit, numThreadsPerSearch, numSearchPartitions, minHitsPerThread,
+ postFilterThreshold, approximateThreshold, targetHitsMaxAdjustmentFactor);
}
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java b/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java
index f288010a633..724325051f9 100644
--- a/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java
+++ b/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java
@@ -95,7 +95,9 @@ public class RankFeatures implements Cloneable {
if (feature == null) return Optional.empty();
if (feature instanceof Tensor) return Optional.of((Tensor)feature);
if (feature instanceof Double) return Optional.of(Tensor.from((Double)feature));
- throw new IllegalArgumentException("Expected '" + name + "' to be a tensor, but it is the string '" + feature + "'");
+ throw new IllegalArgumentException("Expected '" + name + "' to be a tensor, but it is the string '" + feature +
+ "', this usually means that '" + name + "' is not defined in the schema. " +
+ "See https://docs.vespa.ai/en/tensor-user-guide.html#querying-with-tensors");
}
/**
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 62b56e6e8ff..4956698cc2f 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
@@ -7,7 +7,6 @@ import com.yahoo.search.dispatch.LoadBalancer.GroupStatus;
import com.yahoo.search.dispatch.searchcluster.Group;
import com.yahoo.search.dispatch.searchcluster.Node;
import org.junit.jupiter.api.Test;
-import org.opentest4j.AssertionFailedError;
import java.time.Duration;
import java.time.Instant;
@@ -34,7 +33,7 @@ public class LoadBalancerTest {
Optional<Group> grp = lb.takeGroup(null);
Group group = grp.orElseThrow(() -> {
- throw new AssertionFailedError("Expected a SearchCluster.Group");
+ throw new IllegalStateException("Expected a SearchCluster.Group");
});
assertEquals(1, group.nodes().size());
}
@@ -47,7 +46,7 @@ public class LoadBalancerTest {
Optional<Group> grp = lb.takeGroup(null);
Group group = grp.orElseThrow(() -> {
- throw new AssertionFailedError("Expected a SearchCluster.Group");
+ throw new IllegalStateException("Expected a SearchCluster.Group");
});
assertEquals(1, group.nodes().size());
}
diff --git a/container-search/src/test/java/com/yahoo/search/grouping/vespa/RequestBuilderTestCase.java b/container-search/src/test/java/com/yahoo/search/grouping/vespa/RequestBuilderTestCase.java
index f8e67a10076..6d02721c15e 100644
--- a/container-search/src/test/java/com/yahoo/search/grouping/vespa/RequestBuilderTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/grouping/vespa/RequestBuilderTestCase.java
@@ -25,10 +25,8 @@ import com.yahoo.searchlib.expression.StrCatFunctionNode;
import com.yahoo.searchlib.expression.StringResultNode;
import com.yahoo.searchlib.expression.TimeStampFunctionNode;
import com.yahoo.searchlib.expression.ToStringFunctionNode;
-import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
-import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -468,29 +466,29 @@ public class RequestBuilderTestCase {
String expectedA = "[{ Attribute, result = [Count] }]";
assertLayout("all(group(a) each(output(count())))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all()))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all(group(b))))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all(group(b) each())))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all(group(b) each())))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all(group(b) each())) as(foo)" +
" each())",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all(group(b) each())) as(foo)" +
" each(group(b)))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
assertLayout("all(group(a) each(output(count()) all(group(b) each())) as(foo)" +
" each(group(b) each()))",
- Arrays.asList(expectedA).toString());
+ List.of(expectedA).toString());
String expectedB = "[{ Attribute }, { Attribute, result = [Count] }]";
assertLayout("all(group(a) each(output(count()) all(group(b) each())) as(foo)" +
" each(group(b) each(output(count()))))",
- Arrays.asList(expectedB, expectedA).toString());
+ List.of(expectedB, expectedA).toString());
}
@Test
@@ -650,8 +648,8 @@ public class RequestBuilderTestCase {
@Test
void requireThatTimeZoneIsAppliedToTimeFunctions() {
- for (String timePart : Arrays.asList("dayofmonth", "dayofweek", "dayofyear", "hourofday",
- "minuteofhour", "monthofyear", "secondofminute", "year"))
+ for (String timePart : List.of("dayofmonth", "dayofweek", "dayofyear", "hourofday",
+ "minuteofhour", "monthofyear", "secondofminute", "year"))
{
String request = "all(output(avg(time." + timePart + "(foo))))";
assertTimeZone(request, "GMT-2", -7200L);
@@ -686,7 +684,7 @@ public class RequestBuilderTestCase {
test.expectedOutput = Boolean.toString(true);
test.request = "all(output(avg(now() - foo)))";
test.outputWriter = new OutputWriter() {
- long before = System.currentTimeMillis();
+ final long before = System.currentTimeMillis();
@Override
public String write(List<Grouping> groupingList, GroupingTransform transform) {
@@ -836,7 +834,7 @@ public class RequestBuilderTestCase {
builder.build();
fail();
} catch (IllegalInputException e) {
- Assertions.assertThat(e.getMessage()).contains(errorSubstring);
+ assertTrue(e.getMessage().contains(errorSubstring));
}
}
@@ -924,7 +922,7 @@ public class RequestBuilderTestCase {
RequestBuilder builder = new RequestBuilder(0);
builder.setRootOperation(GroupingOperation.fromString(test.request));
builder.setTimeZone(TimeZone.getTimeZone(test.timeZone));
- builder.addContinuations(Arrays.asList(test.continuation));
+ builder.addContinuations(test.continuation != null ? List.of(test.continuation) : List.of());
try {
builder.build();
if (test.expectedException != null) {
diff --git a/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java
index 83022ccf3ff..7b8015044c6 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/handler/JSONSearchHandlerTestCase.java
@@ -16,7 +16,6 @@ import com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.SlimeUtils;
import com.yahoo.test.json.JsonTestHelper;
-import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
@@ -149,7 +148,7 @@ public class JSONSearchHandlerTestCase {
configurer.reloadConfig();
SearchHandler newSearchHandler = fetchSearchHandler(configurer);
- assertTrue(searchHandler != newSearchHandler, "Do I have a new instance of the search handler?");
+ assertNotSame(searchHandler, newSearchHandler, "Do I have a new instance of the search handler?");
try (RequestHandlerTestDriver newDriver = new RequestHandlerTestDriver(newSearchHandler)) {
ObjectNode json = jsonMapper.createObjectNode();
json.put("yql", "selectz * from foo where bar > 1453501295");
@@ -193,13 +192,15 @@ public class JSONSearchHandlerTestCase {
ObjectNode json = jsonMapper.createObjectNode();
json.put("format", "xml");
- assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
- "<result total-hit-count=\"0\">\n" +
- " <hit relevancy=\"1.0\">\n" +
- " <field name=\"relevancy\">1.0</field>\n" +
- " <field name=\"uri\">testHit</field>\n" +
- " </hit>\n" +
- "</result>\n", driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE).readAll());
+ assertEquals("""
+ <?xml version="1.0" encoding="utf-8" ?>
+ <result total-hit-count="0">
+ <hit relevancy="1.0">
+ <field name="relevancy">1.0</field>
+ <field name="uri">testHit</field>
+ </hit>
+ </result>
+ """, driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE).readAll());
}
@Test
@@ -253,13 +254,15 @@ public class JSONSearchHandlerTestCase {
}
private static final String xmlResult =
- "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
- "<result total-hit-count=\"0\">\n" +
- " <hit relevancy=\"1.0\">\n" +
- " <field name=\"relevancy\">1.0</field>\n" +
- " <field name=\"uri\">testHit</field>\n" +
- " </hit>\n" +
- "</result>\n";
+ """
+ <?xml version="1.0" encoding="utf-8" ?>
+ <result total-hit-count="0">
+ <hit relevancy="1.0">
+ <field name="relevancy">1.0</field>
+ <field name="uri">testHit</field>
+ </hit>
+ </result>
+ """;
private void assertXmlResult(JsonNode json, RequestHandlerTestDriver driver) {
assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString(), JSON_CONTENT_TYPE), xmlResult);
@@ -276,19 +279,6 @@ public class JSONSearchHandlerTestCase {
}
- private static final String pageResult =
- "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
- "<page version=\"1.0\">\n" +
- "\n" +
- " <content>\n" +
- " <hit relevance=\"1.0\">\n" +
- " <id>testHit</id>\n" +
- " <uri>testHit</uri>\n" +
- " </hit>\n" +
- " </content>\n" +
- "\n" +
- "</page>\n";
-
private void assertOkResult(RequestHandlerTestDriver.MockResponseHandler response, String expected) {
assertEquals(expected, response.readAll());
assertEquals(200, response.getStatus());
@@ -302,11 +292,26 @@ public class JSONSearchHandlerTestCase {
configurer.reloadConfig();
SearchHandler newSearchHandler = fetchSearchHandler(configurer);
- assertTrue(searchHandler != newSearchHandler, "Do I have a new instance of the search handler?");
+ assertNotSame(searchHandler, newSearchHandler, "Do I have a new instance of the search handler?");
return new RequestHandlerTestDriver(newSearchHandler);
}
@Test
+ void testInputParameters() throws IOException {
+ String json = """
+ {
+ "input": {
+ "query(q_category)": { "Tablet Keyboard Cases": 42.5 },
+ "query(q_vector)": [ 1, 2.5, 3 ]
+ }
+ }
+ """;
+ Map<String, String> map = new Json2SingleLevelMap(new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8))).parse();
+ assertEquals("{ \"Tablet Keyboard Cases\": 42.5 }", map.get("input.query(q_category)"));
+ assertEquals("[ 1, 2.5, 3 ]", map.get("input.query(q_vector)"));
+ }
+
+ @Test
void testSelectParameters() throws IOException {
ObjectNode json = jsonMapper.createObjectNode();
@@ -353,23 +358,25 @@ public class JSONSearchHandlerTestCase {
@Test
void testJsonWithWhereAndGroupingUnderSelect() {
- String query = "{\n" +
- " \"select\": {\n" +
- " \"where\": {\n" +
- " \"contains\": [\n" +
- " \"field\",\n" +
- " \"term\"\n" +
- " ]\n" +
- " },\n" +
- " \"grouping\":[\n" +
- " {\n" +
- " \"all\": {\n" +
- " \"output\": \"count()\"\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- " }\n" +
- "}\n";
+ String query = """
+ {
+ "select": {
+ "where": {
+ "contains": [
+ "field",
+ "term"
+ ]
+ },
+ "grouping":[
+ {
+ "all": {
+ "output": "count()"
+ }
+ }
+ ]
+ }
+ }
+ """;
String result = driver.sendRequest(uri + "searchChain=echoingQuery", com.yahoo.jdisc.http.HttpRequest.Method.POST, query, JSON_CONTENT_TYPE).readAll();
String expected = "{\"root\":{\"id\":\"toplevel\",\"relevance\":1.0,\"fields\":{\"totalCount\":0},\"children\":[{\"id\":\"Query\",\"relevance\":1.0,\"fields\":{\"query\":\"select * from sources * where field contains \\\"term\\\" | all(output(count()))\"}}]}}";
@@ -378,21 +385,23 @@ public class JSONSearchHandlerTestCase {
@Test
void testJsonWithWhereAndGroupingSeparate() {
- String query = "{\n" +
- " \"select.where\": {\n" +
- " \"contains\": [\n" +
- " \"field\",\n" +
- " \"term\"\n" +
- " ]\n" +
- " },\n" +
- " \"select.grouping\":[\n" +
- " {\n" +
- " \"all\": {\n" +
- " \"output\": \"count()\"\n" +
- " }\n" +
- " }\n" +
- " ]\n" +
- "}\n";
+ String query = """
+ {
+ "select.where": {
+ "contains": [
+ "field",
+ "term"
+ ]
+ },
+ "select.grouping":[
+ {
+ "all": {
+ "output": "count()"
+ }
+ }
+ ]
+ }
+ """;
String result = driver.sendRequest(uri + "searchChain=echoingQuery", com.yahoo.jdisc.http.HttpRequest.Method.POST, query, JSON_CONTENT_TYPE).readAll();
String expected = "{\"root\":{\"id\":\"toplevel\",\"relevance\":1.0,\"fields\":{\"totalCount\":0},\"children\":[{\"id\":\"Query\",\"relevance\":1.0,\"fields\":{\"query\":\"select * from sources * where field contains \\\"term\\\" | all(output(count()))\"}}]}}";
@@ -524,7 +533,7 @@ public class JSONSearchHandlerTestCase {
// Get mapping
Map<String, String> propertyMap = request.propertyMap();
- Assertions.assertThat(propertyMap).isEqualTo(map);
+ assertEquals(propertyMap, map);
}
@Test
diff --git a/container-search/src/test/java/com/yahoo/search/logging/LocalDiskLoggerTest.java b/container-search/src/test/java/com/yahoo/search/logging/LocalDiskLoggerTest.java
index 6ed1154e58a..e94068fa988 100644
--- a/container-search/src/test/java/com/yahoo/search/logging/LocalDiskLoggerTest.java
+++ b/container-search/src/test/java/com/yahoo/search/logging/LocalDiskLoggerTest.java
@@ -32,21 +32,11 @@ public class LocalDiskLoggerTest {
.blob("my entry blob content".getBytes())
.track("my-track")
.send();
- waitForFile(logFile);
+ logger.deconstruct();
String test = IOUtils.readAll(new FileReader(logFile));
assertTrue(test.contains(Base64.getEncoder().encodeToString("my entry blob content".getBytes())));
assertTrue(test.contains("my-track"));
}
- private void waitForFile(File file) throws InterruptedException {
- int waitFor = 10;
- while ( ! file.exists() && --waitFor > 0) {
- Thread.sleep(10);
- }
- if ( ! file.exists()) {
- fail("Local disk logger file was not created");
- }
- }
-
}
diff --git a/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java b/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
index e3a1eb18a33..37d0e9e1072 100644
--- a/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
@@ -20,6 +20,7 @@ public class MatchingTestCase {
assertNull(query.getRanking().getMatching().getMinHitsPerThread());
assertNull(query.getRanking().getMatching().getPostFilterThreshold());
assertNull(query.getRanking().getMatching().getApproximateThreshold());
+ assertNull(query.getRanking().getMatching().getTargetHitsMaxAdjustmentFactor());
}
@Test
@@ -30,13 +31,15 @@ public class MatchingTestCase {
"&ranking.matching.numSearchPartitions=13" +
"&ranking.matching.minHitsPerThread=3" +
"&ranking.matching.postFilterThreshold=0.8" +
- "&ranking.matching.approximateThreshold=0.3");
+ "&ranking.matching.approximateThreshold=0.3" +
+ "&ranking.matching.targetHitsMaxAdjustmentFactor=2.5");
assertEquals(Double.valueOf(0.7), query.getRanking().getMatching().getTermwiseLimit());
assertEquals(Integer.valueOf(17), query.getRanking().getMatching().getNumThreadsPerSearch());
assertEquals(Integer.valueOf(13), query.getRanking().getMatching().getNumSearchPartitions());
assertEquals(Integer.valueOf(3), query.getRanking().getMatching().getMinHitsPerThread());
assertEquals(Double.valueOf(0.8), query.getRanking().getMatching().getPostFilterThreshold());
assertEquals(Double.valueOf(0.3), query.getRanking().getMatching().getApproximateThreshold());
+ assertEquals(Double.valueOf(2.5), query.getRanking().getMatching().getTargetHitsMaxAdjustmentFactor());
query.prepare();
assertEquals("0.7", query.getRanking().getProperties().get("vespa.matching.termwise_limit").get(0));
@@ -45,6 +48,7 @@ public class MatchingTestCase {
assertEquals("3", query.getRanking().getProperties().get("vespa.matching.minhitsperthread").get(0));
assertEquals("0.8", query.getRanking().getProperties().get("vespa.matching.global_filter.upper_limit").get(0));
assertEquals("0.3", query.getRanking().getProperties().get("vespa.matching.global_filter.lower_limit").get(0));
+ assertEquals("2.5", query.getRanking().getProperties().get("vespa.matching.nns.target_hits_max_adjustment_factor").get(0));
}
@Test
diff --git a/container-search/src/test/java/com/yahoo/search/query/SortingTestCase.java b/container-search/src/test/java/com/yahoo/search/query/SortingTestCase.java
index 8422196638a..b325bde05d9 100644
--- a/container-search/src/test/java/com/yahoo/search/query/SortingTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/query/SortingTestCase.java
@@ -81,8 +81,8 @@ public class SortingTestCase {
private void requireThatChineseHasCorrectRules(Collator col) {
final int reorderCodes [] = {UScript.HAN};
- assertEquals("14.0.0.0", col.getUCAVersion().toString());
- assertEquals("153.112.40.0", col.getVersion().toString());
+ assertEquals("15.0.0.0", col.getUCAVersion().toString());
+ assertEquals("153.120.43.8", col.getVersion().toString());
assertEquals(Arrays.toString(reorderCodes), Arrays.toString(col.getReorderCodes()));
assertNotEquals("", ((RuleBasedCollator) col).getRules());