[network] Adressing issue #11503 (#12316)

Signed-off-by: clinique <gael@lhopital.org>
pull/12348/head
Gaël L'hopital 2022-02-20 23:24:49 +01:00 committed by GitHub
parent 6ef311304f
commit cabcaa9698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 105 additions and 83 deletions

View File

@ -29,11 +29,11 @@ import org.openhab.binding.network.internal.utils.NetworkUtils.ArpPingUtilEnum;
@NonNullByDefault @NonNullByDefault
public class NetworkBindingConfiguration { public class NetworkBindingConfiguration {
public Boolean allowSystemPings = true; public boolean allowSystemPings = true;
public Boolean allowDHCPlisten = true; public boolean allowDHCPlisten = true;
public BigDecimal cacheDeviceStateTimeInMS = BigDecimal.valueOf(2000); public BigDecimal cacheDeviceStateTimeInMS = BigDecimal.valueOf(2000);
public String arpPingToolPath = "arping"; public String arpPingToolPath = "arping";
public @NonNullByDefault({}) ArpPingUtilEnum arpPingUtilMethod; public ArpPingUtilEnum arpPingUtilMethod = ArpPingUtilEnum.DISABLED;
// For backwards compatibility reasons, the default is to use the ping method execution time as latency value // For backwards compatibility reasons, the default is to use the ping method execution time as latency value
public boolean preferResponseTimeAsLatency = false; public boolean preferResponseTimeAsLatency = false;

View File

@ -12,11 +12,14 @@
*/ */
package org.openhab.binding.network.internal; package org.openhab.binding.network.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* Listener for binding configuration changes. * Listener for binding configuration changes.
* *
* @author Andreas Hirsch - Initial contribution * @author Andreas Hirsch - Initial contribution
*/ */
@NonNullByDefault
public interface NetworkBindingConfigurationListener { public interface NetworkBindingConfigurationListener {
void bindingConfigurationChanged(); void bindingConfigurationChanged();

View File

@ -57,10 +57,9 @@ public class PresenceDetection implements IPRequestReceivedCallback {
/// Configuration variables /// Configuration variables
private boolean useDHCPsniffing = false; private boolean useDHCPsniffing = false;
private String arpPingState = "Disabled";
private String ipPingState = "Disabled"; private String ipPingState = "Disabled";
protected String arpPingUtilPath = ""; protected String arpPingUtilPath = "";
protected ArpPingUtilEnum arpPingMethod = ArpPingUtilEnum.UNKNOWN_TOOL; protected ArpPingUtilEnum arpPingMethod = ArpPingUtilEnum.DISABLED;
protected @Nullable IpPingMethodEnum pingMethod = null; protected @Nullable IpPingMethodEnum pingMethod = null;
private boolean iosDevice; private boolean iosDevice;
private Set<Integer> tcpPorts = new HashSet<>(); private Set<Integer> tcpPorts = new HashSet<>();
@ -184,40 +183,13 @@ public class PresenceDetection implements IPRequestReceivedCallback {
* it will be disabled as well. * it will be disabled as well.
* *
* @param enable Enable or disable ARP ping * @param enable Enable or disable ARP ping
* @param arpPingUtilPath c * @param destinationAddress target ip address
*/ */
private void setUseArpPing(boolean enable, @Nullable InetAddress destinationAddress) { private void setUseArpPing(boolean enable, @Nullable InetAddress destinationAddress) {
if (!enable || arpPingUtilPath.isEmpty()) { if (!enable || arpPingUtilPath.isEmpty()) {
arpPingState = "Disabled"; arpPingMethod = ArpPingUtilEnum.DISABLED;
arpPingMethod = ArpPingUtilEnum.UNKNOWN_TOOL; } else if (!(destinationAddress instanceof Inet4Address)) {
return; arpPingMethod = ArpPingUtilEnum.DISABLED_INVALID_IP;
} else if (destinationAddress == null || !(destinationAddress instanceof Inet4Address)) {
arpPingState = "Destination is not a valid IPv4 address";
arpPingMethod = ArpPingUtilEnum.UNKNOWN_TOOL;
return;
}
switch (arpPingMethod) {
case UNKNOWN_TOOL: {
arpPingState = "Unknown arping tool";
break;
}
case THOMAS_HABERT_ARPING: {
arpPingState = "Arping tool by Thomas Habets";
break;
}
case THOMAS_HABERT_ARPING_WITHOUT_TIMEOUT: {
arpPingState = "Arping tool by Thomas Habets (old version)";
break;
}
case ELI_FULKERSON_ARP_PING_FOR_WINDOWS: {
arpPingState = "Eli Fulkerson ARPing tool for Windows";
break;
}
case IPUTILS_ARPING: {
arpPingState = "Ipuitls Arping";
break;
}
} }
} }
@ -234,7 +206,7 @@ public class PresenceDetection implements IPRequestReceivedCallback {
} }
public String getArpPingState() { public String getArpPingState() {
return arpPingState; return arpPingMethod.description;
} }
public String getIPPingState() { public String getIPPingState() {
@ -318,7 +290,7 @@ public class PresenceDetection implements IPRequestReceivedCallback {
if (pingMethod != null) { if (pingMethod != null) {
detectionChecks += 1; detectionChecks += 1;
} }
if (arpPingMethod != ArpPingUtilEnum.UNKNOWN_TOOL) { if (arpPingMethod.canProceed) {
interfaceNames = networkUtils.getInterfaceNames(); interfaceNames = networkUtils.getInterfaceNames();
detectionChecks += interfaceNames.size(); detectionChecks += interfaceNames.size();
} }

View File

@ -12,25 +12,37 @@
*/ */
package org.openhab.binding.network.internal; package org.openhab.binding.network.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/** /**
* The {@link SpeedTestConfiguration} is the class used to match the * The {@link SpeedTestConfiguration} is the class used to match the
* thing configuration. * thing configuration.
* *
* @author Gaël L'hopital - Initial contribution * @author Gaël L'hopital - Initial contribution
*/ */
@NonNullByDefault
public class SpeedTestConfiguration { public class SpeedTestConfiguration {
public Integer refreshInterval = 20; public int refreshInterval = 20;
public Integer initialDelay = 5; public int initialDelay = 5;
public Integer uploadSize = 1000000; public int uploadSize = 1000000;
public Integer maxTimeout = 3; public int maxTimeout = 3;
private String url; private @Nullable String url;
private String fileName; private @Nullable String fileName;
public String getUploadURL() { public @Nullable String getUploadURL() {
return url + (url.endsWith("/") ? "" : "/"); String localUrl = url;
if (localUrl != null) {
localUrl += localUrl.endsWith("/") ? "" : "/";
}
return localUrl;
} }
public String getDownloadURL() { public @Nullable String getDownloadURL() {
return getUploadURL() + fileName; String result = getUploadURL();
if (result != null && fileName != null) {
result += fileName;
}
return result;
} }
} }

View File

@ -13,13 +13,18 @@
package org.openhab.binding.network.internal; package org.openhab.binding.network.internal;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.net.NetUtil; import org.openhab.core.net.NetUtil;
@ -48,11 +53,8 @@ public class WakeOnLanPacketSender {
private final String macAddress; private final String macAddress;
@Nullable private final @Nullable String hostname;
private final String hostname; private final @Nullable Integer port;
@Nullable
private final Integer port;
private final Consumer<byte[]> magicPacketMacSender; private final Consumer<byte[]> magicPacketMacSender;
private final Consumer<byte[]> magicPacketIpSender; private final Consumer<byte[]> magicPacketIpSender;
@ -131,10 +133,10 @@ public class WakeOnLanPacketSender {
private void sendMagicPacketViaIp(byte[] magicPacket) { private void sendMagicPacketViaIp(byte[] magicPacket) {
try (DatagramSocket socket = new DatagramSocket()) { try (DatagramSocket socket = new DatagramSocket()) {
if (!StringUtils.isEmpty(this.hostname)) { if (hostname != null && !hostname.isBlank()) {
logger.debug("Sending Wake-on-LAN Packet via IP Address"); logger.debug("Sending Wake-on-LAN Packet via IP Address");
SocketAddress socketAddress = new InetSocketAddress(this.hostname, SocketAddress socketAddress = new InetSocketAddress(hostname,
Objects.requireNonNullElse(this.port, WOL_UDP_PORT)); Objects.requireNonNullElse(port, WOL_UDP_PORT));
sendMagicPacketToIp(magicPacket, socket, socketAddress); sendMagicPacketToIp(magicPacket, socket, socketAddress);
} else { } else {
throw new IllegalStateException("Hostname is not set!"); throw new IllegalStateException("Hostname is not set!");

View File

@ -70,7 +70,7 @@ public class DHCPPacketListenerServer extends Thread {
Byte dhcpMessageType = request.getDHCPMessageType(); Byte dhcpMessageType = request.getDHCPMessageType();
if (dhcpMessageType != DHCPPacket.DHCPREQUEST) { if (dhcpMessageType == null || dhcpMessageType != DHCPPacket.DHCPREQUEST) {
return; // skipping non DHCPREQUEST message types return; // skipping non DHCPREQUEST message types
} }

View File

@ -69,7 +69,8 @@ public class SpeedTestHandler extends BaseThingHandler implements ISpeedTestList
} }
private synchronized void startSpeedTest() { private synchronized void startSpeedTest() {
if (speedTestSocket == null) { String url = configuration.getDownloadURL();
if (speedTestSocket == null && url != null) {
logger.debug("Network speedtest started"); logger.debug("Network speedtest started");
final SpeedTestSocket socket = new SpeedTestSocket(1500); final SpeedTestSocket socket = new SpeedTestSocket(1500);
speedTestSocket = socket; speedTestSocket = socket;
@ -78,7 +79,7 @@ public class SpeedTestHandler extends BaseThingHandler implements ISpeedTestList
updateState(CHANNEL_TEST_START, new DateTimeType()); updateState(CHANNEL_TEST_START, new DateTimeType());
updateState(CHANNEL_TEST_END, UnDefType.NULL); updateState(CHANNEL_TEST_END, UnDefType.NULL);
updateProgress(new QuantityType<>(0, Units.PERCENT)); updateProgress(new QuantityType<>(0, Units.PERCENT));
socket.startDownload(configuration.getDownloadURL()); socket.startDownload(url);
} else { } else {
logger.info("A speedtest is already in progress, will retry on next refresh"); logger.info("A speedtest is already in progress, will retry on next refresh");
} }
@ -109,7 +110,8 @@ public class SpeedTestHandler extends BaseThingHandler implements ISpeedTestList
switch (testReport.getSpeedTestMode()) { switch (testReport.getSpeedTestMode()) {
case DOWNLOAD: case DOWNLOAD:
updateState(CHANNEL_RATE_DOWN, quantity); updateState(CHANNEL_RATE_DOWN, quantity);
if (speedTestSocket != null && configuration != null) { String url = configuration.getUploadURL();
if (speedTestSocket != null && url != null) {
speedTestSocket.startUpload(configuration.getUploadURL(), configuration.uploadSize); speedTestSocket.startUpload(configuration.getUploadURL(), configuration.uploadSize);
} }
break; break;

View File

@ -16,6 +16,7 @@ import java.util.Optional;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -24,9 +25,10 @@ import org.slf4j.LoggerFactory;
* *
* @author Andreas Hirsch - Initial contribution * @author Andreas Hirsch - Initial contribution
*/ */
@NonNullByDefault
public class LatencyParser { public class LatencyParser {
private static Pattern LATENCY_PATTERN = Pattern.compile(".*time=(.*) ?ms"); private static final Pattern LATENCY_PATTERN = Pattern.compile(".*time=(.*) ?ms");
private final Logger logger = LoggerFactory.getLogger(LatencyParser.class); private final Logger logger = LoggerFactory.getLogger(LatencyParser.class);
// This is how the input looks like on Mac and Linux: // This is how the input looks like on Mac and Linux:

View File

@ -203,19 +203,19 @@ public class NetworkUtils {
public ArpPingUtilEnum determineNativeARPpingMethod(String arpToolPath) { public ArpPingUtilEnum determineNativeARPpingMethod(String arpToolPath) {
String result = ExecUtil.executeCommandLineAndWaitResponse(Duration.ofMillis(100), arpToolPath, "--help"); String result = ExecUtil.executeCommandLineAndWaitResponse(Duration.ofMillis(100), arpToolPath, "--help");
if (result == null || result.isBlank()) { if (result == null || result.isBlank()) {
return ArpPingUtilEnum.UNKNOWN_TOOL; return ArpPingUtilEnum.DISABLED_UNKNOWN_TOOL;
} else if (result.contains("Thomas Habets")) { } else if (result.contains("Thomas Habets")) {
if (result.matches("(?s)(.*)w sec Specify a timeout(.*)")) { if (result.matches("(?s)(.*)w sec Specify a timeout(.*)")) {
return ArpPingUtilEnum.THOMAS_HABERT_ARPING; return ArpPingUtilEnum.THOMAS_HABERT_ARPING;
} else { } else {
return ArpPingUtilEnum.THOMAS_HABERT_ARPING_WITHOUT_TIMEOUT; return ArpPingUtilEnum.THOMAS_HABERT_ARPING_WITHOUT_TIMEOUT;
} }
} else if (result.contains("-w timeout")) { } else if (result.contains("-w timeout") || result.contains("-w <timeout>")) {
return ArpPingUtilEnum.IPUTILS_ARPING; return ArpPingUtilEnum.IPUTILS_ARPING;
} else if (result.contains("Usage: arp-ping.exe")) { } else if (result.contains("Usage: arp-ping.exe")) {
return ArpPingUtilEnum.ELI_FULKERSON_ARP_PING_FOR_WINDOWS; return ArpPingUtilEnum.ELI_FULKERSON_ARP_PING_FOR_WINDOWS;
} }
return ArpPingUtilEnum.UNKNOWN_TOOL; return ArpPingUtilEnum.DISABLED_UNKNOWN_TOOL;
} }
public enum IpPingMethodEnum { public enum IpPingMethodEnum {
@ -292,11 +292,21 @@ public class NetworkUtils {
} }
public enum ArpPingUtilEnum { public enum ArpPingUtilEnum {
UNKNOWN_TOOL, DISABLED("Disabled", false),
IPUTILS_ARPING, DISABLED_INVALID_IP("Destination is not a valid IPv4 address", false),
THOMAS_HABERT_ARPING, DISABLED_UNKNOWN_TOOL("Unknown arping tool", false),
THOMAS_HABERT_ARPING_WITHOUT_TIMEOUT, IPUTILS_ARPING("Iputils Arping", true),
ELI_FULKERSON_ARP_PING_FOR_WINDOWS THOMAS_HABERT_ARPING("Arping tool by Thomas Habets", true),
THOMAS_HABERT_ARPING_WITHOUT_TIMEOUT("Arping tool by Thomas Habets (old version)", true),
ELI_FULKERSON_ARP_PING_FOR_WINDOWS("Eli Fulkerson ARPing tool for Windows", true);
public final String description;
public final boolean canProceed;
ArpPingUtilEnum(String description, boolean canProceed) {
this.description = description;
this.canProceed = canProceed;
}
} }
/** /**
@ -317,7 +327,7 @@ public class NetworkUtils {
String interfaceName, String ipV4address, int timeoutInMS) throws IOException, InterruptedException { String interfaceName, String ipV4address, int timeoutInMS) throws IOException, InterruptedException {
double execStartTimeInMS = System.currentTimeMillis(); double execStartTimeInMS = System.currentTimeMillis();
if (arpUtilPath == null || arpingTool == null || arpingTool == ArpPingUtilEnum.UNKNOWN_TOOL) { if (arpUtilPath == null || arpingTool == null || !arpingTool.canProceed) {
return Optional.empty(); return Optional.empty();
} }
Process proc; Process proc;

View File

@ -14,15 +14,18 @@ package org.openhab.binding.network.internal.utils;
import java.util.Optional; import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* Information about the ping result. * Information about the ping result.
* *
* @author Andreas Hirsch - Initial contribution * @author Andreas Hirsch - Initial contribution
*/ */
@NonNullByDefault
public class PingResult { public class PingResult {
private boolean success; private boolean success;
private Double responseTimeInMS; private Optional<Double> responseTimeInMS = Optional.empty();
private double executionTimeInMS; private double executionTimeInMS;
/** /**
@ -46,14 +49,14 @@ public class PingResult {
* by ping command is not available. * by ping command is not available.
*/ */
public Optional<Double> getResponseTimeInMS() { public Optional<Double> getResponseTimeInMS() {
return responseTimeInMS == null ? Optional.empty() : Optional.of(responseTimeInMS); return responseTimeInMS;
} }
/** /**
* @param responseTimeInMS Response time in ms which was returned by the ping command. * @param responseTimeInMS Response time in ms which was returned by the ping command.
*/ */
public void setResponseTimeInMS(double responseTimeInMS) { public void setResponseTimeInMS(double responseTimeInMS) {
this.responseTimeInMS = responseTimeInMS; this.responseTimeInMS = Optional.of(responseTimeInMS);
} }
@Override @Override

View File

@ -207,16 +207,19 @@
<description>States whether a device is online or offline</description> <description>States whether a device is online or offline</description>
<state readOnly="true"></state> <state readOnly="true"></state>
</channel-type> </channel-type>
<channel-type id="latency"> <channel-type id="latency">
<item-type>Number:Time</item-type> <item-type>Number:Time</item-type>
<label>Latency</label> <label>Latency</label>
<description>States the latency time</description> <description>States the latency time</description>
<state readOnly="true" pattern="%d %unit%"></state> <state readOnly="true" pattern="%d %unit%"></state>
</channel-type> </channel-type>
<channel-type id="lastseen"> <channel-type id="lastseen">
<item-type>DateTime</item-type> <item-type>DateTime</item-type>
<label>Last Seen</label> <label>Last Seen</label>
<description>States the last seen date/time</description> <description>States the last seen date/time</description>
<category>time</category>
<state readOnly="true"></state> <state readOnly="true"></state>
</channel-type> </channel-type>
</thing:thing-descriptions> </thing:thing-descriptions>

View File

@ -178,8 +178,8 @@ public class PresenceDetectionTest {
@Test @Test
public void reuseValueTests() throws InterruptedException, IOException { public void reuseValueTests() throws InterruptedException, IOException {
final long START_TIME = 1000L; final long startTime = 1000L;
when(subject.cache.getCurrentNanoTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(START_TIME)); when(subject.cache.getCurrentNanoTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(startTime));
// The PresenceDetectionValue.getLowestLatency() should return the smallest latency // The PresenceDetectionValue.getLowestLatency() should return the smallest latency
PresenceDetectionValue v = subject.updateReachableValue(PresenceDetectionType.ICMP_PING, 20); PresenceDetectionValue v = subject.updateReachableValue(PresenceDetectionType.ICMP_PING, 20);
@ -188,19 +188,19 @@ public class PresenceDetectionTest {
assertThat(v.getLowestLatency(), is(19.0)); assertThat(v.getLowestLatency(), is(19.0));
// Advance in time but not expire the cache (1ms left) // Advance in time but not expire the cache (1ms left)
final long ALMOST_EXPIRE = START_TIME + CACHETIME - 1; final long almostExpire = startTime + CACHETIME - 1;
when(subject.cache.getCurrentNanoTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(ALMOST_EXPIRE)); when(subject.cache.getCurrentNanoTime()).thenReturn(TimeUnit.MILLISECONDS.toNanos(almostExpire));
// Updating should reset the expire timer of the cache // Updating should reset the expire timer of the cache
v2 = subject.updateReachableValue(PresenceDetectionType.ICMP_PING, 28); v2 = subject.updateReachableValue(PresenceDetectionType.ICMP_PING, 28);
assertEquals(v, v2); assertEquals(v, v2);
assertThat(v2.getLowestLatency(), is(19.0)); assertThat(v2.getLowestLatency(), is(19.0));
assertThat(ExpiringCacheHelper.expireTime(subject.cache), assertThat(ExpiringCacheHelper.expireTime(subject.cache),
is(TimeUnit.MILLISECONDS.toNanos(ALMOST_EXPIRE + CACHETIME))); is(TimeUnit.MILLISECONDS.toNanos(almostExpire + CACHETIME)));
// Cache expire. A new PresenceDetectionValue instance will be returned // Cache expire. A new PresenceDetectionValue instance will be returned
when(subject.cache.getCurrentNanoTime()) when(subject.cache.getCurrentNanoTime())
.thenReturn(TimeUnit.MILLISECONDS.toNanos(ALMOST_EXPIRE + CACHETIME + CACHETIME + 1)); .thenReturn(TimeUnit.MILLISECONDS.toNanos(almostExpire + CACHETIME + CACHETIME + 1));
v2 = subject.updateReachableValue(PresenceDetectionType.ICMP_PING, 25); v2 = subject.updateReachableValue(PresenceDetectionType.ICMP_PING, 25);
assertNotEquals(v, v2); assertNotEquals(v, v2);
assertThat(v2.getLowestLatency(), is(25.0)); assertThat(v2.getLowestLatency(), is(25.0));

View File

@ -22,6 +22,8 @@ import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.Timeout;
@ -33,6 +35,7 @@ import org.openhab.core.util.HexUtils;
* @author Wouter Born - Initial contribution * @author Wouter Born - Initial contribution
*/ */
@Timeout(value = 10) @Timeout(value = 10)
@NonNullByDefault
public class WakeOnLanPacketSenderTest { public class WakeOnLanPacketSenderTest {
private void assertValidMagicPacket(byte[] macBytes, byte[] packet) { private void assertValidMagicPacket(byte[] macBytes, byte[] packet) {
@ -102,7 +105,8 @@ public class WakeOnLanPacketSenderTest {
assertThrows(IllegalStateException.class, () -> sendWOLTest(null, 4444)); assertThrows(IllegalStateException.class, () -> sendWOLTest(null, 4444));
} }
private void sendWOLTest(String hostname, Integer port) throws InterruptedException, IOException { private void sendWOLTest(@Nullable String hostname, @Nullable Integer port)
throws InterruptedException, IOException {
DatagramSocket socket = new DatagramSocket(4444); DatagramSocket socket = new DatagramSocket(4444);
byte[] buf = new byte[256]; byte[] buf = new byte[256];

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.SocketException; import java.net.SocketException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.openhab.binding.network.internal.dhcp.DHCPPacket.BadPacketException; import org.openhab.binding.network.internal.dhcp.DHCPPacket.BadPacketException;
@ -30,6 +31,7 @@ import org.openhab.binding.network.internal.dhcp.DHCPPacket.BadPacketException;
* *
* @author David Graeff - Initial contribution * @author David Graeff - Initial contribution
*/ */
@NonNullByDefault
public class DHCPTest { public class DHCPTest {
@Test @Test
public void testService() throws SocketException { public void testService() throws SocketException {

View File

@ -17,6 +17,7 @@ import static org.mockito.Mockito.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.openhab.binding.network.internal.toberemoved.cache.ExpiringCacheAsync.ExpiringCacheUpdate; import org.openhab.binding.network.internal.toberemoved.cache.ExpiringCacheAsync.ExpiringCacheUpdate;
@ -26,6 +27,7 @@ import org.openhab.binding.network.internal.toberemoved.cache.ExpiringCacheAsync
* *
* @author David Graeff - Initial contribution * @author David Graeff - Initial contribution
*/ */
@NonNullByDefault
public class ExpiringCacheAsyncTest { public class ExpiringCacheAsyncTest {
@Test @Test
public void testConstructorWrongCacheTime() { public void testConstructorWrongCacheTime() {

View File

@ -12,11 +12,14 @@
*/ */
package org.openhab.binding.network.internal.toberemoved.cache; package org.openhab.binding.network.internal.toberemoved.cache;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* Helper class to make the package private cacheUpdater field available for tests. * Helper class to make the package private cacheUpdater field available for tests.
* *
* @author David Graeff * @author David Graeff - Initial Contribution
*/ */
@NonNullByDefault
public class ExpiringCacheHelper { public class ExpiringCacheHelper {
public static long expireTime(@SuppressWarnings("rawtypes") ExpiringCacheAsync cache) { public static long expireTime(@SuppressWarnings("rawtypes") ExpiringCacheAsync cache) {
return cache.expiresAt; return cache.expiresAt;

View File

@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.*;
import java.util.Optional; import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
@ -23,6 +24,7 @@ import org.junit.jupiter.api.Test;
* *
* @author Andreas Hirsch - Initial contribution * @author Andreas Hirsch - Initial contribution
*/ */
@NonNullByDefault
public class LatencyParserTest { public class LatencyParserTest {
@Test @Test