diff options
Diffstat (limited to 'config-model/src/test/java/com/yahoo')
4 files changed, 185 insertions, 10 deletions
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java index eecd03cbe5b..f7641f97df6 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/derived/ImportedFieldsTestCase.java @@ -15,4 +15,9 @@ public class ImportedFieldsTestCase extends AbstractExportingTestCase { public void configs_for_imported_fields_are_derived() throws IOException, ParseException { assertCorrectDeriving("importedfields", "child"); } + + @Test + public void configs_for_imported_struct_fields_are_derived() throws IOException, ParseException { + assertCorrectDeriving("imported_struct_fields", "child"); + } } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java index 48adc0eefc5..3735b997073 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/AddAttributeTransformToSummaryOfImportedFieldsTest.java @@ -54,7 +54,7 @@ public class AddAttributeTransformToSummaryOfImportedFieldsTest { SDField targetField = new SDField("target_field", DataType.INT); DocumentReference documentReference = new DocumentReference(new Field("reference_field"), targetSearch); ImportedField importedField = new ImportedField(fieldName, documentReference, targetField); - return new ImportedFields(Collections.singletonMap(fieldName, importedField)); + return new ImportedFields(Collections.singletonMap(fieldName, importedField), Collections.emptyMap()); } private static DocumentSummary createDocumentSummary(String fieldName) { diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java index 9b63c1cafe9..4167e534653 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ImportedFieldsTestCase.java @@ -12,6 +12,7 @@ import org.junit.rules.ExpectedException; import static org.junit.Assert.assertEquals; import static com.yahoo.config.model.test.TestUtil.joinLines; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; /** * @author geirst @@ -20,14 +21,14 @@ public class ImportedFieldsTestCase { @Test public void fields_can_be_imported_from_referenced_document_types() throws ParseException { - Search search = buildAdSearch(joinLines( - "search ad {", - " document ad {", - " field campaign_ref type reference<campaign> { indexing: attribute }", - " field person_ref type reference<person> { indexing: attribute }", - " }", - " import field campaign_ref.budget as my_budget {}", - " import field person_ref.name as my_name {}", + Search search = buildAdSearch(joinLines( + "search ad {", + " document ad {", + " field campaign_ref type reference<campaign> { indexing: attribute }", + " field person_ref type reference<person> { indexing: attribute }", + " }", + " import field campaign_ref.budget as my_budget {}", + " import field person_ref.name as my_name {}", "}")); assertEquals(2, search.importedFields().get().fields().size()); assertSearchContainsImportedField("my_budget", "campaign_ref", "campaign", "budget", search); @@ -65,6 +66,166 @@ public class ImportedFieldsTestCase { return builder.getSearch("ad"); } + private static void checkStructImport(ParentSdBuilder parentBuilder) throws ParseException { + Search search = buildChildSearch(parentBuilder.build(), joinLines("search child {", + " document child {", + " field parent_ref type reference<parent> {", + " indexing: attribute | summary", + " }", + " }", + " import field parent_ref.elem_array as my_elem_array {}", + " import field parent_ref.elem_map as my_elem_map {}", + " import field parent_ref.str_int_map as my_str_int_map {}", + "}")); + assertEquals(parentBuilder.countAttrs(), search.importedFields().get().fields().size()); + checkImportedField("my_elem_array.name", "parent_ref", "parent", "elem_array.name", search, parentBuilder.elem_array_name_attr); + checkImportedField("my_elem_array.weight", "parent_ref", "parent", "elem_array.weight", search, parentBuilder.elem_array_weight_attr); + checkImportedField("my_elem_map.key", "parent_ref", "parent", "elem_map.key", search, parentBuilder.elem_map_key_attr); + checkImportedField("my_elem_map.value.name", "parent_ref", "parent", "elem_map.value.name", search, parentBuilder.elem_map_value_name_attr); + checkImportedField("my_elem_map.value.weight", "parent_ref", "parent", "elem_map.value.weight", search, parentBuilder.elem_map_value_weight_attr); + checkImportedField("my_str_int_map.key", "parent_ref", "parent", "str_int_map.key", search, parentBuilder.str_int_map_key_attr); + checkImportedField("my_str_int_map.value", "parent_ref", "parent", "str_int_map.value", search, parentBuilder.str_int_map_value_attr); + } + + @Test + public void check_struct_import() throws ParseException { + checkStructImport(new ParentSdBuilder()); + checkStructImport(new ParentSdBuilder().elem_array_weight_attr(false).elem_map_value_weight_attr(false)); + checkStructImport(new ParentSdBuilder().elem_array_name_attr(false).elem_map_value_name_attr(false)); + } + + @Test + public void check_illegal_struct_import_missing_array_of_struct_attributes() throws ParseException { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("For search 'child', import field 'my_elem_array' (nested to 'my_elem_array'): Field 'elem_array' via reference field 'parent_ref': Is not a struct containing an attribute field."); + checkStructImport(new ParentSdBuilder().elem_array_name_attr(false).elem_array_weight_attr(false)); + } + + @Test + public void check_illegal_struct_import_missing_map_of_struct_key_attribute() throws ParseException { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("For search 'child', import field 'my_elem_map' (nested to 'my_elem_map.key'): Field 'elem_map.key' via reference field 'parent_ref': Is not an attribute field. Only attribute fields supported"); + checkStructImport(new ParentSdBuilder().elem_map_key_attr(false)); + } + + @Test + public void check_illegal_struct_import_missing_map_of_struct_value_attributes() throws ParseException { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("For search 'child', import field 'my_elem_map' (nested to 'my_elem_map.value'): Field 'elem_map.value' via reference field 'parent_ref': Is not a struct containing an attribute field."); + checkStructImport(new ParentSdBuilder().elem_map_value_name_attr(false).elem_map_value_weight_attr(false)); + } + + @Test + public void check_illegal_struct_import_missing_map_of_primitive_key_attribute() throws ParseException { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("For search 'child', import field 'my_str_int_map' (nested to 'my_str_int_map.key'): Field 'str_int_map.key' via reference field 'parent_ref': Is not an attribute field. Only attribute fields supported"); + checkStructImport(new ParentSdBuilder().str_int_map_key_attr(false)); + } + + @Test + public void check_illegal_struct_import_missing_map_of_primitive_value_attribute() throws ParseException { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("For search 'child', import field 'my_str_int_map' (nested to 'my_str_int_map.value'): Field 'str_int_map.value' via reference field 'parent_ref': Is not an attribute field. Only attribute fields supported"); + checkStructImport(new ParentSdBuilder().str_int_map_value_attr(false)); + } + + private static class ParentSdBuilder { + private boolean elem_array_name_attr; + private boolean elem_array_weight_attr; + private boolean elem_map_key_attr; + private boolean elem_map_value_name_attr; + private boolean elem_map_value_weight_attr; + private boolean str_int_map_key_attr; + private boolean str_int_map_value_attr; + + public ParentSdBuilder() { + elem_array_name_attr = true; + elem_array_weight_attr = true; + elem_map_key_attr = true; + elem_map_value_name_attr = true; + elem_map_value_weight_attr = true; + str_int_map_key_attr = true; + str_int_map_value_attr = true; + } + + public ParentSdBuilder elem_array_name_attr(boolean v) { elem_array_name_attr = v; return this; } + public ParentSdBuilder elem_array_weight_attr(boolean v) { elem_array_weight_attr = v; return this; } + public ParentSdBuilder elem_map_key_attr(boolean v) { elem_map_key_attr = v; return this; } + public ParentSdBuilder elem_map_value_name_attr(boolean v) { elem_map_value_name_attr = v; return this; } + public ParentSdBuilder elem_map_value_weight_attr(boolean v) { elem_map_value_weight_attr = v; return this; } + public ParentSdBuilder str_int_map_key_attr(boolean v) { str_int_map_key_attr = v; return this; } + public ParentSdBuilder str_int_map_value_attr(boolean v) { str_int_map_value_attr = v; return this; } + + public String build() { + return joinLines("search parent {", + " document parent {", + " struct elem {", + " field name type string {}", + " field weight type int {}", + " }", + " field elem_array type array<elem> {", + " indexing: summary", + " struct-field name {", + structFieldSpec(elem_array_name_attr), + " }", + " struct-field weight {", + structFieldSpec(elem_array_weight_attr), + " }", + " }", + " field elem_map type map<string, elem> {", + " indexing: summary", + " struct-field key {", + structFieldSpec(elem_map_key_attr), + " }", + " struct-field value.name {", + structFieldSpec(elem_map_value_name_attr), + " }", + " struct-field value.weight {", + structFieldSpec(elem_map_value_weight_attr), + " }", + " }", + " field str_int_map type map<string, int> {", + " indexing: summary", + " struct-field key {", + structFieldSpec(str_int_map_key_attr), + " }", + " struct-field value {", + structFieldSpec(str_int_map_value_attr), + " }", + " }", + " }", + "}"); + } + + private static String structFieldSpec(boolean isAttribute) { + return isAttribute ? " indexing: attribute" : ""; + } + + private static int b2i(boolean b) { + return b ? 1 : 0; + } + + public int countAttrs() { + int elem_array_attr_count = b2i(elem_array_name_attr) + b2i(elem_array_weight_attr); + int elem_map_attr_count = b2i(elem_map_key_attr) + b2i(elem_map_value_name_attr) + b2i(elem_map_value_weight_attr); + int str_int_map_attr_count = b2i(str_int_map_key_attr) + b2i(str_int_map_value_attr); + return elem_array_attr_count + elem_map_attr_count + str_int_map_attr_count; + } + } + + private static Search buildChildSearch(String parentSdContent, String sdContent) throws ParseException { + SearchBuilder builder = new SearchBuilder(); + builder.importString(parentSdContent); + builder.importString(sdContent); + builder.build(); + return builder.getSearch("child"); + } + + private static void assertSearchNotContainsImportedField(String fieldName, Search search) { + ImportedField importedField = search.importedFields().get().fields().get(fieldName); + assertNull(importedField); + } + private static void assertSearchContainsImportedField(String fieldName, String referenceFieldName, String referenceDocType, @@ -77,4 +238,13 @@ public class ImportedFieldsTestCase { assertEquals(referenceDocType, importedField.reference().targetSearch().getName()); assertEquals(targetFieldName, importedField.targetField().getName()); } + + private static void checkImportedField(String fieldName, String referenceFieldName, String referenceDocType, + String targetFieldName, Search search, boolean present) { + if (present) { + assertSearchContainsImportedField(fieldName, referenceFieldName, referenceDocType, targetFieldName, search); + } else { + assertSearchNotContainsImportedField(fieldName, search); + } + } } diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java index d0b6524a7e1..e4c23f407c8 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/ValidateFieldTypesTest.java @@ -55,7 +55,7 @@ public class ValidateFieldTypesTest { SDField targetField = new SDField("target_field", dataType); DocumentReference documentReference = new DocumentReference(new Field("reference_field"), targetSearch); ImportedField importedField = new ImportedField(fieldName, documentReference, targetField); - return new ImportedFields(Collections.singletonMap(fieldName, importedField)); + return new ImportedFields(Collections.singletonMap(fieldName, importedField), Collections.emptyMap()); } private static DocumentSummary createDocumentSummary(String fieldName, DataType dataType) { |