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