]> git.basschouten.com Git - openhab-addons.git/blob
ce945a6b6daac108939ee5b221304a70da137c66
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.inmemory.internal;
14
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.Matchers.*;
17 import static org.mockito.Mockito.when;
18
19 import java.time.ZoneId;
20 import java.time.ZonedDateTime;
21 import java.util.ArrayList;
22 import java.util.Comparator;
23 import java.util.List;
24 import java.util.TreeSet;
25
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.junit.jupiter.api.BeforeEach;
28 import org.junit.jupiter.api.Test;
29 import org.junit.jupiter.api.extension.ExtendWith;
30 import org.mockito.Mock;
31 import org.mockito.junit.jupiter.MockitoExtension;
32 import org.mockito.junit.jupiter.MockitoSettings;
33 import org.mockito.quality.Strictness;
34 import org.openhab.core.items.GenericItem;
35 import org.openhab.core.library.types.DecimalType;
36 import org.openhab.core.library.types.HSBType;
37 import org.openhab.core.library.types.PercentType;
38 import org.openhab.core.library.types.StringType;
39 import org.openhab.core.persistence.FilterCriteria;
40 import org.openhab.core.persistence.HistoricItem;
41 import org.openhab.core.types.State;
42
43 /**
44  * The {@link InMemoryPersistenceTests} contains tests for the {@link InMemoryPersistenceService}
45  *
46  * @author Jan N. Klug - Initial contribution
47  */
48 @ExtendWith(MockitoExtension.class)
49 @MockitoSettings(strictness = Strictness.LENIENT)
50 @NonNullByDefault
51 public class InMemoryPersistenceTests {
52     private static final String ITEM_NAME = "testItem";
53     private static final String ALIAS = "alias";
54
55     private @NonNullByDefault({}) InMemoryPersistenceService service;
56     private @NonNullByDefault({}) @Mock GenericItem item;
57
58     private @NonNullByDefault({}) FilterCriteria filterCriteria;
59
60     @BeforeEach
61     public void setup() {
62         when(item.getName()).thenReturn(ITEM_NAME);
63
64         filterCriteria = new FilterCriteria();
65         filterCriteria.setItemName(ITEM_NAME);
66
67         service = new InMemoryPersistenceService();
68     }
69
70     @Test
71     public void storeDirect() {
72         State state = new DecimalType(1);
73         when(item.getState()).thenReturn(state);
74
75         ZonedDateTime expectedTime = ZonedDateTime.now();
76         service.store(item);
77
78         TreeSet<HistoricItem> storedStates = new TreeSet<>(Comparator.comparing(HistoricItem::getTimestamp));
79         service.query(filterCriteria).forEach(storedStates::add);
80
81         assertThat(storedStates, hasSize(1));
82         assertThat(storedStates.first().getName(), is(ITEM_NAME));
83         assertThat(storedStates.first().getState(), is(state));
84         assertThat((double) storedStates.first().getTimestamp().toEpochSecond(),
85                 is(closeTo(expectedTime.toEpochSecond(), 2)));
86     }
87
88     @Test
89     public void storeAlias() {
90         State state = new PercentType(1);
91         when(item.getState()).thenReturn(state);
92
93         ZonedDateTime expectedTime = ZonedDateTime.now();
94         service.store(item, ALIAS);
95
96         TreeSet<HistoricItem> storedStates = new TreeSet<>(Comparator.comparing(HistoricItem::getTimestamp));
97
98         // query with item name should return nothing
99         service.query(filterCriteria).forEach(storedStates::add);
100         assertThat(storedStates, is(empty()));
101
102         filterCriteria.setItemName(ALIAS);
103         service.query(filterCriteria).forEach(storedStates::add);
104
105         assertThat(storedStates.size(), is(1));
106         assertThat(storedStates.first().getName(), is(ALIAS));
107         assertThat(storedStates.first().getState(), is(state));
108         assertThat((double) storedStates.first().getTimestamp().toEpochSecond(),
109                 is(closeTo(expectedTime.toEpochSecond(), 2)));
110     }
111
112     @Test
113     public void storeHistoric() {
114         State state = new HSBType("120,100,100");
115         when(item.getState()).thenReturn(state);
116
117         State historicState = new HSBType("40,50,50");
118         ZonedDateTime expectedTime = ZonedDateTime.of(2022, 05, 31, 10, 0, 0, 0, ZoneId.systemDefault());
119         service.store(item, expectedTime, historicState);
120
121         TreeSet<HistoricItem> storedStates = new TreeSet<>(Comparator.comparing(HistoricItem::getTimestamp));
122         service.query(filterCriteria).forEach(storedStates::add);
123
124         assertThat(storedStates, hasSize(1));
125         assertThat(storedStates.first().getName(), is(ITEM_NAME));
126         assertThat(storedStates.first().getState(), is(historicState));
127         assertThat(storedStates.first().getTimestamp(), is(expectedTime));
128     }
129
130     @Test
131     public void queryWithoutItemNameReturnsEmptyList() {
132         TreeSet<HistoricItem> storedStates = new TreeSet<>(Comparator.comparing(HistoricItem::getTimestamp));
133         service.query(new FilterCriteria()).forEach(storedStates::add);
134
135         assertThat(storedStates, is(empty()));
136     }
137
138     @Test
139     public void queryUnknownItemReturnsEmptyList() {
140         TreeSet<HistoricItem> storedStates = new TreeSet<>(Comparator.comparing(HistoricItem::getTimestamp));
141         service.query(filterCriteria).forEach(storedStates::add);
142
143         assertThat(storedStates, is(empty()));
144     }
145
146     @Test
147     public void querySupportsAscendingOrdering() {
148         ZonedDateTime start = ZonedDateTime.of(2020, 12, 1, 12, 0, 0, 0, ZoneId.systemDefault());
149         service.store(item, start, new DecimalType(1));
150         service.store(item, start.plusHours(1), new DecimalType(2));
151         service.store(item, start.plusHours(2), new DecimalType(3));
152
153         filterCriteria.setOrdering(FilterCriteria.Ordering.ASCENDING);
154         filterCriteria.setBeginDate(start);
155
156         List<Integer> resultSet = new ArrayList<>();
157         service.query(filterCriteria).forEach(h -> resultSet.add(((DecimalType) h.getState()).intValue()));
158
159         assertThat(resultSet, contains(1, 2, 3));
160     }
161
162     @Test
163     public void querySupportsDescendingOrdering() {
164         ZonedDateTime start = ZonedDateTime.of(2020, 12, 1, 12, 0, 0, 0, ZoneId.systemDefault());
165         service.store(item, start, new DecimalType(1));
166         service.store(item, start.plusHours(1), new DecimalType(2));
167         service.store(item, start.plusHours(2), new DecimalType(3));
168
169         filterCriteria.setOrdering(FilterCriteria.Ordering.DESCENDING);
170         filterCriteria.setBeginDate(start);
171
172         List<Integer> resultSet = new ArrayList<>();
173         service.query(filterCriteria).forEach(h -> resultSet.add(((DecimalType) h.getState()).intValue()));
174
175         assertThat(resultSet, contains(3, 2, 1));
176     }
177
178     @Test
179     public void removeBetweenTimes() {
180         State historicState1 = new StringType("value1");
181         State historicState2 = new StringType("value2");
182         State historicState3 = new StringType("value3");
183
184         ZonedDateTime expectedTime = ZonedDateTime.of(2022, 05, 31, 10, 0, 0, 0, ZoneId.systemDefault());
185         service.store(item, expectedTime, historicState1);
186         service.store(item, expectedTime.plusHours(2), historicState2);
187         service.store(item, expectedTime.plusHours(4), historicState3);
188
189         // ensure both are stored
190         TreeSet<HistoricItem> storedStates = new TreeSet<>(Comparator.comparing(HistoricItem::getTimestamp));
191         service.query(filterCriteria).forEach(storedStates::add);
192
193         assertThat(storedStates, hasSize(3));
194
195         filterCriteria.setBeginDate(expectedTime.plusHours(1));
196         filterCriteria.setEndDate(expectedTime.plusHours(3));
197         service.remove(filterCriteria);
198
199         filterCriteria = new FilterCriteria();
200         filterCriteria.setItemName(ITEM_NAME);
201         storedStates.clear();
202         service.query(filterCriteria).forEach(storedStates::add);
203
204         assertThat(storedStates, hasSize(2));
205
206         assertThat(storedStates.first().getName(), is(ITEM_NAME));
207         assertThat(storedStates.first().getState(), is(historicState1));
208         assertThat(storedStates.first().getTimestamp(), is(expectedTime));
209
210         assertThat(storedStates.last().getName(), is(ITEM_NAME));
211         assertThat(storedStates.last().getState(), is(historicState3));
212         assertThat(storedStates.last().getTimestamp(), is(expectedTime.plusHours(4)));
213     }
214 }