// 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().getSearchCluster(); 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); } }