added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
27
itests/org.openhab.binding.modbus.tests/.classpath
Normal file
27
itests/org.openhab.binding.modbus.tests/.classpath
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
itests/org.openhab.binding.modbus.tests/.project
Normal file
23
itests/org.openhab.binding.modbus.tests/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.modbus.tests</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
itests/org.openhab.binding.modbus.tests/NOTICE
Normal file
13
itests/org.openhab.binding.modbus.tests/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab2-addons
|
||||
74
itests/org.openhab.binding.modbus.tests/itest.bndrun
Normal file
74
itests/org.openhab.binding.modbus.tests/itest.bndrun
Normal file
@@ -0,0 +1,74 @@
|
||||
-include: ../itest-common.bndrun
|
||||
|
||||
Bundle-SymbolicName: ${project.artifactId}
|
||||
Fragment-Host: org.openhab.binding.modbus
|
||||
|
||||
-runrequires: \
|
||||
bnd.identity;id='org.openhab.binding.modbus.tests',\
|
||||
bnd.identity;id='org.openhab.core.binding.xml',\
|
||||
bnd.identity;id='org.openhab.core.thing.xml',\
|
||||
bnd.identity;id='ch.qos.logback.core',\
|
||||
bnd.identity;id='ch.qos.logback.classic'
|
||||
|
||||
# 1) We would like to use the "volatile" storage only, drop other storage
|
||||
# 2) We use logback (see logback.xml), drop others logging implementation
|
||||
# to avoid conflicts
|
||||
-runblacklist: \
|
||||
bnd.identity;id='org.openhab.core.storage.json',\
|
||||
bnd.identity;id='org.openhab.core.storage.mapdb',\
|
||||
bnd.identity;id='slf4j.simple',\
|
||||
bnd.identity;id='org.apache.log4j'
|
||||
|
||||
-runproperties: \
|
||||
logback.configurationFile=file:${.}/logback.xml
|
||||
|
||||
#
|
||||
# done
|
||||
#
|
||||
-runbundles: \
|
||||
javax.measure.unit-api;version='[1.0.0,1.0.1)',\
|
||||
org.apache.commons.io;version='[2.2.0,2.2.1)',\
|
||||
org.apache.commons.lang;version='[2.6.0,2.6.1)',\
|
||||
org.apache.felix.configadmin;version='[1.9.8,1.9.9)',\
|
||||
org.apache.felix.scr;version='[2.1.10,2.1.11)',\
|
||||
org.eclipse.equinox.event;version='[1.4.300,1.4.301)',\
|
||||
org.osgi.service.event;version='[1.4.0,1.4.1)',\
|
||||
osgi.enroute.hamcrest.wrapper;version='[1.3.0,1.3.1)',\
|
||||
osgi.enroute.junit.wrapper;version='[4.12.0,4.12.1)',\
|
||||
org.openhab.core;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.config.core;version='[2.5.0,2.5.1)',\
|
||||
org.objenesis;version='[2.6.0,2.6.1)',\
|
||||
org.openhab.core.config.discovery;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.io.console;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.thing;version='[2.5.0,2.5.1)',\
|
||||
slf4j.api;version='[1.7.25,1.7.26)',\
|
||||
com.google.gson;version='[2.8.2,2.8.3)',\
|
||||
org.apache.servicemix.specs.activation-api-1.1;version='[2.9.0,2.9.1)',\
|
||||
org.apache.servicemix.specs.jaxb-api-2.2;version='[2.9.0,2.9.1)',\
|
||||
org.apache.servicemix.specs.stax-api-1.2;version='[2.9.0,2.9.1)',\
|
||||
tec.uom.lib.uom-lib-common;version='[1.0.3,1.0.4)',\
|
||||
tec.uom.se;version='[1.0.10,1.0.11)',\
|
||||
org.apache.servicemix.bundles.jaxb-impl;version='[2.2.11,2.2.12)',\
|
||||
net.bytebuddy.byte-buddy;version='[1.9.10,1.9.11)',\
|
||||
net.bytebuddy.byte-buddy-agent;version='[1.9.10,1.9.11)',\
|
||||
org.mockito.mockito-core;version='[3.1.0,3.1.1)',\
|
||||
com.neuronrobotics.nrjavaserial;version='[3.15.0,3.15.1)',\
|
||||
org.openhab.core.transform;version='[2.5.0,2.5.1)',\
|
||||
org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
|
||||
org.eclipse.jetty.http;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.io;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.security;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.server;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.servlet;version='[9.4.20,9.4.21)',\
|
||||
org.eclipse.jetty.util;version='[9.4.20,9.4.21)',\
|
||||
org.openhab.core.test;version='[2.5.0,2.5.1)',\
|
||||
org.apache.servicemix.bundles.xstream;version='[1.4.7,1.4.8)',\
|
||||
org.openhab.core.binding.xml;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.config.xml;version='[2.5.0,2.5.1)',\
|
||||
org.openhab.core.thing.xml;version='[2.5.0,2.5.1)',\
|
||||
ch.qos.logback.core;version='[1.2.3,1.2.4)',\
|
||||
ch.qos.logback.classic;version='[1.2.3,1.2.4)',\
|
||||
org.openhab.binding.modbus;version='[2.5.9,2.5.10)',\
|
||||
org.openhab.binding.modbus.tests;version='[2.5.9,2.5.10)',\
|
||||
org.openhab.io.transport.modbus;version='[2.5.9,2.5.10)',\
|
||||
org.apache.commons.commons-pool2;version='[2.8.1,2.8.2)'
|
||||
19
itests/org.openhab.binding.modbus.tests/logback.xml
Normal file
19
itests/org.openhab.binding.modbus.tests/logback.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<configuration debug="true">
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.openhab.binding.modbus" level="trace" />
|
||||
<logger name="org.openhab.binding.modbus.tests" level="trace" />
|
||||
<logger name="org.openhab.io.transport.modbus" level="trace" />
|
||||
<logger name="net.wimpi.modbus" level="trace" />
|
||||
<logger name="org.openhab.core.internal.items.ItemUpdater" level="trace" />
|
||||
<logger name="org.openhab.core.internal.items.ItemStateConverterImpl" level="debug" />
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
30
itests/org.openhab.binding.modbus.tests/pom.xml
Normal file
30
itests/org.openhab.binding.modbus.tests/pom.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.itests</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.itests</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.modbus.tests</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Integration Tests :: Modbus Binding Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.modbus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.io.transport.modbus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.itests</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.itests</artifactId>
|
||||
<version>2.5.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.modbus.tests</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Integration Tests :: Modbus Binding Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.modbus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.io.transport.modbus</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.modbus.tests;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.events.Event;
|
||||
import org.openhab.core.events.EventFilter;
|
||||
import org.openhab.core.events.EventSubscriber;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemProvider;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.items.ManagedItemProvider;
|
||||
import org.openhab.core.items.events.ItemStateEvent;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ManagedThingProvider;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingProvider;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.openhab.core.thing.link.ItemChannelLink;
|
||||
import org.openhab.core.thing.link.ItemChannelLinkProvider;
|
||||
import org.openhab.core.thing.link.ManagedItemChannelLinkProvider;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.test.java.JavaOSGiTest;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.openhab.binding.modbus.internal.ModbusHandlerFactory;
|
||||
import org.openhab.io.transport.modbus.ModbusCommunicationInterface;
|
||||
import org.openhab.io.transport.modbus.ModbusManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Sami Salonen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractModbusOSGiTest extends JavaOSGiTest {
|
||||
|
||||
private static class StateSubscriber implements EventSubscriber {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(StateSubscriber.class);
|
||||
|
||||
public Map<String, List<State>> stateUpdates = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Set<@NonNull String> getSubscribedEventTypes() {
|
||||
return Collections.singleton(ItemStateEvent.TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable EventFilter getEventFilter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Event event) {
|
||||
// Expecting only state updates in the tests
|
||||
assertThat(event, is(instanceOf(ItemStateEvent.class)));
|
||||
ItemStateEvent stateEvent = (ItemStateEvent) event;
|
||||
logger.trace("Captured event: {} of type {}. Payload: {}", event,
|
||||
stateEvent.getItemState().getClass().getSimpleName(), event.getPayload());
|
||||
stateUpdates.computeIfAbsent(stateEvent.getItemName(), (item) -> new ArrayList<>())
|
||||
.add(stateEvent.getItemState());
|
||||
}
|
||||
}
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(AbstractModbusOSGiTest.class);
|
||||
|
||||
@Mock
|
||||
protected @NonNullByDefault({}) ModbusManager mockedModbusManager;
|
||||
protected @NonNullByDefault({}) ManagedThingProvider thingProvider;
|
||||
protected @NonNullByDefault({}) ManagedItemProvider itemProvider;
|
||||
protected @NonNullByDefault({}) ManagedItemChannelLinkProvider itemChannelLinkProvider;
|
||||
protected @NonNullByDefault({}) ItemRegistry itemRegistry;
|
||||
protected @NonNullByDefault({}) CoreItemFactory coreItemFactory;
|
||||
|
||||
private @NonNullByDefault({}) ModbusManager realModbusManager;
|
||||
private Set<Item> addedItems = new HashSet<>();
|
||||
private Set<Thing> addedThings = new HashSet<>();
|
||||
private Set<ItemChannelLink> addedLinks = new HashSet<>();
|
||||
private StateSubscriber stateSubscriber = new StateSubscriber();
|
||||
|
||||
@Mock
|
||||
protected @NonNullByDefault({}) ModbusCommunicationInterface comms;
|
||||
|
||||
public AbstractModbusOSGiTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Before each test, configure mocked services
|
||||
*/
|
||||
@Before
|
||||
public void setUpAbstractModbusOSGiTest() {
|
||||
logger.debug("setUpAbstractModbusOSGiTest BEGIN");
|
||||
registerVolatileStorageService();
|
||||
registerService(mockedModbusManager);
|
||||
registerService(stateSubscriber);
|
||||
|
||||
swapModbusManagerToMocked();
|
||||
|
||||
thingProvider = getService(ThingProvider.class, ManagedThingProvider.class);
|
||||
assertThat("Could not get ManagedThingProvider", thingProvider, is(notNullValue()));
|
||||
itemProvider = getService(ItemProvider.class, ManagedItemProvider.class);
|
||||
assertThat("Could not get ManagedItemProvider", itemProvider, is(notNullValue()));
|
||||
itemChannelLinkProvider = getService(ItemChannelLinkProvider.class, ManagedItemChannelLinkProvider.class);
|
||||
assertThat("Could not get ManagedItemChannelLinkProvider", itemChannelLinkProvider, is(notNullValue()));
|
||||
itemRegistry = getService(ItemRegistry.class);
|
||||
assertThat("Could not get ItemRegistry", itemRegistry, is(notNullValue()));
|
||||
|
||||
coreItemFactory = new CoreItemFactory();
|
||||
|
||||
// Clean slate for all tests
|
||||
reset(mockedModbusManager);
|
||||
|
||||
stateSubscriber.stateUpdates.clear();
|
||||
logger.debug("setUpAbstractModbusOSGiTest END");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDownAbstractModbusOSGiTest() {
|
||||
logger.debug("tearDownAbstractModbusOSGiTest BEGIN");
|
||||
swapModbusManagerToReal();
|
||||
for (Item item : addedItems) {
|
||||
assertNotNull(itemProvider.remove(item.getName()));
|
||||
}
|
||||
for (Thing thing : addedThings) {
|
||||
disposeThing(thing);
|
||||
}
|
||||
for (ItemChannelLink link : addedLinks) {
|
||||
logger.debug("Unlinking {} <-> {}", link.getItemName(), link.getLinkedUID());
|
||||
assertNotNull(itemChannelLinkProvider.remove(link.getUID()));
|
||||
}
|
||||
logger.debug("tearDownAbstractModbusOSGiTest END");
|
||||
}
|
||||
|
||||
protected void addThing(Thing thing) {
|
||||
assertThat(addedThings.contains(thing), not(equalTo(true)));
|
||||
ThingHandler mockHandler = thing.getHandler();
|
||||
if (mockHandler != null) {
|
||||
// If there is a handler attached to fresh thing, it should be mocked (this pattern is used with some tests)
|
||||
assertThat(Mockito.mockingDetails(thing.getHandler()).isMock(), is(equalTo(true)));
|
||||
}
|
||||
|
||||
thingProvider.add(thing);
|
||||
waitForAssert(() -> assertThat(thing.getHandler(), notNullValue()));
|
||||
assertThat(thing.getConfiguration(), is(notNullValue()));
|
||||
addedThings.add(thing);
|
||||
if (mockHandler != null) {
|
||||
// Re-attach mock handler
|
||||
ThingHandler realHandlerInitedByCore = thing.getHandler();
|
||||
assertNotNull(realHandlerInitedByCore);
|
||||
assertNotSame(realHandlerInitedByCore, mockHandler);
|
||||
realHandlerInitedByCore.dispose();
|
||||
thing.setHandler(mockHandler);
|
||||
}
|
||||
}
|
||||
|
||||
protected void disposeThing(Thing thing) {
|
||||
thingProvider.remove(thing.getUID());
|
||||
}
|
||||
|
||||
protected void addItem(Item item) {
|
||||
assertThat(addedItems.contains(item), not(equalTo(true)));
|
||||
itemProvider.add(item);
|
||||
addedItems.add(item);
|
||||
}
|
||||
|
||||
protected void linkItem(String itemName, ChannelUID channelUID) {
|
||||
logger.debug("Linking {} <-> {}", itemName, channelUID);
|
||||
ItemChannelLink link = new ItemChannelLink(itemName, channelUID);
|
||||
assertThat(addedLinks.contains(link), not(equalTo(true)));
|
||||
itemChannelLinkProvider.add(link);
|
||||
addedLinks.add(link);
|
||||
}
|
||||
|
||||
protected List<State> getStateUpdates(String itemName) {
|
||||
return stateSubscriber.stateUpdates.get(itemName);
|
||||
}
|
||||
|
||||
protected void mockTransformation(String name, TransformationService service) {
|
||||
Dictionary<String, Object> params = new Hashtable<>();
|
||||
params.put("smarthome.transform", name);
|
||||
registerService(service, params);
|
||||
}
|
||||
|
||||
protected void mockCommsToModbusManager() {
|
||||
assert comms != null;
|
||||
doReturn(comms).when(mockedModbusManager).newModbusCommunicationInterface(any(), any());
|
||||
}
|
||||
|
||||
protected void swapModbusManagerToMocked() {
|
||||
assertNull(realModbusManager);
|
||||
realModbusManager = getService(ModbusManager.class);
|
||||
assertThat("Could not get ModbusManager", realModbusManager, is(notNullValue()));
|
||||
assertThat("Could not get ModbusManagerImpl", realModbusManager.getClass().getSimpleName(),
|
||||
is(equalTo("ModbusManagerImpl")));
|
||||
assertNotNull(realModbusManager);
|
||||
|
||||
ModbusHandlerFactory modbusHandlerFactory = getService(ThingHandlerFactory.class, ModbusHandlerFactory.class);
|
||||
assertThat("Could not get ModbusHandlerFactory", modbusHandlerFactory, is(notNullValue()));
|
||||
assertNotNull(modbusHandlerFactory);
|
||||
modbusHandlerFactory.unsetModbusManager(realModbusManager);
|
||||
modbusHandlerFactory.setModbusManager(mockedModbusManager);
|
||||
}
|
||||
|
||||
protected void swapModbusManagerToReal() {
|
||||
assertNotNull(realModbusManager);
|
||||
ModbusHandlerFactory modbusHandlerFactory = getService(ThingHandlerFactory.class, ModbusHandlerFactory.class);
|
||||
assertThat("Could not get ModbusHandlerFactory", modbusHandlerFactory, is(notNullValue()));
|
||||
assertNotNull(modbusHandlerFactory);
|
||||
modbusHandlerFactory.unsetModbusManager(mockedModbusManager);
|
||||
modbusHandlerFactory.setModbusManager(realModbusManager);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,855 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.modbus.tests;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.hamcrest.MockitoHamcrest.argThat;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
import org.openhab.core.thing.binding.builder.BridgeBuilder;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.openhab.binding.modbus.handler.ModbusPollerThingHandler;
|
||||
import org.openhab.binding.modbus.internal.ModbusBindingConstantsInternal;
|
||||
import org.openhab.binding.modbus.internal.handler.ModbusDataThingHandler;
|
||||
import org.openhab.io.transport.modbus.AsyncModbusFailure;
|
||||
import org.openhab.io.transport.modbus.AsyncModbusReadResult;
|
||||
import org.openhab.io.transport.modbus.BitArray;
|
||||
import org.openhab.io.transport.modbus.ModbusConstants;
|
||||
import org.openhab.io.transport.modbus.ModbusFailureCallback;
|
||||
import org.openhab.io.transport.modbus.ModbusReadCallback;
|
||||
import org.openhab.io.transport.modbus.ModbusReadFunctionCode;
|
||||
import org.openhab.io.transport.modbus.ModbusReadRequestBlueprint;
|
||||
import org.openhab.io.transport.modbus.ModbusRegisterArray;
|
||||
import org.openhab.io.transport.modbus.PollTask;
|
||||
import org.openhab.io.transport.modbus.endpoint.ModbusSlaveEndpoint;
|
||||
import org.openhab.io.transport.modbus.endpoint.ModbusTCPSlaveEndpoint;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Sami Salonen - Initial contribution
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ModbusPollerThingHandlerTest extends AbstractModbusOSGiTest {
|
||||
|
||||
private static final String HOST = "thisishost";
|
||||
private static final int PORT = 44;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ModbusPollerThingHandlerTest.class);
|
||||
|
||||
private Bridge endpoint;
|
||||
private Bridge poller;
|
||||
|
||||
@Mock
|
||||
private ThingHandlerCallback thingCallback;
|
||||
|
||||
public static BridgeBuilder createTcpThingBuilder(String id) {
|
||||
return BridgeBuilder
|
||||
.create(ModbusBindingConstantsInternal.THING_TYPE_MODBUS_TCP,
|
||||
new ThingUID(ModbusBindingConstantsInternal.THING_TYPE_MODBUS_TCP, id))
|
||||
.withLabel("label for " + id);
|
||||
}
|
||||
|
||||
public static BridgeBuilder createPollerThingBuilder(String id) {
|
||||
return BridgeBuilder
|
||||
.create(ModbusBindingConstantsInternal.THING_TYPE_MODBUS_POLLER,
|
||||
new ThingUID(ModbusBindingConstantsInternal.THING_TYPE_MODBUS_POLLER, id))
|
||||
.withLabel("label for " + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that basic poller <-> endpoint interaction has taken place (on poller init)
|
||||
*/
|
||||
private void verifyEndpointBasicInitInteraction() {
|
||||
verify(mockedModbusManager).newModbusCommunicationInterface(any(), any());
|
||||
}
|
||||
|
||||
public ModbusReadCallback getPollerCallback(ModbusPollerThingHandler handler)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Field callbackField = ModbusPollerThingHandler.class.getDeclaredField("callbackDelegator");
|
||||
callbackField.setAccessible(true);
|
||||
return (ModbusReadCallback) callbackField.get(handler);
|
||||
}
|
||||
|
||||
public ModbusFailureCallback<ModbusReadRequestBlueprint> getPollerFailureCallback(ModbusPollerThingHandler handler)
|
||||
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
|
||||
Field callbackField = ModbusPollerThingHandler.class.getDeclaredField("callbackDelegator");
|
||||
callbackField.setAccessible(true);
|
||||
return (ModbusFailureCallback<ModbusReadRequestBlueprint>) callbackField.get(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Before each test, setup TCP endpoint thing, configure mocked item registry
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
mockCommsToModbusManager();
|
||||
Configuration tcpConfig = new Configuration();
|
||||
tcpConfig.put("host", HOST);
|
||||
tcpConfig.put("port", PORT);
|
||||
tcpConfig.put("id", 9);
|
||||
endpoint = createTcpThingBuilder("tcpendpoint").withConfiguration(tcpConfig).build();
|
||||
addThing(endpoint);
|
||||
|
||||
assertThat(endpoint.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (endpoint != null) {
|
||||
thingProvider.remove(endpoint.getUID());
|
||||
}
|
||||
if (poller != null) {
|
||||
thingProvider.remove(poller.getUID());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeNonPolling()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L); // 0 -> non polling
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 9);
|
||||
pollerConfig.put("type", ModbusBindingConstantsInternal.READ_TYPE_HOLDING_REGISTER);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
|
||||
logger.info("Poller created, registering to registry...");
|
||||
addThing(poller);
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
logger.info("Poller registered");
|
||||
|
||||
verifyEndpointBasicInitInteraction();
|
||||
// polling is _not_ setup
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
}
|
||||
|
||||
private void testPollerLengthCheck(String type, int length, boolean expectedOnline) {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", length);
|
||||
pollerConfig.put("type", type);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
|
||||
addThing(poller);
|
||||
assertThat(poller.getStatus(), is(equalTo(expectedOnline ? ThingStatus.ONLINE : ThingStatus.OFFLINE)));
|
||||
if (!expectedOnline) {
|
||||
assertThat(poller.getStatusInfo().getStatusDetail(), is(equalTo(ThingStatusDetail.CONFIGURATION_ERROR)));
|
||||
}
|
||||
|
||||
verifyEndpointBasicInitInteraction();
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerWithMaxRegisters()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_HOLDING_REGISTER,
|
||||
ModbusConstants.MAX_REGISTERS_READ_COUNT, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerLengthOutOfBoundsWithRegisters()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_HOLDING_REGISTER,
|
||||
ModbusConstants.MAX_REGISTERS_READ_COUNT + 1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerWithMaxInputRegisters()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_INPUT_REGISTER,
|
||||
ModbusConstants.MAX_REGISTERS_READ_COUNT, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerLengthOutOfBoundsWithInputRegisters()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_INPUT_REGISTER,
|
||||
ModbusConstants.MAX_REGISTERS_READ_COUNT + 1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerWithMaxCoils()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_COIL, ModbusConstants.MAX_BITS_READ_COUNT, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerLengthOutOfBoundsWithCoils()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_COIL, ModbusConstants.MAX_BITS_READ_COUNT + 1,
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerWithMaxDiscreteInput()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_DISCRETE_INPUT,
|
||||
ModbusConstants.MAX_BITS_READ_COUNT, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollerLengthOutOfBoundsWithDiscreteInput()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollerLengthCheck(ModbusBindingConstantsInternal.READ_TYPE_DISCRETE_INPUT,
|
||||
ModbusConstants.MAX_BITS_READ_COUNT + 1, false);
|
||||
}
|
||||
|
||||
public void testPollingGeneric(String type, ModbusReadFunctionCode expectedFunctionCode)
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
PollTask pollTask = Mockito.mock(PollTask.class);
|
||||
doReturn(pollTask).when(comms).registerRegularPoll(notNull(), eq(150l), eq(0L), notNull(), notNull());
|
||||
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", type);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
|
||||
assertThat(poller.getStatusInfo().toString(), poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
verifyEndpointBasicInitInteraction();
|
||||
verify(mockedModbusManager).newModbusCommunicationInterface(argThat(new TypeSafeMatcher<ModbusSlaveEndpoint>() {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("correct endpoint (");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(ModbusSlaveEndpoint endpoint) {
|
||||
return checkEndpoint(endpoint);
|
||||
}
|
||||
}), any());
|
||||
|
||||
verify(comms).registerRegularPoll(argThat(new TypeSafeMatcher<ModbusReadRequestBlueprint>() {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("correct request");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(ModbusReadRequestBlueprint request) {
|
||||
return checkRequest(request, expectedFunctionCode);
|
||||
}
|
||||
}), eq(150l), eq(0L), notNull(), notNull());
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
private boolean checkEndpoint(ModbusSlaveEndpoint endpointParam) {
|
||||
return endpointParam.equals(new ModbusTCPSlaveEndpoint(HOST, PORT));
|
||||
}
|
||||
|
||||
private boolean checkRequest(ModbusReadRequestBlueprint request, ModbusReadFunctionCode functionCode) {
|
||||
return request.getDataLength() == 13 && request.getFunctionCode() == functionCode
|
||||
&& request.getProtocolID() == 0 && request.getReference() == 5 && request.getUnitID() == 9;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializePollingWithCoils()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollingGeneric("coil", ModbusReadFunctionCode.READ_COILS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializePollingWithDiscrete()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollingGeneric("discrete", ModbusReadFunctionCode.READ_INPUT_DISCRETES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializePollingWithInputRegisters()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollingGeneric("input", ModbusReadFunctionCode.READ_INPUT_REGISTERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializePollingWithHoldingRegisters()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
testPollingGeneric("holding", ModbusReadFunctionCode.READ_MULTIPLE_REGISTERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPollUnregistrationOnDispose()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
PollTask pollTask = Mockito.mock(PollTask.class);
|
||||
doReturn(pollTask).when(comms).registerRegularPoll(notNull(), eq(150l), eq(0L), notNull(), notNull());
|
||||
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
// verify registration
|
||||
final AtomicReference<ModbusReadCallback> callbackRef = new AtomicReference<>();
|
||||
verify(mockedModbusManager).newModbusCommunicationInterface(argThat(new TypeSafeMatcher<ModbusSlaveEndpoint>() {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("correct endpoint");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(ModbusSlaveEndpoint endpoint) {
|
||||
return checkEndpoint(endpoint);
|
||||
}
|
||||
}), any());
|
||||
verify(comms).registerRegularPoll(argThat(new TypeSafeMatcher<ModbusReadRequestBlueprint>() {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(ModbusReadRequestBlueprint request) {
|
||||
return checkRequest(request, ModbusReadFunctionCode.READ_COILS);
|
||||
}
|
||||
}), eq(150l), eq(0L), argThat(new TypeSafeMatcher<ModbusReadCallback>() {
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(ModbusReadCallback callback) {
|
||||
callbackRef.set(callback);
|
||||
return true;
|
||||
}
|
||||
}), notNull());
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
|
||||
// reset call counts for easy assertions
|
||||
reset(mockedModbusManager);
|
||||
|
||||
// remove the thing
|
||||
disposeThing(poller);
|
||||
|
||||
// 1) should first unregister poll task
|
||||
verify(comms).unregisterRegularPoll(eq(pollTask));
|
||||
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeWithNoBridge()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.OFFLINE)));
|
||||
assertThat(poller.getStatusInfo().getStatusDetail(), is(equalTo(ThingStatusDetail.BRIDGE_OFFLINE)));
|
||||
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeWithOfflineBridge()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
|
||||
endpoint.setStatusInfo(new ThingStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, ""));
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.OFFLINE)));
|
||||
assertThat(poller.getStatusInfo().getStatusDetail(), is(equalTo(ThingStatusDetail.BRIDGE_OFFLINE)));
|
||||
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegistersPassedToChildDataThings()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
PollTask pollTask = Mockito.mock(PollTask.class);
|
||||
doReturn(pollTask).when(comms).registerRegularPoll(notNull(), eq(150l), eq(0L), notNull(), notNull());
|
||||
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ArgumentCaptor<ModbusReadCallback> callbackCapturer = ArgumentCaptor.forClass(ModbusReadCallback.class);
|
||||
verify(comms).registerRegularPoll(notNull(), eq(150l), eq(0L), callbackCapturer.capture(), notNull());
|
||||
ModbusReadCallback readCallback = callbackCapturer.getValue();
|
||||
|
||||
assertNotNull(readCallback);
|
||||
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
ModbusRegisterArray registers = Mockito.mock(ModbusRegisterArray.class);
|
||||
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
ModbusDataThingHandler child2 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
|
||||
AsyncModbusReadResult result = new AsyncModbusReadResult(request, registers);
|
||||
|
||||
// has one data child
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child1).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
|
||||
reset(child1);
|
||||
|
||||
// two children (one child initialized)
|
||||
thingHandler.childHandlerInitialized(child2, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child1).onReadResult(result);
|
||||
verify(child2).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
|
||||
reset(child1);
|
||||
reset(child2);
|
||||
|
||||
// one child disposed
|
||||
thingHandler.childHandlerDisposed(child1, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child2).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBitsPassedToChildDataThings()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
PollTask pollTask = Mockito.mock(PollTask.class);
|
||||
doReturn(pollTask).when(comms).registerRegularPoll(notNull(), eq(150l), eq(0L), notNull(), notNull());
|
||||
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ArgumentCaptor<ModbusReadCallback> callbackCapturer = ArgumentCaptor.forClass(ModbusReadCallback.class);
|
||||
verify(comms).registerRegularPoll(any(), eq(150l), eq(0L), callbackCapturer.capture(), notNull());
|
||||
ModbusReadCallback readCallback = callbackCapturer.getValue();
|
||||
|
||||
assertNotNull(readCallback);
|
||||
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
BitArray bits = Mockito.mock(BitArray.class);
|
||||
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
ModbusDataThingHandler child2 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
|
||||
AsyncModbusReadResult result = new AsyncModbusReadResult(request, bits);
|
||||
|
||||
// has one data child
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child1).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
|
||||
reset(child1);
|
||||
|
||||
// two children (one child initialized)
|
||||
thingHandler.childHandlerInitialized(child2, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child1).onReadResult(result);
|
||||
verify(child2).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
|
||||
reset(child1);
|
||||
reset(child2);
|
||||
|
||||
// one child disposed
|
||||
thingHandler.childHandlerDisposed(child1, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child2).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorPassedToChildDataThings()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
PollTask pollTask = Mockito.mock(PollTask.class);
|
||||
doReturn(pollTask).when(comms).registerRegularPoll(notNull(), eq(150l), eq(0L), notNull(), notNull());
|
||||
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 150L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
final ArgumentCaptor<ModbusFailureCallback<ModbusReadRequestBlueprint>> callbackCapturer = ArgumentCaptor
|
||||
.forClass((Class) ModbusFailureCallback.class);
|
||||
verify(comms).registerRegularPoll(any(), eq(150l), eq(0L), notNull(), callbackCapturer.capture());
|
||||
ModbusFailureCallback<ModbusReadRequestBlueprint> readCallback = callbackCapturer.getValue();
|
||||
|
||||
assertNotNull(readCallback);
|
||||
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
Exception error = Mockito.mock(Exception.class);
|
||||
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
ModbusDataThingHandler child2 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
|
||||
AsyncModbusFailure<ModbusReadRequestBlueprint> result = new AsyncModbusFailure<ModbusReadRequestBlueprint>(
|
||||
request, error);
|
||||
|
||||
// has one data child
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child1).handleReadError(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
|
||||
reset(child1);
|
||||
|
||||
// two children (one child initialized)
|
||||
thingHandler.childHandlerInitialized(child2, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child1).handleReadError(result);
|
||||
verify(child2).handleReadError(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
|
||||
reset(child1);
|
||||
reset(child2);
|
||||
|
||||
// one child disposed
|
||||
thingHandler.childHandlerDisposed(child1, Mockito.mock(Thing.class));
|
||||
readCallback.handle(result);
|
||||
verify(child2).handleReadError(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
verifyNoMoreInteractions(child2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefresh()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
thingHandler.refresh();
|
||||
verify(comms).submitOneTimePoll(any(), any(), any());
|
||||
}
|
||||
|
||||
/**
|
||||
* When there's no recently received data, refresh() will re-use that instead
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws NoSuchFieldException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
@Test
|
||||
public void testRefreshWithPreviousData()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
pollerConfig.put("cacheMillis", 10000L);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
|
||||
// data is received
|
||||
ModbusReadCallback pollerReadCallback = getPollerCallback(thingHandler);
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
ModbusRegisterArray registers = Mockito.mock(ModbusRegisterArray.class);
|
||||
AsyncModbusReadResult result = new AsyncModbusReadResult(request, registers);
|
||||
pollerReadCallback.handle(result);
|
||||
|
||||
// data child receives the data
|
||||
verify(child1).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
reset(child1);
|
||||
|
||||
// call refresh
|
||||
// cache is still valid, we should not have real data poll this time
|
||||
thingHandler.refresh();
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
|
||||
// data child receives the cached data
|
||||
verify(child1).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
}
|
||||
|
||||
/**
|
||||
* When there's no recently received data, refresh() will re-use that instead
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws NoSuchFieldException
|
||||
* @throws SecurityException
|
||||
*/
|
||||
@Test
|
||||
public void testRefreshWithPreviousDataCacheDisabled()
|
||||
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
pollerConfig.put("cacheMillis", 0L);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
|
||||
// data is received
|
||||
ModbusReadCallback pollerReadCallback = getPollerCallback(thingHandler);
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
ModbusRegisterArray registers = Mockito.mock(ModbusRegisterArray.class);
|
||||
AsyncModbusReadResult result = new AsyncModbusReadResult(request, registers);
|
||||
|
||||
pollerReadCallback.handle(result);
|
||||
|
||||
// data child receives the data
|
||||
verify(child1).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
reset(child1);
|
||||
|
||||
// call refresh
|
||||
// caching disabled, should poll from manager
|
||||
thingHandler.refresh();
|
||||
verify(comms).submitOneTimePoll(any(), any(), any());
|
||||
verifyNoMoreInteractions(mockedModbusManager);
|
||||
|
||||
// data child receives the cached data
|
||||
verifyNoMoreInteractions(child1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing again caching, such that most recently received data is propagated to children
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
* @throws NoSuchFieldException
|
||||
* @throws SecurityException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testRefreshWithPreviousData2() throws IllegalArgumentException, IllegalAccessException,
|
||||
NoSuchFieldException, SecurityException, InterruptedException {
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
pollerConfig.put("cacheMillis", 10000L);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
|
||||
// data is received
|
||||
ModbusReadCallback pollerReadCallback = getPollerCallback(thingHandler);
|
||||
ModbusFailureCallback<ModbusReadRequestBlueprint> failureCallback = getPollerFailureCallback(thingHandler);
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
ModbusReadRequestBlueprint request2 = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
ModbusRegisterArray registers = Mockito.mock(ModbusRegisterArray.class);
|
||||
Exception error = Mockito.mock(Exception.class);
|
||||
AsyncModbusReadResult registersResult = new AsyncModbusReadResult(request, registers);
|
||||
AsyncModbusFailure<ModbusReadRequestBlueprint> errorResult = new AsyncModbusFailure<ModbusReadRequestBlueprint>(
|
||||
request2, error);
|
||||
|
||||
pollerReadCallback.handle(registersResult);
|
||||
|
||||
// data child should receive the data
|
||||
verify(child1).onReadResult(registersResult);
|
||||
verifyNoMoreInteractions(child1);
|
||||
reset(child1);
|
||||
|
||||
// Sleep to have time between the data
|
||||
Thread.sleep(5L);
|
||||
|
||||
// error is received
|
||||
failureCallback.handle(errorResult);
|
||||
|
||||
// data child should receive the error
|
||||
verify(child1).handleReadError(errorResult);
|
||||
verifyNoMoreInteractions(child1);
|
||||
reset(child1);
|
||||
|
||||
// call refresh, should return latest data (that is, error)
|
||||
// cache is still valid, we should not have real data poll this time
|
||||
thingHandler.refresh();
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
|
||||
// data child receives the cached error
|
||||
verify(child1).handleReadError(errorResult);
|
||||
verifyNoMoreInteractions(child1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshWithOldPreviousData() throws IllegalArgumentException, IllegalAccessException,
|
||||
NoSuchFieldException, SecurityException, InterruptedException {
|
||||
|
||||
Configuration pollerConfig = new Configuration();
|
||||
pollerConfig.put("refresh", 0L);
|
||||
pollerConfig.put("start", 5);
|
||||
pollerConfig.put("length", 13);
|
||||
pollerConfig.put("type", "coil");
|
||||
pollerConfig.put("cacheMillis", 10L);
|
||||
poller = createPollerThingBuilder("poller").withConfiguration(pollerConfig).withBridge(endpoint.getUID())
|
||||
.build();
|
||||
addThing(poller);
|
||||
verifyEndpointBasicInitInteraction();
|
||||
|
||||
ModbusPollerThingHandler thingHandler = (ModbusPollerThingHandler) poller.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
ModbusDataThingHandler child1 = Mockito.mock(ModbusDataThingHandler.class);
|
||||
thingHandler.childHandlerInitialized(child1, Mockito.mock(Thing.class));
|
||||
|
||||
assertThat(poller.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
|
||||
// data is received
|
||||
ModbusReadCallback pollerReadCallback = getPollerCallback(thingHandler);
|
||||
ModbusReadRequestBlueprint request = Mockito.mock(ModbusReadRequestBlueprint.class);
|
||||
ModbusRegisterArray registers = Mockito.mock(ModbusRegisterArray.class);
|
||||
AsyncModbusReadResult result = new AsyncModbusReadResult(request, registers);
|
||||
|
||||
pollerReadCallback.handle(result);
|
||||
|
||||
// data child should receive the data
|
||||
verify(child1).onReadResult(result);
|
||||
verifyNoMoreInteractions(child1);
|
||||
reset(child1);
|
||||
|
||||
// Sleep to ensure cache expiry
|
||||
Thread.sleep(15L);
|
||||
|
||||
// call refresh. Since cache expired, will poll for more
|
||||
verify(comms, never()).submitOneTimePoll(any(), any(), any());
|
||||
thingHandler.refresh();
|
||||
verify(comms).submitOneTimePoll(any(), any(), any());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.modbus.tests;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.binding.builder.BridgeBuilder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.openhab.binding.modbus.handler.EndpointNotInitializedException;
|
||||
import org.openhab.binding.modbus.internal.ModbusBindingConstantsInternal;
|
||||
import org.openhab.binding.modbus.internal.handler.ModbusTcpThingHandler;
|
||||
import org.openhab.io.transport.modbus.endpoint.EndpointPoolConfiguration;
|
||||
import org.openhab.io.transport.modbus.endpoint.ModbusSlaveEndpoint;
|
||||
import org.openhab.io.transport.modbus.endpoint.ModbusTCPSlaveEndpoint;
|
||||
|
||||
/**
|
||||
* @author Sami Salonen - Initial contribution
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ModbusTcpThingHandlerTest extends AbstractModbusOSGiTest {
|
||||
|
||||
private static BridgeBuilder createTcpThingBuilder(String id) {
|
||||
return BridgeBuilder.create(ModbusBindingConstantsInternal.THING_TYPE_MODBUS_TCP,
|
||||
new ThingUID(ModbusBindingConstantsInternal.THING_TYPE_MODBUS_TCP, id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeAndSlaveEndpoint() throws EndpointNotInitializedException {
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 44);
|
||||
thingConfig.put("id", 9);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 1);
|
||||
thingConfig.put("timeBetweenReconnectMillis", 2);
|
||||
thingConfig.put("connectMaxTries", 3);
|
||||
thingConfig.put("reconnectAfterMillis", 4);
|
||||
thingConfig.put("connectTimeoutMillis", 5);
|
||||
|
||||
EndpointPoolConfiguration expectedPoolConfiguration = new EndpointPoolConfiguration();
|
||||
expectedPoolConfiguration.setConnectMaxTries(3);
|
||||
expectedPoolConfiguration.setConnectTimeoutMillis(5);
|
||||
expectedPoolConfiguration.setInterConnectDelayMillis(2);
|
||||
expectedPoolConfiguration.setInterTransactionDelayMillis(1);
|
||||
expectedPoolConfiguration.setReconnectAfterMillis(4);
|
||||
|
||||
Bridge thing = createTcpThingBuilder("tcpendpoint").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ModbusTcpThingHandler thingHandler = (ModbusTcpThingHandler) thing.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
ModbusSlaveEndpoint slaveEndpoint = thingHandler.getEndpoint();
|
||||
assertThat(slaveEndpoint, is(equalTo(new ModbusTCPSlaveEndpoint("thisishost", 44))));
|
||||
assertThat(thingHandler.getSlaveId(), is(9));
|
||||
|
||||
InOrder orderedVerify = Mockito.inOrder(mockedModbusManager);
|
||||
ModbusSlaveEndpoint endpoint = thingHandler.getEndpoint();
|
||||
Objects.requireNonNull(endpoint);
|
||||
orderedVerify.verify(mockedModbusManager).newModbusCommunicationInterface(endpoint, expectedPoolConfiguration);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoDifferentEndpointWithDifferentParameters() {
|
||||
// thing1
|
||||
{
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 44);
|
||||
thingConfig.put("connectMaxTries", 1);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 1);
|
||||
|
||||
final Bridge thing = createTcpThingBuilder("tcpendpoint").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ModbusTcpThingHandler thingHandler = (ModbusTcpThingHandler) thing.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
}
|
||||
{
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 45);
|
||||
thingConfig.put("connectMaxTries", 1);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 100);
|
||||
|
||||
final Bridge thing = createTcpThingBuilder("tcpendpoint2").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
// Different endpoint (port 45), so should be OK even though timeBetweenTransactionsMillis is different
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ModbusTcpThingHandler thingHandler = (ModbusTcpThingHandler) thing.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoIdenticalEndpointWithDifferentParameters() {
|
||||
// Real implementation needed to validate this behaviour
|
||||
swapModbusManagerToReal();
|
||||
// thing1
|
||||
{
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 44);
|
||||
thingConfig.put("connectMaxTries", 1);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 1);
|
||||
|
||||
final Bridge thing = createTcpThingBuilder("tcpendpoint").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ModbusTcpThingHandler thingHandler = (ModbusTcpThingHandler) thing.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
}
|
||||
{
|
||||
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 44);
|
||||
thingConfig.put("connectMaxTries", 1);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 100);
|
||||
|
||||
final Bridge thing = createTcpThingBuilder("tcpendpoint2").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.OFFLINE)));
|
||||
assertThat(thing.getStatusInfo().getStatusDetail(), is(equalTo(ThingStatusDetail.CONFIGURATION_ERROR)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoIdenticalEndpointWithSameParameters() {
|
||||
// Real implementation needed to validate this behaviour
|
||||
swapModbusManagerToReal();
|
||||
// thing1
|
||||
{
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 44);
|
||||
thingConfig.put("connectMaxTries", 1);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 1);
|
||||
|
||||
final Bridge thing = createTcpThingBuilder("tcpendpoint").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
|
||||
ModbusTcpThingHandler thingHandler = (ModbusTcpThingHandler) thing.getHandler();
|
||||
assertNotNull(thingHandler);
|
||||
}
|
||||
{
|
||||
Configuration thingConfig = new Configuration();
|
||||
thingConfig.put("host", "thisishost");
|
||||
thingConfig.put("port", 44);
|
||||
thingConfig.put("connectMaxTries", 1);
|
||||
thingConfig.put("timeBetweenTransactionsMillis", 1);
|
||||
thingConfig.put("connectTimeoutMillis", 10000); // default
|
||||
|
||||
final Bridge thing = createTcpThingBuilder("tcpendpoint2").withConfiguration(thingConfig).build();
|
||||
addThing(thing);
|
||||
// Same endpoint and same parameters -> should not affect this thing
|
||||
assertThat(thing.getStatus(), is(equalTo(ThingStatus.ONLINE)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user