]> git.basschouten.com Git - openhab-addons.git/blob
c47545a199c1925977fa38f3043b53e18dcff9c9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.persistence.dynamodb.internal;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.junit.jupiter.api.Assumptions.assumeTrue;
17
18 import java.time.ZonedDateTime;
19 import java.util.Iterator;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.junit.jupiter.api.BeforeAll;
24 import org.junit.jupiter.api.Test;
25 import org.openhab.core.persistence.FilterCriteria;
26 import org.openhab.core.persistence.FilterCriteria.Operator;
27 import org.openhab.core.persistence.FilterCriteria.Ordering;
28 import org.openhab.core.persistence.HistoricItem;
29 import org.openhab.core.types.State;
30
31 /**
32  * This is abstract class helping with integration testing the persistence service. Different kind of queries are tested
33  * against actual dynamo db database.
34  *
35  *
36  * Inheritor of this base class needs to store two states of one item in a static method annotated with @BeforeClass.
37  * This
38  * static
39  * class should update the private static fields
40  * beforeStore (date before storing anything), afterStore1 (after storing first item, but before storing second item),
41  * afterStore2 (after storing second item). The item name must correspond to getItemName. The first state needs to be
42  * smaller than the second state.
43  *
44  * To have more comprehensive tests, the inheritor class can define getQueryItemStateBetween to provide a value between
45  * the two states. Null can be used to omit the additional tests.
46  *
47  *
48  * See DimmerItemIntegrationTest for example how to use this base class.
49  *
50  * @author Sami Salonen - Initial contribution
51  *
52  */
53 @NonNullByDefault
54 public abstract class AbstractTwoItemIntegrationTest extends BaseIntegrationTest {
55
56     protected static @Nullable ZonedDateTime beforeStore;
57     protected static @Nullable ZonedDateTime afterStore1;
58     protected static @Nullable ZonedDateTime afterStore2;
59
60     protected abstract String getItemName();
61
62     /**
63      * State of the time item stored first, should be smaller than the second value
64      *
65      * @return
66      */
67     protected abstract State getFirstItemState();
68
69     /**
70      * State of the time item stored second, should be larger than the first value
71      *
72      * @return
73      */
74     protected abstract State getSecondItemState();
75
76     /**
77      * State that is between the first and second. Use null to omit extended tests using this value.
78      *
79      * @return
80      */
81     protected abstract @Nullable State getQueryItemStateBetween();
82
83     protected void assertStateEquals(State expected, State actual) {
84         assertEquals(expected, actual);
85     }
86
87     @BeforeAll
88     public static void checkService() throws InterruptedException {
89         String msg = "DynamoDB integration tests will be skipped. Did you specify AWS credentials for testing? "
90                 + "See BaseIntegrationTest for more details";
91         if (service == null) {
92             System.out.println(msg);
93         }
94         assumeTrue(service != null, msg);
95     }
96
97     /**
98      * Asserts that iterable contains correct items and nothing else
99      *
100      */
101     private void assertIterableContainsItems(Iterable<HistoricItem> iterable, boolean ascending) {
102         Iterator<HistoricItem> iterator = iterable.iterator();
103         HistoricItem actual1 = iterator.next();
104         HistoricItem actual2 = iterator.next();
105         assertFalse(iterator.hasNext());
106
107         for (HistoricItem actual : new HistoricItem[] { actual1, actual2 }) {
108             assertEquals(getItemName(), actual.getName());
109         }
110         HistoricItem storedFirst;
111         HistoricItem storedSecond;
112         if (ascending) {
113             storedFirst = actual1;
114             storedSecond = actual2;
115         } else {
116             storedFirst = actual2;
117             storedSecond = actual1;
118         }
119
120         assertStateEquals(getFirstItemState(), storedFirst.getState());
121         assertTrue(storedFirst.getTimestamp().toInstant().isBefore(afterStore1.toInstant()));
122         assertTrue(storedFirst.getTimestamp().toInstant().isAfter(beforeStore.toInstant()));
123
124         assertStateEquals(getSecondItemState(), storedSecond.getState());
125         assertTrue(storedSecond.getTimestamp().toInstant().isBefore(afterStore2.toInstant()));
126         assertTrue(storedSecond.getTimestamp().toInstant().isAfter(afterStore1.toInstant()));
127     }
128
129     @Test
130     public void testQueryUsingName() {
131         FilterCriteria criteria = new FilterCriteria();
132         criteria.setOrdering(Ordering.ASCENDING);
133         criteria.setItemName(getItemName());
134         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
135         assertIterableContainsItems(iterable, true);
136     }
137
138     @Test
139     public void testQueryUsingNameAndStart() {
140         FilterCriteria criteria = new FilterCriteria();
141         criteria.setOrdering(Ordering.ASCENDING);
142         criteria.setItemName(getItemName());
143         criteria.setBeginDate(beforeStore);
144         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
145         assertIterableContainsItems(iterable, true);
146     }
147
148     @Test
149     public void testQueryUsingNameAndStartNoMatch() {
150         FilterCriteria criteria = new FilterCriteria();
151         criteria.setItemName(getItemName());
152         criteria.setBeginDate(afterStore2);
153         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
154         assertFalse(iterable.iterator().hasNext());
155     }
156
157     @Test
158     public void testQueryUsingNameAndEnd() {
159         FilterCriteria criteria = new FilterCriteria();
160         criteria.setOrdering(Ordering.ASCENDING);
161         criteria.setItemName(getItemName());
162         criteria.setEndDate(afterStore2);
163         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
164         assertIterableContainsItems(iterable, true);
165     }
166
167     @Test
168     public void testQueryUsingNameAndEndNoMatch() {
169         FilterCriteria criteria = new FilterCriteria();
170         criteria.setItemName(getItemName());
171         criteria.setEndDate(beforeStore);
172         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
173         assertFalse(iterable.iterator().hasNext());
174     }
175
176     @Test
177     public void testQueryUsingNameAndStartAndEnd() {
178         FilterCriteria criteria = new FilterCriteria();
179         criteria.setOrdering(Ordering.ASCENDING);
180         criteria.setItemName(getItemName());
181         criteria.setBeginDate(beforeStore);
182         criteria.setEndDate(afterStore2);
183         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
184         assertIterableContainsItems(iterable, true);
185     }
186
187     @Test
188     public void testQueryUsingNameAndStartAndEndDesc() {
189         FilterCriteria criteria = new FilterCriteria();
190         criteria.setOrdering(Ordering.DESCENDING);
191         criteria.setItemName(getItemName());
192         criteria.setBeginDate(beforeStore);
193         criteria.setEndDate(afterStore2);
194         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
195         assertIterableContainsItems(iterable, false);
196     }
197
198     @Test
199     public void testQueryUsingNameAndStartAndEndWithNEQOperator() {
200         FilterCriteria criteria = new FilterCriteria();
201         criteria.setOperator(Operator.NEQ);
202         criteria.setState(getSecondItemState());
203         criteria.setItemName(getItemName());
204         criteria.setBeginDate(beforeStore);
205         criteria.setEndDate(afterStore2);
206         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
207         Iterator<HistoricItem> iterator = iterable.iterator();
208         HistoricItem actual1 = iterator.next();
209         assertFalse(iterator.hasNext());
210         assertStateEquals(getFirstItemState(), actual1.getState());
211         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore1.toInstant()));
212         assertTrue(actual1.getTimestamp().toInstant().isAfter(beforeStore.toInstant()));
213     }
214
215     @Test
216     public void testQueryUsingNameAndStartAndEndWithEQOperator() {
217         FilterCriteria criteria = new FilterCriteria();
218         criteria.setOperator(Operator.EQ);
219         criteria.setState(getFirstItemState());
220         criteria.setItemName(getItemName());
221         criteria.setBeginDate(beforeStore);
222         criteria.setEndDate(afterStore2);
223         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
224         Iterator<HistoricItem> iterator = iterable.iterator();
225         HistoricItem actual1 = iterator.next();
226         assertFalse(iterator.hasNext());
227         assertStateEquals(getFirstItemState(), actual1.getState());
228         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore1.toInstant()));
229         assertTrue(actual1.getTimestamp().toInstant().isAfter(beforeStore.toInstant()));
230     }
231
232     @Test
233     public void testQueryUsingNameAndStartAndEndWithLTOperator() {
234         FilterCriteria criteria = new FilterCriteria();
235         criteria.setOperator(Operator.LT);
236         criteria.setState(getSecondItemState());
237         criteria.setItemName(getItemName());
238         criteria.setBeginDate(beforeStore);
239         criteria.setEndDate(afterStore2);
240         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
241         Iterator<HistoricItem> iterator = iterable.iterator();
242         HistoricItem actual1 = iterator.next();
243         assertFalse(iterator.hasNext());
244         assertStateEquals(getFirstItemState(), actual1.getState());
245         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore1.toInstant()));
246         assertTrue(actual1.getTimestamp().toInstant().isAfter(beforeStore.toInstant()));
247     }
248
249     @Test
250     public void testQueryUsingNameAndStartAndEndWithLTOperatorNoMatch() {
251         FilterCriteria criteria = new FilterCriteria();
252         criteria.setOperator(Operator.LT);
253         criteria.setState(getFirstItemState());
254         criteria.setItemName(getItemName());
255         criteria.setBeginDate(beforeStore);
256         criteria.setEndDate(afterStore2);
257         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
258         Iterator<HistoricItem> iterator = iterable.iterator();
259         assertFalse(iterator.hasNext());
260     }
261
262     @Test
263     public void testQueryUsingNameAndStartAndEndWithLTEOperator() {
264         FilterCriteria criteria = new FilterCriteria();
265         criteria.setOperator(Operator.LTE);
266         criteria.setState(getFirstItemState());
267         criteria.setItemName(getItemName());
268         criteria.setBeginDate(beforeStore);
269         criteria.setEndDate(afterStore2);
270         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
271         Iterator<HistoricItem> iterator = iterable.iterator();
272         HistoricItem actual1 = iterator.next();
273         assertFalse(iterator.hasNext());
274         assertStateEquals(getFirstItemState(), actual1.getState());
275         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore1.toInstant()));
276         assertTrue(actual1.getTimestamp().toInstant().isAfter(beforeStore.toInstant()));
277     }
278
279     @Test
280     public void testQueryUsingNameAndStartAndEndWithGTOperator() {
281         // Skip for subclasses which have null "state between"
282         assumeTrue(getQueryItemStateBetween() != null);
283
284         FilterCriteria criteria = new FilterCriteria();
285         criteria.setOperator(Operator.GT);
286         criteria.setState(getQueryItemStateBetween());
287         criteria.setItemName(getItemName());
288         criteria.setBeginDate(beforeStore);
289         criteria.setEndDate(afterStore2);
290         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
291         Iterator<HistoricItem> iterator = iterable.iterator();
292         HistoricItem actual1 = iterator.next();
293         assertFalse(iterator.hasNext());
294         assertStateEquals(getSecondItemState(), actual1.getState());
295         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore2.toInstant()));
296         assertTrue(actual1.getTimestamp().toInstant().isAfter(afterStore1.toInstant()));
297     }
298
299     @Test
300     public void testQueryUsingNameAndStartAndEndWithGTOperatorNoMatch() {
301         FilterCriteria criteria = new FilterCriteria();
302         criteria.setOperator(Operator.GT);
303         criteria.setState(getSecondItemState());
304         criteria.setItemName(getItemName());
305         criteria.setBeginDate(beforeStore);
306         criteria.setEndDate(afterStore2);
307         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
308         Iterator<HistoricItem> iterator = iterable.iterator();
309         assertFalse(iterator.hasNext());
310     }
311
312     @Test
313     public void testQueryUsingNameAndStartAndEndWithGTEOperator() {
314         FilterCriteria criteria = new FilterCriteria();
315         criteria.setOperator(Operator.GTE);
316         criteria.setState(getSecondItemState());
317         criteria.setItemName(getItemName());
318         criteria.setBeginDate(beforeStore);
319         criteria.setEndDate(afterStore2);
320         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
321         Iterator<HistoricItem> iterator = iterable.iterator();
322         HistoricItem actual1 = iterator.next();
323         assertFalse(iterator.hasNext());
324         assertStateEquals(getSecondItemState(), actual1.getState());
325         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore2.toInstant()));
326         assertTrue(actual1.getTimestamp().toInstant().isAfter(afterStore1.toInstant()));
327     }
328
329     @Test
330     public void testQueryUsingNameAndStartAndEndFirst() {
331         FilterCriteria criteria = new FilterCriteria();
332         criteria.setOrdering(Ordering.ASCENDING);
333         criteria.setItemName(getItemName());
334         criteria.setBeginDate(beforeStore);
335         criteria.setEndDate(afterStore1);
336         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
337
338         Iterator<HistoricItem> iterator = iterable.iterator();
339         HistoricItem actual1 = iterator.next();
340         assertFalse(iterator.hasNext());
341         assertStateEquals(getFirstItemState(), actual1.getState());
342         assertTrue(actual1.getTimestamp().toInstant().isBefore(afterStore1.toInstant()));
343         assertTrue(actual1.getTimestamp().toInstant().isAfter(beforeStore.toInstant()));
344     }
345
346     @Test
347     public void testQueryUsingNameAndStartAndEndNoMatch() {
348         FilterCriteria criteria = new FilterCriteria();
349         criteria.setItemName(getItemName());
350         criteria.setBeginDate(beforeStore);
351         criteria.setEndDate(beforeStore); // sic
352         Iterable<HistoricItem> iterable = BaseIntegrationTest.service.query(criteria);
353         assertFalse(iterable.iterator().hasNext());
354     }
355 }