diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain |
Publish
Diffstat (limited to 'config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain')
7 files changed, 570 insertions, 0 deletions
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/Federation2Test.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/Federation2Test.java new file mode 100644 index 00000000000..bc7197b5408 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/Federation2Test.java @@ -0,0 +1,69 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.test.SimpletypesConfig; +import org.junit.Test; +import org.w3c.dom.Element; + +import static org.junit.Assert.assertEquals; + +/** + * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a> + */ +public class Federation2Test extends SearchChainsTestBase { + @Override + Element servicesXml() { + return parse( + " <search>\n" + + "\n" + + " <chain id=\"chain1\">\n" + + " <searcher id=\"com.yahoo.example.TestSearcher\">\n" + + " <config name=\"test.simpletypes\">\n" + + " <stringval>testSearcher</stringval>\n" + + " </config>\n" + + " </searcher>\n" + + " </chain>\n" + + "\n" + + " <provider id=\"test-source-inherits\">\n" + + " <searcher id=\"com.yahoo.example.AddHitSearcher\" />\n" + + " <source id=\"test-inherits\" />\n" + + " </provider>\n" + + "\n" + + " <!-- Two providers with a common source -->\n" + + " <provider id=\"providerA\">\n" + + " <source id=\"commonSource\">\n" + + " <searcher id=\"com.yahoo.example.AddHitSearcher\">\n" + + " <config name=\"test.simpletypes\">\n" + + " <stringval>providerA</stringval>\n" + + " </config>\n" + + " </searcher>\n" + + " </source>\n" + + " </provider>\n" + + "\n" + + " <provider id=\"providerB\">\n" + + " <source idref=\"commonSource\">\n" + + " <searcher id=\"com.yahoo.example.AddHitSearcher\">\n" + + " <config name=\"test.simpletypes\">\n" + + " <stringval>providerB</stringval>\n" + + " </config>\n" + + " </searcher>\n" + + " </source>\n" + + " </provider>\n" + + "\n" + + " </search>\n"); + } + + + @Test + public void testProviderConfigs() { + //SimpletypesConfig testConfig = root.getConfig(SimpletypesConfig.class, "test/searchchains/chain/chain1/component/com.yahoo.example.TestSearcher"); + //assertEquals("testSearcher",testConfig.stringval()); + + SimpletypesConfig configA = root.getConfig(SimpletypesConfig.class, "searchchains/chain/providerA/source/commonSource/component/com.yahoo.example.AddHitSearcher"); + assertEquals("providerA",configA.stringval()); + + SimpletypesConfig configB = root.getConfig(SimpletypesConfig.class, "searchchains/chain/providerB/source/commonSource/component/com.yahoo.example.AddHitSearcher"); + assertEquals("providerB",configB.stringval()); + } + +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationTest.java new file mode 100644 index 00000000000..d25af7302de --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationTest.java @@ -0,0 +1,113 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.search.federation.FederationConfig; +import org.junit.Test; +import org.w3c.dom.Element; + +import java.util.List; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.*; + +/** + * Test generated config for federation. + * @author tonytv + */ +public class FederationTest extends SearchChainsTestBase { + @Override + Element servicesXml() { + return parse( + "<searchchains>", + " <searchchain id='federation1'>", + " <federation id='federationSearcher1'>", + " <source id='source1'>", + " <federationoptions optional='false' />", + " </source>", + " </federation>", + " </searchchain>", + + + " <provider id='provider1'>", + " <federationoptions optional='true' timeout='2.3 s' />", + + " <source id='source1'>", + " <federationoptions timeout='12 ms' />", + " </source>", + " <source id='source2' />", + " <source id='sourceCommon' />", + " </provider>", + + " <provider id='provider2' type='local' cluster='cluster1' />", + + " <provider id='provider3'>", + " <source idref='sourceCommon' />", + " </provider>", + + " <searchchain id='parentChain1' />", + "</searchchains>"); + } + + + @Test + public void validateNativeDefaultTargets() { + FederationConfig.Builder fb = new FederationConfig.Builder(); + root.getConfig(fb, "searchchains/chain/native/component/federation"); + FederationConfig config = new FederationConfig(fb); + + for (FederationConfig.Target target : config.target()) { + String failMessage = "Failed for target " + target.id(); + + if (target.id().startsWith("source")) { + assertTrue(failMessage, target.useByDefault()); + } else { + assertFalse(failMessage, target.useByDefault()); + } + } + + assertThat(config.target().size(), is(5)); + assertUseByDefault(config, "source1", false); + assertUseByDefault(config, "source2", false); + + assertUseByDefault(config, "provider2", true); + assertUseByDefault(config, "cluster2", true); + + assertUseByDefault(config, "sourceCommon", "provider1", false); + assertUseByDefault(config, "sourceCommon", "provider3", false); + + } + + private void assertUseByDefault(FederationConfig config, String sourceName, String providerName, + boolean expectedValue) { + + FederationConfig.Target target = getTarget(config.target(), sourceName); + FederationConfig.Target.SearchChain searchChain = getProvider(target, providerName); + assertThat(searchChain.useByDefault(), is(expectedValue)); + } + + private FederationConfig.Target.SearchChain getProvider(FederationConfig.Target target, String providerName) { + for (FederationConfig.Target.SearchChain searchChain : target.searchChain()) { + if (searchChain.providerId().equals(providerName)) + return searchChain; + } + fail("No provider " + providerName); + return null; + } + + private void assertUseByDefault(FederationConfig config, String chainName, boolean expectedValue) { + FederationConfig.Target target = getTarget(config.target(), chainName); + assertThat(target.searchChain().size(), is(1)); + assertThat(target.searchChain().get(0).useByDefault(), is(expectedValue)); + } + + private FederationConfig.Target getTarget(List<FederationConfig.Target> targets, String chainId) { + for (FederationConfig.Target target : targets) { + if (target.id().equals(chainId)) + return target; + } + fail("No target with id " + chainId); + return null; + } + + +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/MockSearchClusters.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/MockSearchClusters.java new file mode 100644 index 00000000000..daef1b845f7 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/MockSearchClusters.java @@ -0,0 +1,61 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.vespa.config.search.AttributesConfig; +import com.yahoo.vespa.config.search.RankProfilesConfig; +import com.yahoo.config.model.ConfigModelRepo; +import com.yahoo.config.model.producer.AbstractConfigProducerRoot; +import com.yahoo.prelude.fastsearch.DocumentdbInfoConfig; +import com.yahoo.search.config.IndexInfoConfig; +import com.yahoo.vespa.configdefinition.IlscriptsConfig; +import com.yahoo.vespa.model.search.AbstractSearchCluster; +import java.util.HashMap; +import java.util.Map; + +public class MockSearchClusters { + private static class MockSearchCluster extends AbstractSearchCluster { + public MockSearchCluster(AbstractConfigProducerRoot root, String clusterName, int clusterIndex, boolean isStreaming) { + super(root, clusterName, clusterIndex); + streaming = isStreaming; + } + private final boolean streaming; + + @Override + public int getRowBits() { + return 0; + } + + @Override + protected AbstractSearchCluster.IndexingMode getIndexingMode() { return streaming ? AbstractSearchCluster.IndexingMode.STREAMING : AbstractSearchCluster.IndexingMode.REALTIME; } + @Override + protected void assureSdConsistent() {} + + @Override + public void getConfig(DocumentdbInfoConfig.Builder builder) { + } + @Override + public void getConfig(IndexInfoConfig.Builder builder) { + } + @Override + public void getConfig(IlscriptsConfig.Builder builder) { + } + @Override + public void getConfig(AttributesConfig.Builder builder) { + } + @Override + public void getConfig(RankProfilesConfig.Builder builder) { + } + } + + public static AbstractSearchCluster mockSearchCluster(AbstractConfigProducerRoot root, String clusterName, int clusterIndex, boolean isStreaming) { + + return new MockSearchCluster(root, clusterName, clusterIndex, isStreaming); + } + + public static Map<String, AbstractSearchCluster> twoMockClusterSpecsByName(AbstractConfigProducerRoot root) { + Map<String, AbstractSearchCluster> result = new HashMap<>(); + result.put("cluster1", mockSearchCluster(root, "cluster1", 1, false)); + result.put("cluster2", mockSearchCluster(root, "cluster2", 2, true)); + return result; + } +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTest.java new file mode 100644 index 00000000000..09c1043734e --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTest.java @@ -0,0 +1,135 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.component.ComponentId; +import com.yahoo.container.core.ChainsConfig; +import com.yahoo.prelude.cluster.ClusterSearcher; +import com.yahoo.search.config.ClusterConfig; +import com.yahoo.search.federation.ProviderConfig; +import com.yahoo.vespa.defaults.Defaults; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Element; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + + +/** + * Test of search chains config + * <p>TODO: examine the actual values in the configs.</p> + * @author tonytv + */ +public class SearchChainsTest extends SearchChainsTestBase { + private ChainsConfig chainsConfig; + private ProviderConfig providerConfig; + private ClusterConfig clusterConfig; + + @Before + public void subscribe() { + ChainsConfig.Builder chainsBuilder = new ChainsConfig.Builder(); + chainsBuilder = (ChainsConfig.Builder)root.getConfig(chainsBuilder, "searchchains"); + chainsConfig = new ChainsConfig(chainsBuilder); + + ProviderConfig.Builder providerBuilder = new ProviderConfig.Builder(); + providerBuilder = (ProviderConfig.Builder)root.getConfig(providerBuilder, "searchchains/chain/provider:1/component/com.yahoo.search.federation.vespa.VespaSearcher"); + providerConfig = new ProviderConfig(providerBuilder); + + ClusterConfig.Builder clusterBuilder = new ClusterConfig.Builder(); + clusterBuilder = (ClusterConfig.Builder)root.getConfig(clusterBuilder, "searchchains/chain/cluster2/component/" + ClusterSearcher.class.getName()); + clusterConfig = new ClusterConfig(clusterBuilder); + } + + + @Override + Element servicesXml() { + return parse( + "<searchchains>", + " <searcher id='searcher:1' classId='classId1' />", + + " <provider id='provider:1' type='vespa' inherits='parentChain1 parentChain2' excludes='ExcludedSearcher1 ExcludedSearcher2'", + " cacheweight='2.3'>", + " <federationoptions optional='true' timeout='2.3 s' />", + " <nodes>", + " <node host='sourcehost1' port='12'/>", + " <node host='sourcehost2' port='34'/>", + " </nodes>", + + " <source id='source:1' inherits='parentChain3 parentChain4' excludes='ExcludedSearcher3 ExcludedSearcher4'>", + " <federationoptions timeout='12 ms' />", + " </source>", + " <source id='source:2' />", + " </provider>", + + " <provider id='provider:2' type='local' cluster='cluster1' />", + " <provider id='provider:3' />", + + " <provider id='vespa-provider' type='vespa' >", + " <nodes>", + " <node host='localhost' port='" + Defaults.getDefaults().vespaWebServicePort() + "' />", + " </nodes>", + " <config name='search.federation.provider'>", + " <queryType>PROGRAMMATIC</queryType>", + " </config>", + " </provider>", + + " <searchchain id='default:99'>", + " <federation id='federation:98' provides='provide_federation' before='p1 p2' after='s1 s2'>", + " <source id='source:1'>", + " <federationoptions optional='false' />", + " </source>", + " </federation>", + " </searchchain>", + + " <searchchain id='parentChain1' />", + " <searchchain id='parentChain2' />", + " <searchchain id='parentChain3' />", + " <searchchain id='parentChain4' />", + "</searchchains>"); + } + + @Test + public void require_vespa_searcher_inside_vespa_provider() { + SearchChains searchchains = getSearchChains(); + SearchChain vespaProvider = searchchains.allChains().getComponent("vespa-provider"); + Searcher<?> vespaSearcher = vespaProvider.getInnerComponents().iterator().next(); + assertThat(vespaSearcher, instanceOf(HttpProviderSearcher.class)); + } + + private SearchChains getSearchChains() { + return (SearchChains) root.getChildren().get("searchchains"); + } + + @Test + public void require_user_config_for_vespa_searcher_works() { + assertEquals(root.getConfig(ProviderConfig.class, "searchchains/chain/vespa-provider/component/com.yahoo.search.federation.vespa.VespaSearcher"). + queryType(), ProviderConfig.QueryType.PROGRAMMATIC); + } + + @Test + public void require_that_source_chain_spec_id_is_namespaced_in_provider_id() { + Source source = (Source) getSearchChains().allChains().getComponent("source:1@provider:1"); + assertThat(source.getChainSpecification().componentId.getNamespace(), is(ComponentId.fromString("provider:1"))); + } + + @Test + public void validateHttpProviderConfig() { + assertNotNull(providerConfig); + } + + @Test + public void validateLocalProviderConfig() { + assertEquals(2, clusterConfig.clusterId()); + assertEquals("cluster2", clusterConfig.clusterName()); + } + + public static boolean verifyChainExists(List<ChainsConfig.Chains> chains, String componentId) { + for (ChainsConfig.Chains c : chains) { + if (c.id().equals(componentId)) return true; + } + return false; + } +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTest2.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTest2.java new file mode 100644 index 00000000000..5e93233f443 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTest2.java @@ -0,0 +1,78 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.config.model.builder.xml.test.DomBuilderTest; +import com.yahoo.config.model.test.MockRoot; +import com.yahoo.vespa.model.builder.xml.dom.chains.search.DomSearchChainsBuilder; +import com.yahoo.vespa.model.container.xml.ContainerModelBuilderTest; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Element; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.hamcrest.Matchers.containsString; + +/** + * @author gjoranv + * @since 5.1.11 + */ +public class SearchChainsTest2 { + + private MockRoot root; + + @Before + public void prepareTest() throws Exception { + root = new MockRoot("root"); + } + + @Test + public void fail_upon_unresolved_inheritance() { + final Element searchElem = DomBuilderTest.parse( + "<search>", + " <chain id='default' inherits='nonexistent' />", + "</search>"); + try { + SearchChains chains = new DomSearchChainsBuilder().build(new MockRoot(), searchElem); + chains.validate(); + fail("Expected exception when inheriting a nonexistent search chain."); + } catch (Exception e) { + assertThat(e.getMessage(), containsString("Missing chain 'nonexistent'")); + } + } + + @Test + public void fail_upon_two_user_declared_chains_with_same_name() { + final Element clusterElem = DomBuilderTest.parse( + "<jdisc id='cluster1' version='1.0'>", + ContainerModelBuilderTest.nodesXml, + " <search>", + " <chain id='same' />", + " <chain id='same' />", + " </search>", + "</jdisc>"); + try { + ContainerModelBuilderTest.createModel(root, clusterElem); + fail("Expected exception when declaring chains with duplicate id."); + } catch (Exception e) { + assertThat(e.getMessage(), containsString("Two entities have the same component id 'same'")); + } + } + + @Test + public void fail_upon_user_declared_chain_with_same_id_as_builtin_chain() throws Exception { + final Element clusterElem = DomBuilderTest.parse( + "<jdisc id='cluster1' version='1.0'>", + ContainerModelBuilderTest.nodesXml, + " <search>", + " <chain id='vespa' />", + " </search>", + "</jdisc>"); + try { + ContainerModelBuilderTest.createModel(root, clusterElem); + fail("Expected exception when taking the id from a builtin chain."); + } catch (Exception e) { + assertThat(e.getMessage(), containsString("Two entities have the same component id 'vespa'")); + } + } +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTestBase.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTestBase.java new file mode 100644 index 00000000000..a942e428be0 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SearchChainsTestBase.java @@ -0,0 +1,25 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.binaryprefix.BinaryPrefix; +import com.yahoo.binaryprefix.BinaryScaledAmount; +import com.yahoo.config.model.builder.xml.test.DomBuilderTest; +import com.yahoo.vespa.model.builder.xml.dom.chains.search.DomSearchChainsBuilder; +import org.junit.Before; +import org.w3c.dom.Element; + +/** Creates SearchChains model from xml input. + * @author tonytv + */ +public abstract class SearchChainsTestBase extends DomBuilderTest { + + @Before + public void setupSearchChains() { + SearchChains searchChains = new DomSearchChainsBuilder().build(root, servicesXml()); + searchChains.initialize(MockSearchClusters.twoMockClusterSpecsByName(root), + new BinaryScaledAmount(100, BinaryPrefix.mega)); + root.freezeModelTopology(); + } + + abstract Element servicesXml(); +} diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SourceGroupTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SourceGroupTest.java new file mode 100644 index 00000000000..bf50a40fd2d --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SourceGroupTest.java @@ -0,0 +1,89 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.search.searchchain; + +import com.yahoo.component.ComponentId; +import com.yahoo.component.ComponentSpecification; +import com.yahoo.component.chain.Phase; +import com.yahoo.component.chain.model.ChainSpecification; +import com.yahoo.config.model.test.MockRoot; +import com.yahoo.search.searchchain.model.federation.FederationOptions; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collections; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.hamcrest.Matchers.containsString; + +/** + * @author tonytv + */ +public class SourceGroupTest { + private MockRoot root; + private SearchChains searchChains; + + @Before + public void setUp() throws Exception { + root = new MockRoot(); + searchChains = new SearchChains(root, "searchchains"); + } + + @Test + public void report_error_when_no_leader() { + try { + Provider provider = createProvider("p1"); + Source source = createSource("s1", Source.GroupOption.participant); + provider.addSource(source); + + searchChains.add(provider); + root.freezeModelTopology(); + + searchChains.validate(); + } catch (Exception e) { + assertThat(e.getMessage(), containsString("Missing leader for the source s1.")); + return; + } + fail("Expected exception"); + } + + private Provider createProvider(String p1) { + return new Provider(createSearchChainSpecification(p1), new FederationOptions()); + } + + private ChainSpecification createSearchChainSpecification(String id) { + return new ChainSpecification(ComponentId.fromString(id), + new ChainSpecification.Inheritance(null, null), + Collections.<Phase>emptyList(), + Collections.<ComponentSpecification>emptySet()); + } + + private Source createSource(String sourceId, Source.GroupOption groupOption) { + return new Source( + createSearchChainSpecification(sourceId), + new FederationOptions(), + groupOption); + } + + @Test + public void require_that_source_and_provider_id_is_not_allowed_to_be_equal() { + Provider provider = createProvider("sameId"); + Provider provider2 = createProvider("ignoredId"); + + Source source = createSource("sameId", Source.GroupOption.leader); + + provider2.addSource(source); + + searchChains.add(provider); + searchChains.add(provider2); + root.freezeModelTopology(); + + try { + searchChains.validate(); + fail("Expected exception"); + } catch (Exception e) { + assertThat(e.getMessage(), containsString("Same id used for a source")); + assertThat(e.getMessage(), containsString("'sameId'")); + } + } +} |