// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.content.cluster;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.model.test.TestDriver;
import com.yahoo.vespa.config.search.DispatchConfig;
import com.yahoo.vespa.config.search.DispatchNodesConfig;
import com.yahoo.vespa.config.search.core.ProtonConfig;
import com.yahoo.vespa.model.content.Content;
import com.yahoo.vespa.model.search.SearchCluster;
import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils;
import org.junit.jupiter.api.Test;
import java.util.List;
import static com.yahoo.config.model.test.TestUtil.joinLines;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author Simon Thoresen Hult
*/
public class ClusterTest {
private static final double DELTA = 1E-12;
@Test
void requireThatContentSearchIsApplied() {
ContentCluster cluster = newContentCluster(joinLines("",
" 1.1",
" 2.3",
""));
SearchCluster searchCluster = cluster.getSearch().getIndexed();
assertNotNull(searchCluster);
assertEquals(1.1, searchCluster.getQueryTimeout(), DELTA);
assertEquals(2.3, searchCluster.getVisibilityDelay(), DELTA);
ProtonConfig proton = getProtonConfig(cluster);
assertEquals(searchCluster.getVisibilityDelay(), proton.documentdb(0).visibilitydelay(), DELTA);
}
@Test
void requireThatVisibilityDelayIsZeroForGlobalDocumentType() {
ContentCluster cluster = newContentCluster(joinLines("",
" 2.3",
""), true);
ProtonConfig proton = getProtonConfig(cluster);
assertEquals(0.0, proton.documentdb(0).visibilitydelay(), DELTA);
}
@Test
void requireThatSearchCoverageIsApplied() {
ContentCluster cluster = newContentCluster(joinLines("",
" ",
" 0.11",
" 0.23",
" 0.58",
" ",
""));
DispatchConfig.Builder builder = new DispatchConfig.Builder();
cluster.getSearch().getConfig(builder);
DispatchConfig config = new DispatchConfig(builder);
assertEquals(11.0, config.minSearchCoverage(), DELTA);
assertEquals(0.23, config.minWaitAfterCoverageFactor(), DELTA);
assertEquals(0.58, config.maxWaitAfterCoverageFactor(), DELTA);
assertEquals(3, config.redundancy());
assertEquals(DispatchConfig.DistributionPolicy.ADAPTIVE, config.distributionPolicy());
}
@Test
void requireThatDispatchTuningIsApplied() {
ContentCluster cluster = newContentCluster(joinLines("", ""),
"",
joinLines(
"77",
"best-of-random-2",
"93",
"0.777"),
false);
DispatchConfig.Builder builder = new DispatchConfig.Builder();
cluster.getSearch().getConfig(builder);
DispatchConfig config = new DispatchConfig(builder);
assertEquals(3, config.redundancy());
assertEquals(93.0, config.minActivedocsPercentage(), DELTA);
assertEquals(DispatchConfig.DistributionPolicy.BEST_OF_RANDOM_2, config.distributionPolicy());
assertEquals(77, config.maxHitsPerNode());
assertEquals(0.777, config.topKProbability(), DELTA);
}
@Test
void requireThatDefaultDispatchConfigIsCorrect() {
ContentCluster cluster = newContentCluster(joinLines("", ""),
joinLines("", ""));
DispatchConfig.Builder builder = new DispatchConfig.Builder();
DispatchNodesConfig.Builder nodesBuilder = new DispatchNodesConfig.Builder();
cluster.getSearch().getConfig(builder);
cluster.getSearch().getConfig(nodesBuilder);
DispatchConfig config = builder.build();
DispatchNodesConfig nodesConfig = nodesBuilder.build();
assertEquals(3, config.redundancy());
assertEquals(DispatchConfig.DistributionPolicy.ADAPTIVE, config.distributionPolicy());
assertEquals(1.0, config.maxWaitAfterCoverageFactor(), DELTA);
assertEquals(0, config.minWaitAfterCoverageFactor(), DELTA);
assertEquals(8, config.numJrtConnectionsPerNode());
assertEquals(8, config.numJrtTransportThreads());
assertEquals(100.0, config.minSearchCoverage(), DELTA);
assertEquals(97.0, config.minActivedocsPercentage(), DELTA);
assertEquals(0.9999, config.topKProbability(), DELTA);
assertEquals(3, nodesConfig.node().size());
assertEquals(0, nodesConfig.node(0).key());
assertEquals(1, nodesConfig.node(1).key());
assertEquals(2, nodesConfig.node(2).key());
assertEquals(19106, nodesConfig.node(0).port());
assertEquals(19118, nodesConfig.node(1).port());
assertEquals(19130, nodesConfig.node(2).port());
assertEquals(0, nodesConfig.node(0).group());
assertEquals(0, nodesConfig.node(1).group());
assertEquals(0, nodesConfig.node(2).group());
assertEquals("localhost", nodesConfig.node(0).host());
assertEquals("localhost", nodesConfig.node(1).host());
assertEquals("localhost", nodesConfig.node(2).host());
}
private static ContentCluster newContentCluster(String contentSearchXml, String searchNodeTuningXml) {
return newContentCluster(contentSearchXml, searchNodeTuningXml, "", false);
}
private static ContentCluster newContentCluster(String contentSearchXml) {
return newContentCluster(contentSearchXml, false);
}
private static ContentCluster newContentCluster(String contentSearchXml, boolean globalDocType) {
return newContentCluster(contentSearchXml, "", "", globalDocType);
}
private static ContentCluster newContentCluster(String contentSearchXml, String searchNodeTuningXml,
String dispatchTuning, boolean globalDocType)
{
ApplicationPackage app = new MockApplicationPackage.Builder()
.withHosts(joinLines(
"",
" my_host",
""))
.withServices(joinLines(
"",
" ",
" ",
" ",
"",
" ",
" ",
"",
" ",
" 3",
" ",
" " + getDocumentXml(globalDocType),
" ",
" ",
" ",
" 2",
searchNodeTuningXml,
" ",
" ",
" ",
" ",
" ",
" ",
" ",
contentSearchXml,
" ",
" ",
dispatchTuning,
" ",
" ",
" ",
""))
.withSchemas(ApplicationPackageUtils.generateSchemas("my_document"))
.build();
List contents = new TestDriver().buildModel(app).getConfigModels(Content.class);
assertEquals(1, contents.size());
return contents.get(0).getCluster();
}
private static String getDocumentXml(boolean globalDocType) {
return "";
}
private static ProtonConfig getProtonConfig(ContentCluster cluster) {
ProtonConfig.Builder builder = new ProtonConfig.Builder();
cluster.getSearch().getConfig(builder);
return new ProtonConfig(builder);
}
}