]> git.basschouten.com Git - openhab-addons.git/blob
a8cabbd6becd4d5ac2491e314e03b9d3552595b2
[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.binding.modbus.tests;
14
15 import static org.hamcrest.CoreMatchers.*;
16 import static org.hamcrest.core.Is.is;
17 import static org.hamcrest.core.IsInstanceOf.instanceOf;
18 import static org.junit.Assert.*;
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.Mockito.*;
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Dictionary;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Hashtable;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.eclipse.jdt.annotation.NonNull;
33 import org.eclipse.jdt.annotation.NonNullByDefault;
34 import org.eclipse.jdt.annotation.Nullable;
35 import org.openhab.core.events.Event;
36 import org.openhab.core.events.EventFilter;
37 import org.openhab.core.events.EventSubscriber;
38 import org.openhab.core.items.Item;
39 import org.openhab.core.items.ItemProvider;
40 import org.openhab.core.items.ItemRegistry;
41 import org.openhab.core.items.ManagedItemProvider;
42 import org.openhab.core.items.events.ItemStateEvent;
43 import org.openhab.core.library.CoreItemFactory;
44 import org.openhab.core.thing.ChannelUID;
45 import org.openhab.core.thing.ManagedThingProvider;
46 import org.openhab.core.thing.Thing;
47 import org.openhab.core.thing.ThingProvider;
48 import org.openhab.core.thing.binding.ThingHandler;
49 import org.openhab.core.thing.binding.ThingHandlerFactory;
50 import org.openhab.core.thing.link.ItemChannelLink;
51 import org.openhab.core.thing.link.ItemChannelLinkProvider;
52 import org.openhab.core.thing.link.ManagedItemChannelLinkProvider;
53 import org.openhab.core.transform.TransformationService;
54 import org.openhab.core.types.State;
55 import org.openhab.core.test.java.JavaOSGiTest;
56 import org.junit.After;
57 import org.junit.Before;
58 import org.mockito.Mock;
59 import org.mockito.Mockito;
60 import org.openhab.binding.modbus.internal.ModbusHandlerFactory;
61 import org.openhab.io.transport.modbus.ModbusCommunicationInterface;
62 import org.openhab.io.transport.modbus.ModbusManager;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66 /**
67  * @author Sami Salonen - Initial contribution
68  */
69 @NonNullByDefault
70 public abstract class AbstractModbusOSGiTest extends JavaOSGiTest {
71
72     private static class StateSubscriber implements EventSubscriber {
73
74         private final Logger logger = LoggerFactory.getLogger(StateSubscriber.class);
75
76         public Map<String, List<State>> stateUpdates = new HashMap<>();
77
78         @Override
79         public Set<@NonNull String> getSubscribedEventTypes() {
80             return Collections.singleton(ItemStateEvent.TYPE);
81         }
82
83         @Override
84         public @Nullable EventFilter getEventFilter() {
85             return null;
86         }
87
88         @Override
89         public void receive(Event event) {
90             // Expecting only state updates in the tests
91             assertThat(event, is(instanceOf(ItemStateEvent.class)));
92             ItemStateEvent stateEvent = (ItemStateEvent) event;
93             logger.trace("Captured event: {} of type {}. Payload: {}", event,
94                     stateEvent.getItemState().getClass().getSimpleName(), event.getPayload());
95             stateUpdates.computeIfAbsent(stateEvent.getItemName(), (item) -> new ArrayList<>())
96                     .add(stateEvent.getItemState());
97         }
98     }
99
100     private final Logger logger = LoggerFactory.getLogger(AbstractModbusOSGiTest.class);
101
102     @Mock
103     protected @NonNullByDefault({}) ModbusManager mockedModbusManager;
104     protected @NonNullByDefault({}) ManagedThingProvider thingProvider;
105     protected @NonNullByDefault({}) ManagedItemProvider itemProvider;
106     protected @NonNullByDefault({}) ManagedItemChannelLinkProvider itemChannelLinkProvider;
107     protected @NonNullByDefault({}) ItemRegistry itemRegistry;
108     protected @NonNullByDefault({}) CoreItemFactory coreItemFactory;
109
110     private @NonNullByDefault({}) ModbusManager realModbusManager;
111     private Set<Item> addedItems = new HashSet<>();
112     private Set<Thing> addedThings = new HashSet<>();
113     private Set<ItemChannelLink> addedLinks = new HashSet<>();
114     private StateSubscriber stateSubscriber = new StateSubscriber();
115
116     @Mock
117     protected @NonNullByDefault({}) ModbusCommunicationInterface comms;
118
119     public AbstractModbusOSGiTest() {
120         super();
121     }
122
123     /**
124      * Before each test, configure mocked services
125      */
126     @Before
127     public void setUpAbstractModbusOSGiTest() {
128         logger.debug("setUpAbstractModbusOSGiTest BEGIN");
129         registerVolatileStorageService();
130         registerService(mockedModbusManager);
131         registerService(stateSubscriber);
132
133         swapModbusManagerToMocked();
134
135         thingProvider = getService(ThingProvider.class, ManagedThingProvider.class);
136         assertThat("Could not get ManagedThingProvider", thingProvider, is(notNullValue()));
137         itemProvider = getService(ItemProvider.class, ManagedItemProvider.class);
138         assertThat("Could not get ManagedItemProvider", itemProvider, is(notNullValue()));
139         itemChannelLinkProvider = getService(ItemChannelLinkProvider.class, ManagedItemChannelLinkProvider.class);
140         assertThat("Could not get ManagedItemChannelLinkProvider", itemChannelLinkProvider, is(notNullValue()));
141         itemRegistry = getService(ItemRegistry.class);
142         assertThat("Could not get ItemRegistry", itemRegistry, is(notNullValue()));
143
144         coreItemFactory = new CoreItemFactory();
145
146         // Clean slate for all tests
147         reset(mockedModbusManager);
148
149         stateSubscriber.stateUpdates.clear();
150         logger.debug("setUpAbstractModbusOSGiTest END");
151     }
152
153     @After
154     public void tearDownAbstractModbusOSGiTest() {
155         logger.debug("tearDownAbstractModbusOSGiTest BEGIN");
156         swapModbusManagerToReal();
157         for (Item item : addedItems) {
158             assertNotNull(itemProvider.remove(item.getName()));
159         }
160         for (Thing thing : addedThings) {
161             disposeThing(thing);
162         }
163         for (ItemChannelLink link : addedLinks) {
164             logger.debug("Unlinking {} <-> {}", link.getItemName(), link.getLinkedUID());
165             assertNotNull(itemChannelLinkProvider.remove(link.getUID()));
166         }
167         logger.debug("tearDownAbstractModbusOSGiTest END");
168     }
169
170     protected void addThing(Thing thing) {
171         assertThat(addedThings.contains(thing), not(equalTo(true)));
172         ThingHandler mockHandler = thing.getHandler();
173         if (mockHandler != null) {
174             // If there is a handler attached to fresh thing, it should be mocked (this pattern is used with some tests)
175             assertThat(Mockito.mockingDetails(thing.getHandler()).isMock(), is(equalTo(true)));
176         }
177
178         thingProvider.add(thing);
179         waitForAssert(() -> assertThat(thing.getHandler(), notNullValue()));
180         assertThat(thing.getConfiguration(), is(notNullValue()));
181         addedThings.add(thing);
182         if (mockHandler != null) {
183             // Re-attach mock handler
184             ThingHandler realHandlerInitedByCore = thing.getHandler();
185             assertNotNull(realHandlerInitedByCore);
186             assertNotSame(realHandlerInitedByCore, mockHandler);
187             realHandlerInitedByCore.dispose();
188             thing.setHandler(mockHandler);
189         }
190     }
191
192     protected void disposeThing(Thing thing) {
193         thingProvider.remove(thing.getUID());
194     }
195
196     protected void addItem(Item item) {
197         assertThat(addedItems.contains(item), not(equalTo(true)));
198         itemProvider.add(item);
199         addedItems.add(item);
200     }
201
202     protected void linkItem(String itemName, ChannelUID channelUID) {
203         logger.debug("Linking {} <-> {}", itemName, channelUID);
204         ItemChannelLink link = new ItemChannelLink(itemName, channelUID);
205         assertThat(addedLinks.contains(link), not(equalTo(true)));
206         itemChannelLinkProvider.add(link);
207         addedLinks.add(link);
208     }
209
210     protected List<State> getStateUpdates(String itemName) {
211         return stateSubscriber.stateUpdates.get(itemName);
212     }
213
214     protected void mockTransformation(String name, TransformationService service) {
215         Dictionary<String, Object> params = new Hashtable<>();
216         params.put("smarthome.transform", name);
217         registerService(service, params);
218     }
219
220     protected void mockCommsToModbusManager() {
221         assert comms != null;
222         doReturn(comms).when(mockedModbusManager).newModbusCommunicationInterface(any(), any());
223     }
224
225     protected void swapModbusManagerToMocked() {
226         assertNull(realModbusManager);
227         realModbusManager = getService(ModbusManager.class);
228         assertThat("Could not get ModbusManager", realModbusManager, is(notNullValue()));
229         assertThat("Could not get ModbusManagerImpl", realModbusManager.getClass().getSimpleName(),
230                 is(equalTo("ModbusManagerImpl")));
231         assertNotNull(realModbusManager);
232
233         ModbusHandlerFactory modbusHandlerFactory = getService(ThingHandlerFactory.class, ModbusHandlerFactory.class);
234         assertThat("Could not get ModbusHandlerFactory", modbusHandlerFactory, is(notNullValue()));
235         assertNotNull(modbusHandlerFactory);
236         modbusHandlerFactory.unsetModbusManager(realModbusManager);
237         modbusHandlerFactory.setModbusManager(mockedModbusManager);
238     }
239
240     protected void swapModbusManagerToReal() {
241         assertNotNull(realModbusManager);
242         ModbusHandlerFactory modbusHandlerFactory = getService(ThingHandlerFactory.class, ModbusHandlerFactory.class);
243         assertThat("Could not get ModbusHandlerFactory", modbusHandlerFactory, is(notNullValue()));
244         assertNotNull(modbusHandlerFactory);
245         modbusHandlerFactory.unsetModbusManager(mockedModbusManager);
246         modbusHandlerFactory.setModbusManager(realModbusManager);
247     }
248 }