2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.modbus.tests;
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.*;
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;
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;
67 * @author Sami Salonen - Initial contribution
70 public abstract class AbstractModbusOSGiTest extends JavaOSGiTest {
72 private static class StateSubscriber implements EventSubscriber {
74 private final Logger logger = LoggerFactory.getLogger(StateSubscriber.class);
76 public Map<String, List<State>> stateUpdates = new HashMap<>();
79 public Set<@NonNull String> getSubscribedEventTypes() {
80 return Collections.singleton(ItemStateEvent.TYPE);
84 public @Nullable EventFilter getEventFilter() {
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());
100 private final Logger logger = LoggerFactory.getLogger(AbstractModbusOSGiTest.class);
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;
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();
117 protected @NonNullByDefault({}) ModbusCommunicationInterface comms;
119 public AbstractModbusOSGiTest() {
124 * Before each test, configure mocked services
127 public void setUpAbstractModbusOSGiTest() {
128 logger.debug("setUpAbstractModbusOSGiTest BEGIN");
129 registerVolatileStorageService();
130 registerService(mockedModbusManager);
131 registerService(stateSubscriber);
133 swapModbusManagerToMocked();
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()));
144 coreItemFactory = new CoreItemFactory();
146 // Clean slate for all tests
147 reset(mockedModbusManager);
149 stateSubscriber.stateUpdates.clear();
150 logger.debug("setUpAbstractModbusOSGiTest END");
154 public void tearDownAbstractModbusOSGiTest() {
155 logger.debug("tearDownAbstractModbusOSGiTest BEGIN");
156 swapModbusManagerToReal();
157 for (Item item : addedItems) {
158 assertNotNull(itemProvider.remove(item.getName()));
160 for (Thing thing : addedThings) {
163 for (ItemChannelLink link : addedLinks) {
164 logger.debug("Unlinking {} <-> {}", link.getItemName(), link.getLinkedUID());
165 assertNotNull(itemChannelLinkProvider.remove(link.getUID()));
167 logger.debug("tearDownAbstractModbusOSGiTest END");
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)));
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);
192 protected void disposeThing(Thing thing) {
193 thingProvider.remove(thing.getUID());
196 protected void addItem(Item item) {
197 assertThat(addedItems.contains(item), not(equalTo(true)));
198 itemProvider.add(item);
199 addedItems.add(item);
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);
210 protected List<State> getStateUpdates(String itemName) {
211 return stateSubscriber.stateUpdates.get(itemName);
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);
220 protected void mockCommsToModbusManager() {
221 assert comms != null;
222 doReturn(comms).when(mockedModbusManager).newModbusCommunicationInterface(any(), any());
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);
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);
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);