e30d78d4b3e32416be96eb4dfb8b9131c47ffda1
[policy/drools-pdp.git] / feature-pooling-dmaap / src / test / java / org / onap / policy / drools / pooling / message / SupportBasicMessageTester.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.drools.pooling.message;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.fail;
26
27 import com.fasterxml.jackson.databind.ObjectMapper;
28 import org.junit.Test;
29 import org.onap.policy.drools.pooling.PoolingFeatureException;
30
31 /**
32  * Superclass used to test subclasses of {@link Message}.
33  * 
34  * @param <T> type of {@link Message} subclass that this tests
35  */
36 public abstract class SupportBasicMessageTester<T extends Message> {
37     // values set by makeValidMessage()
38     public static final String VALID_HOST_PREDECESSOR = "hostA";
39     public static final String VALID_HOST = "hostB";
40     public static final String VALID_CHANNEL = "channelC";
41
42     /**
43      * Used to perform JSON serialization and de-serialization.
44      */
45     public final ObjectMapper mapper = new ObjectMapper();
46
47     /**
48      * The subclass of the type of Message being tested.
49      */
50     private final Class<T> subclazz;
51
52     /**
53      * Constructor.
54      * 
55      * @param subclazz subclass of {@link Message} being tested
56      */
57     public SupportBasicMessageTester(Class<T> subclazz) {
58         this.subclazz = subclazz;
59     }
60
61     /**
62      * Creates a default Message and verifies that the source and channel are
63      * {@code null}.
64      * 
65      */
66     @Test
67     public final void testDefaultConstructor() {
68         testDefaultConstructorFields(makeDefaultMessage());
69     }
70
71     /**
72      * Tests that the Message has the correct source, and that the channel is
73      * {@code null}.
74      * 
75      */
76     @Test
77     public final void testConstructorWithArgs() {
78         testValidFields(makeValidMessage());
79     }
80
81     /**
82      * Makes a valid message and then verifies that it can be serialized and
83      * de-serialized. Verifies that the de-serialized message is of the same
84      * type, and has the same content, as the original.
85      * 
86      * @throws Exception if an error occurs
87      */
88     @Test
89     public final void testJsonEncodeDecode() throws Exception {
90         T originalMsg = makeValidMessage();
91
92         Message msg = mapper.readValue(mapper.writeValueAsString(originalMsg), Message.class);
93         assertEquals(subclazz, msg.getClass());
94
95         msg.checkValidity();
96
97         testValidFields(subclazz.cast(msg));
98     }
99
100     /**
101      * Creates a valid Message and verifies that checkValidity() passes.
102      * 
103      * @throws PoolingFeatureException if an error occurs
104      */
105     @Test
106     public final void testCheckValidity_Ok() throws PoolingFeatureException {
107         T msg = makeValidMessage();
108         msg.checkValidity();
109
110         testValidFields(subclazz.cast(msg));
111     }
112
113     /**
114      * Creates a default Message and verifies that checkValidity() fails. Does
115      * not throw an exception.
116      */
117     @Test
118     public final void testCheckValidity_DefaultConstructor() {
119         try {
120             makeDefaultMessage().checkValidity();
121             fail("missing exception");
122
123         } catch (PoolingFeatureException expected) {
124             // success
125         }
126     }
127
128     /**
129      * Creates a message via {@link #makeValidMessage()}, updates it via the
130      * given function, and then invokes the checkValidity() method on it. It is
131      * expected that the checkValidity() will throw an exception.
132      * 
133      * @param func function to update the message prior to invoking
134      *        checkValidity()
135      */
136     public void expectCheckValidityFailure(MessageUpdateFunction<T> func) {
137         try {
138             T msg = makeValidMessage();
139             func.update(msg);
140
141             msg.checkValidity();
142
143             fail("missing exception");
144
145         } catch (PoolingFeatureException expected) {
146             // success
147         }
148     }
149
150     /**
151      * Creates a message via {@link #makeValidMessage()}, updates one of its
152      * fields via the given function, and then invokes the checkValidity()
153      * method on it. It is expected that the checkValidity() will throw an
154      * exception. It checks both the case when the message's field is set to
155      * {@code null}, and when it is set to empty (i.e., "").
156      * 
157      * @param func function to update the message's field prior to invoking
158      *        checkValidity()
159      */
160     public void expectCheckValidityFailure_NullOrEmpty(MessageFieldUpdateFunction<T> func) {
161         expectCheckValidityFailure(msg -> func.update(msg, null));
162         expectCheckValidityFailure(msg -> func.update(msg, ""));
163     }
164
165     /**
166      * Makes a message using the default constructor.
167      * 
168      * @return a new Message
169      */
170     public final T makeDefaultMessage() {
171         try {
172             return subclazz.getConstructor().newInstance();
173
174         } catch (Exception e) {
175             throw new AssertionError(e);
176         }
177     }
178
179
180     // the remaining methods will typically be overridden
181
182     /**
183      * Makes a message that will pass the validity check. Note: this should use
184      * the non-default constructor, and the source and channel should be set to
185      * {@link VALID_HOST} and {@link VALID_CHANNEL}, respectively.
186      * 
187      * @return a valid Message
188      */
189     public abstract T makeValidMessage();
190
191     /**
192      * Verifies that fields are set as expected by
193      * {@link #makeDefaultMessage()}.
194      * 
195      * @param msg the default Message
196      */
197     public void testDefaultConstructorFields(T msg) {
198         assertNull(msg.getSource());
199         assertNull(msg.getChannel());
200     }
201
202     /**
203      * Verifies that fields are set as expected by {@link #makeValidMessage()}.
204      * 
205      * @param msg message whose fields are to be validated
206      */
207     public void testValidFields(T msg) {
208         assertEquals(VALID_HOST, msg.getSource());
209         assertEquals(VALID_CHANNEL, msg.getChannel());
210     }
211
212     /**
213      * Function that updates a message.
214      * 
215      * @param <T> type of Message the function updates
216      */
217     @FunctionalInterface
218     public static interface MessageUpdateFunction<T extends Message> {
219
220         /**
221          * Updates a message.
222          * 
223          * @param msg message to be updated
224          */
225         public void update(T msg);
226     }
227
228     /**
229      * Function that updates a single field within a message.
230      * 
231      * @param <T> type of Message the function updates
232      */
233     @FunctionalInterface
234     public static interface MessageFieldUpdateFunction<T extends Message> {
235
236         /**
237          * Updates a field within a message.
238          * 
239          * @param msg message to be updated
240          * @param newValue new field value
241          */
242         public void update(T msg, String newValue);
243     }
244 }