aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/StructFieldAttributeChangeValidatorTestCase.java
blob: 691e4bf6744527bcf088e3eb9836648da33c8de9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.application.validation.change.search;

import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.vespa.model.application.validation.change.VespaConfigChangeAction;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;

import static com.yahoo.vespa.model.application.validation.change.ConfigChangeTestUtils.newRestartAction;

/**
 * @author geirst
 */
public class StructFieldAttributeChangeValidatorTestCase {

    private static class Fixture extends ContentClusterFixture {

        private final StructFieldAttributeChangeValidator structFieldAttributeValidator;
        private final DocumentTypeChangeValidator docTypeValidator;

        public Fixture(String currentSd, String nextSd) throws Exception {
            super(currentSd, nextSd);
            structFieldAttributeValidator = new StructFieldAttributeChangeValidator(ClusterSpec.Id.from("test"),
                                                                                    currentDocType(),
                                                                                    currentDb().getDerivedConfiguration().getAttributeFields(),
                                                                                    nextDocType(),
                                                                                    nextDb().getDerivedConfiguration().getAttributeFields());
            docTypeValidator = new DocumentTypeChangeValidator(ClusterSpec.Id.from("test"), currentDocType(), nextDocType());
        }

        @Override
        public List<VespaConfigChangeAction> validate() {
            List<VespaConfigChangeAction> result = new ArrayList<>();
            result.addAll(structFieldAttributeValidator.validate());
            result.addAll(docTypeValidator.validate());
            return result;
        }
    }

    private static void validate(String currentSd, String nextSd) throws Exception {
        new Fixture(currentSd, nextSd).assertValidation();
    }

    private static void validate(String currentSd, String nextSd, VespaConfigChangeAction expAction) throws Exception {
        new Fixture(currentSd, nextSd).assertValidation(expAction);
    }

    @Test
    void adding_attribute_aspect_to_struct_field_requires_restart() throws Exception {
        validate(arrayOfStruct(oneFieldStruct(), ""),
                arrayOfStruct(oneFieldStruct(), structAttribute("s1")),
                newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.s1' changed: add attribute aspect"));

        validate(mapOfStruct(oneFieldStruct(), ""),
                mapOfStruct(oneFieldStruct(), structAttribute("key")),
                newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.key' changed: add attribute aspect"));

        validate(mapOfStruct(oneFieldStruct(), ""),
                mapOfStruct(oneFieldStruct(), structAttribute("value.s1")),
                newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.value.s1' changed: add attribute aspect"));

        validate(mapOfPrimitive(""), mapOfPrimitive(structAttribute("key")),
                newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.key' changed: add attribute aspect"));

        validate(mapOfPrimitive(""), mapOfPrimitive(structAttribute("value")),
                newRestartAction(ClusterSpec.Id.from("test"), "Field 'f1.value' changed: add attribute aspect"));
    }

    @Test
    void removing_attribute_aspect_from_struct_field_is_ok() throws Exception {
        validate(arrayOfStruct(oneFieldStruct(), structAttribute("s1")),
                arrayOfStruct(oneFieldStruct(), ""));

        validate(mapOfStruct(oneFieldStruct(), structAttribute("key")),
                mapOfStruct(oneFieldStruct(), ""));

        validate(mapOfStruct(oneFieldStruct(), structAttribute("value.s1")),
                mapOfStruct(oneFieldStruct(), ""));

        validate(mapOfPrimitive(structAttribute("key")), mapOfPrimitive(""));

        validate(mapOfPrimitive(structAttribute("value")), mapOfPrimitive(""));
    }

    @Test
    void adding_struct_field_with_attribute_aspect_is_ok() throws Exception {
        validate(arrayOfStruct(oneFieldStruct(), ""),
                arrayOfStruct(twoFieldStruct(), structAttribute("s2")));

        validate(mapOfStruct(oneFieldStruct(), ""),
                mapOfStruct(twoFieldStruct(), structAttribute("value.s2")));
    }

    @Test
    void removing_struct_field_with_attribute_aspect_is_ok() throws Exception {
        validate(arrayOfStruct(twoFieldStruct(), structAttribute("s2")),
                arrayOfStruct(oneFieldStruct(), ""));

        validate(mapOfStruct(twoFieldStruct(), structAttribute("value.s2")),
                mapOfStruct(oneFieldStruct(), ""));
    }

    @Test
    void adding_struct_field_without_attribute_aspect_is_ok() throws Exception {
        validate(arrayOfStruct(oneFieldStruct(), ""),
                arrayOfStruct(twoFieldStruct(), ""));

        validate(mapOfStruct(oneFieldStruct(), ""),
                mapOfStruct(twoFieldStruct(), ""));
    }

    @Test
    void removing_struct_field_without_attribute_aspect_is_ok() throws Exception {
        validate(arrayOfStruct(twoFieldStruct(), ""),
                arrayOfStruct(oneFieldStruct(), ""));

        validate(mapOfStruct(twoFieldStruct(), ""),
                mapOfStruct(oneFieldStruct(), ""));
    }

    private static String oneFieldStruct() {
        return "struct s { field s1 type string {} }";
    }

    private static String twoFieldStruct() {
        return "struct s { field s1 type string {} field s2 type int {} }";
    }

    private static String structAttribute(String fieldName) {
        return "struct-field " + fieldName + " { indexing: attribute }";
    }

    private static String arrayOfStruct(String struct, String structField) {
        return struct + " field f1 type array<s> { " + structField + "}";
    }

    private static String mapOfStruct(String struct, String structField) {
        return struct + " field f1 type map<string,s> { " + structField + " }";
    }

    private static String mapOfPrimitive(String structField) {
        return "field f1 type map<string,int> { " + structField + " }";
    }

}