diff options
author | Bjørn Christian Seime <bjorncs@yahoo-inc.com> | 2017-02-15 11:48:40 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@yahoo-inc.com> | 2017-02-16 10:44:50 +0100 |
commit | 8b1d8d0caa31d0e29ca64decc2ae5996e4473994 (patch) | |
tree | 04642049de96f52041eac76bc199b6ff782c551a /config-model | |
parent | 2ff3a6724f645b224a004530abc59854b05c7ccc (diff) |
Validate that searchable copies matches redundancy
Verify that the number of searchable copies is the same as effective
redundancy. Rewrite GlobalDistributionValidatorTest to not use Mockito.
Add end-to-end test to verify that the GlobalDistributionValidator is wired
into the overall model validation.
Diffstat (limited to 'config-model')
6 files changed, 99 insertions, 16 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/GlobalDistributionValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/content/GlobalDistributionValidator.java index 684c9aeb225..14f79a8fc52 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/GlobalDistributionValidator.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/GlobalDistributionValidator.java @@ -25,6 +25,7 @@ public class GlobalDistributionValidator { Redundancy redundancy) { verifyGlobalDocumentsHaveRequiredRedundancy(globallyDistributedDocuments, redundancy); + verifySearchableCopiesIsSameAsRedundancy(globallyDistributedDocuments, redundancy); verifyReferredDocumentsArePresent(documentDefinitions); verifyReferredDocumentsAreGlobal(documentDefinitions, globallyDistributedDocuments); } @@ -43,6 +44,20 @@ public class GlobalDistributionValidator { } } + private static void verifySearchableCopiesIsSameAsRedundancy(Set<NewDocumentType> globallyDistributedDocuments, + Redundancy redundancy) { + if (!globallyDistributedDocuments.isEmpty() && + redundancy.effectiveReadyCopies() != redundancy.effectiveFinalRedundancy()) { + throw new IllegalArgumentException( + String.format( + "The following document types have the number of searchable copies less than redundancy: %s. " + + "Searchable copies is %d, while redundancy is %d.", + asPrintableString(toDocumentNameStream(globallyDistributedDocuments)), + redundancy.effectiveReadyCopies(), + redundancy.effectiveFinalRedundancy())); + } + } + private static void verifyReferredDocumentsArePresent(Map<String, NewDocumentType> documentDefinitions) { Set<NewDocumentType.Name> unknowDocuments = getReferencedDocuments(documentDefinitions) .filter(name -> !documentDefinitions.containsKey(name.toString())) diff --git a/config-model/src/test/cfg/application/validation/global_distribution_validation/hosts.xml b/config-model/src/test/cfg/application/validation/global_distribution_validation/hosts.xml new file mode 100644 index 00000000000..c8cbda0509d --- /dev/null +++ b/config-model/src/test/cfg/application/validation/global_distribution_validation/hosts.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<hosts> + <host name="localhost"> + <alias>node1</alias> + </host> +</hosts> diff --git a/config-model/src/test/cfg/application/validation/global_distribution_validation/searchdefinitions/parent.sd b/config-model/src/test/cfg/application/validation/global_distribution_validation/searchdefinitions/parent.sd new file mode 100644 index 00000000000..a772cc87710 --- /dev/null +++ b/config-model/src/test/cfg/application/validation/global_distribution_validation/searchdefinitions/parent.sd @@ -0,0 +1,5 @@ +# Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +search parent { + document parent { + } +} diff --git a/config-model/src/test/cfg/application/validation/global_distribution_validation/searchdefinitions/simple.sd b/config-model/src/test/cfg/application/validation/global_distribution_validation/searchdefinitions/simple.sd new file mode 100644 index 00000000000..49572be1cae --- /dev/null +++ b/config-model/src/test/cfg/application/validation/global_distribution_validation/searchdefinitions/simple.sd @@ -0,0 +1,6 @@ +# Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +search simple { + document simple { + field my_reference type reference<parent> { indexing: summary } + } +} diff --git a/config-model/src/test/cfg/application/validation/global_distribution_validation/services.xml b/config-model/src/test/cfg/application/validation/global_distribution_validation/services.xml new file mode 100644 index 00000000000..df3a3e8f3d7 --- /dev/null +++ b/config-model/src/test/cfg/application/validation/global_distribution_validation/services.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<services> + <admin version="2.0"> + <adminserver hostalias="node1" /> + <logserver hostalias="node1" /> + </admin> + <content version="1.0"> + <redundancy>1</redundancy> + <documents> + <document type='simple' mode="index"/> + <document type='parent' mode="index"/> + </documents> + <nodes> + <node hostalias='node1' distribution-key='0'/> + </nodes> + </content> +</services> diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/GlobalDistributionValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/GlobalDistributionValidatorTest.java index 957d0c6230e..b60fdd41868 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/content/GlobalDistributionValidatorTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/content/GlobalDistributionValidatorTest.java @@ -1,6 +1,7 @@ package com.yahoo.vespa.model.content; import com.yahoo.documentmodel.NewDocumentType; +import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithFilePkg; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -14,8 +15,6 @@ import java.util.stream.Stream; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; import static java.util.stream.Collectors.toSet; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * @author bjorncs @@ -30,24 +29,37 @@ public class GlobalDistributionValidatorTest { Fixture fixture = new Fixture() .addGlobalDocument(createDocumentType("foo")) .addGlobalDocument(createDocumentType("bar")); - Redundancy redundancy = createRedundancyWithGlobalDistributionValue(false); - when(redundancy.effectiveFinalRedundancy()).thenReturn(1); - when(redundancy.totalNodes()).thenReturn(2); + Redundancy redundancy = createRedundancyWithoutGlobalDistribution(); exceptionRule.expect(IllegalArgumentException.class); exceptionRule.expectMessage( "The following document types are marked as global, " + "but do not have high enough redundancy to make the documents globally distributed: " + - "'bar', 'foo'. Redundancy is 1, expected 2."); + "'bar', 'foo'. Redundancy is 2, expected 3."); new GlobalDistributionValidator() .validate(fixture.getDocumentTypes(), fixture.getGloballyDistributedDocuments(), redundancy); } @Test - public void validation_succeeds_when_globally_distributed() { + public void throws_exception_if_searchable_copies_too_low() { + Fixture fixture = new Fixture() + .addGlobalDocument(createDocumentType("foo")) + .addGlobalDocument(createDocumentType("bar")); + Redundancy redundancy = createRedundancyWithTooFewSearchableCopies(); + + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage( + "The following document types have the number of searchable copies less than redundancy: " + + "'bar', 'foo'. Searchable copies is 1, while redundancy is 2."); + new GlobalDistributionValidator() + .validate(fixture.getDocumentTypes(), fixture.getGloballyDistributedDocuments(), redundancy); + } + + @Test + public void validation_succeeds_when_globally_distributed_and_enough_searchable_copies() { Fixture fixture = new Fixture() .addGlobalDocument(createDocumentType("foo")); - Redundancy redundancy = createRedundancyWithGlobalDistributionValue(true); + Redundancy redundancy = createRedundancyWithGlobalDistribution(); new GlobalDistributionValidator() .validate(fixture.getDocumentTypes(), fixture.getGloballyDistributedDocuments(), redundancy); } @@ -55,14 +67,14 @@ public class GlobalDistributionValidatorTest { @Test public void validation_succeeds_on_no_documents() { new GlobalDistributionValidator() - .validate(emptyMap(), emptySet(), createRedundancyWithGlobalDistributionValue(false)); + .validate(emptyMap(), emptySet(), createRedundancyWithoutGlobalDistribution()); } @Test public void validation_succeeds_on_no_global_documents() { Fixture fixture = new Fixture() .addNonGlobalDocument(createDocumentType("foo")); - Redundancy redundancy = createRedundancyWithGlobalDistributionValue(false); + Redundancy redundancy = createRedundancyWithoutGlobalDistribution(); new GlobalDistributionValidator() .validate(fixture.getDocumentTypes(), fixture.getGloballyDistributedDocuments(), redundancy); } @@ -73,7 +85,7 @@ public class GlobalDistributionValidatorTest { Fixture fixture = new Fixture() .addNonGlobalDocument(parent) .addNonGlobalDocument(createDocumentType("child", parent)); - Redundancy redundancy = createRedundancyWithGlobalDistributionValue(false); + Redundancy redundancy = createRedundancyWithoutGlobalDistribution(); exceptionRule.expect(IllegalArgumentException.class); exceptionRule.expectMessage( "The following document types are referenced from other documents, but are not globally distributed: 'parent'"); @@ -87,7 +99,7 @@ public class GlobalDistributionValidatorTest { Fixture fixture = new Fixture() .addGlobalDocument(parent) .addNonGlobalDocument(createDocumentType("child", parent)); - Redundancy redundancy = createRedundancyWithGlobalDistributionValue(true); + Redundancy redundancy = createRedundancyWithGlobalDistribution(); new GlobalDistributionValidator() .validate(fixture.getDocumentTypes(), fixture.getGloballyDistributedDocuments(), redundancy); } @@ -98,7 +110,7 @@ public class GlobalDistributionValidatorTest { NewDocumentType child = createDocumentType("child", unknown); Fixture fixture = new Fixture() .addNonGlobalDocument(child); - Redundancy redundancy = createRedundancyWithGlobalDistributionValue(true); + Redundancy redundancy = createRedundancyWithGlobalDistribution(); exceptionRule.expect(IllegalArgumentException.class); exceptionRule.expectMessage( "The following document types are referenced from other documents, but are not listed in services.xml: 'unknown'"); @@ -106,9 +118,29 @@ public class GlobalDistributionValidatorTest { .validate(fixture.getDocumentTypes(), fixture.getGloballyDistributedDocuments(), redundancy); } - private static Redundancy createRedundancyWithGlobalDistributionValue(boolean isGloballyDistributed) { - Redundancy redundancy = mock(Redundancy.class); - when(redundancy.isEffectivelyGloballyDistributed()).thenReturn(isGloballyDistributed); + @Test + public void throws_exception_if_referenced_document_not_global_end_to_end() { + exceptionRule.expect(IllegalArgumentException.class); + exceptionRule.expectMessage( + "The following document types are referenced from other documents, but are not globally distributed: 'parent'"); + new VespaModelCreatorWithFilePkg("src/test/cfg/application/validation/global_distribution_validation/").create(); + } + + private static Redundancy createRedundancyWithGlobalDistribution() { + Redundancy redundancy = new Redundancy(2, 2, 2); + redundancy.setTotalNodes(2); + return redundancy; + } + + private static Redundancy createRedundancyWithoutGlobalDistribution() { + Redundancy redundancy = new Redundancy(2, 2, 2); + redundancy.setTotalNodes(3); + return redundancy; + } + + private static Redundancy createRedundancyWithTooFewSearchableCopies() { + Redundancy redundancy = new Redundancy(2, 2, 1); + redundancy.setTotalNodes(2); return redundancy; } |