diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index c323df200a..8d0f0f2af0 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -38,6 +38,8 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.http.HttpStatus; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.TestPropertySource; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; @@ -84,8 +86,8 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import org.thingsboard.server.transport.lwm2m.server.client.ResourceUpdateResult; import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2mUplinkMsgHandler; import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler; +import org.thingsboard.server.utils.PortFinder; -import java.net.ServerSocket; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -140,13 +142,27 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte private LwM2mClientContext clientContextTest; // Lwm2m Server - public static final int port = 5685; - public static final int securityPort = 5686; - public static final int portBs = 5687; - public static final int securityPortBs = 5688; + public static final String LWM2M_HOST = "localhost"; + public static final int LWM2M_PORT = PortFinder.findAvailableUdpPort(); // 5685 + public static final int LWM2MS_PORT = PortFinder.findAvailableUdpPort(); //5686 + + public static final String LWM2M_BOOTSTRAP_HOST = "localhost"; + public static final int LWM2M_BOOTSTRAP_PORT = PortFinder.findAvailableUdpPort(); // 5687 + public static final int LWM2MS_BOOTSTRAP_PORT = PortFinder.findAvailableUdpPort(); // 5688 + + @DynamicPropertySource + static void props(DynamicPropertyRegistry registry) { + log.warn("transport.lwm2m.server.bind_port = {}", LWM2M_PORT); + registry.add("transport.lwm2m.server.bind_port", () -> LWM2M_PORT); + log.warn("transport.lwm2m.server.security.bind_port = {}", LWM2MS_PORT); + registry.add("transport.lwm2m.server.security.bind_port", () -> LWM2MS_PORT); + + log.warn("transport.lwm2m.bootstrap.bind_port = {}", LWM2M_BOOTSTRAP_PORT); + registry.add("transport.lwm2m.bootstrap.bind_port", () -> LWM2M_BOOTSTRAP_PORT); + log.warn("transport.lwm2m.bootstrap.security.bind_port = {}", LWM2MS_BOOTSTRAP_PORT); + registry.add("transport.lwm2m.bootstrap.security.bind_port", () -> LWM2MS_BOOTSTRAP_PORT); + } - public static final String host = "localhost"; - public static final String hostBs = "localhost"; public static final Integer shortServerId = 123; public static final Integer shortServerIdBs0 = 0; public static final int serverId = 1; @@ -154,10 +170,10 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte public static final String COAP = "coap://"; public static final String COAPS = "coaps://"; - public static final String URI = COAP + host + ":" + port; - public static final String SECURE_URI = COAPS + host + ":" + securityPort; - public static final String URI_BS = COAP + hostBs + ":" + portBs; - public static final String SECURE_URI_BS = COAPS + hostBs + ":" + securityPortBs; + public static final String URI = COAP + LWM2M_HOST + ":" + LWM2M_PORT; + public static final String SECURE_URI = COAPS + LWM2M_HOST + ":" + LWM2MS_PORT; + public static final String URI_BS = COAP + LWM2M_BOOTSTRAP_HOST + ":" + LWM2M_BOOTSTRAP_PORT; + public static final String SECURE_URI_BS = COAPS + LWM2M_BOOTSTRAP_HOST + ":" + LWM2MS_BOOTSTRAP_PORT; public static final Security SECURITY_NO_SEC = noSec(URI, shortServerId); protected final String OBSERVE_ATTRIBUTES_WITHOUT_PARAMS = @@ -572,12 +588,11 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte this.clientDestroy(false); lwM2MTestClient = new LwM2MTestClient(this.executor, endpoint, resources); - try (ServerSocket socket = new ServerSocket(0)) { - int clientPort = socket.getLocalPort(); - lwM2MTestClient.init(security, securityBs, clientPort, isRpc, - this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, - clientDtlsCidLength, queueMode, supportFormatOnly_SenMLJSON_SenMLCBOR, value3_0_9); - } + int clientPort = PortFinder.findAvailableUdpPort(); + //automatic client port assignment + lwM2MTestClient.init(security, securityBs, 0 /* clientPort */, isRpc, + this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest, + clientDtlsCidLength, queueMode, supportFormatOnly_SenMLJSON_SenMLCBOR, value3_0_9); lwM2MTestClient.setDeviceIdStr(deviceIdStr); } @@ -715,8 +730,8 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte bootstrapServerCredential.setServerPublicKey(""); bootstrapServerCredential.setShortServerId(isBootstrap ? shortServerIdBs0 : shortServerId); bootstrapServerCredential.setBootstrapServerIs(isBootstrap); - bootstrapServerCredential.setHost(isBootstrap ? hostBs : host); - bootstrapServerCredential.setPort(isBootstrap ? portBs : port); + bootstrapServerCredential.setHost(isBootstrap ? LWM2M_BOOTSTRAP_HOST : LWM2M_HOST); + bootstrapServerCredential.setPort(isBootstrap ? LWM2M_BOOTSTRAP_PORT : LWM2M_PORT); return bootstrapServerCredential; } @@ -731,11 +746,15 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte return credentials; } - protected void awaitObserveReadAll(int cntObserve, String deviceIdStr) throws Exception { + awaitObserveReadAll(cntObserve, deviceIdStr, ""); + } + + protected void awaitObserveReadAll(int cntObserve, String deviceIdStr, String assertionAlias) throws Exception { try { await("ObserveReadAll: countObserve " + cntObserve) - .atMost(40, TimeUnit.SECONDS) + .alias(assertionAlias) + .atMost(TIMEOUT, TimeUnit.SECONDS) .until(() -> cntObserve == getCntObserveAll(deviceIdStr)); } catch (ConditionTimeoutException e) { int current = getCntObserveAll(deviceIdStr); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java index e2d57077a3..979a2b8c96 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java @@ -33,7 +33,6 @@ import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicInteger; import static org.thingsboard.server.dao.service.OtaPackageServiceTest.TARGET_FW_VERSION; import static org.thingsboard.server.dao.service.OtaPackageServiceTest.TITLE; @@ -137,6 +136,7 @@ public class FwLwM2MDevice extends BaseInstanceEnabler implements Destroyable { @Override public void destroy() { scheduler.shutdownNow(); + this.leshanClient = null; } private void startDownloading() { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java index 37b30dca97..908c2d52d3 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -78,6 +78,7 @@ import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import static org.awaitility.Awaitility.await; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_CONNECTION_ID_LENGTH; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY; import static org.eclipse.leshan.core.LwM2mId.ACCESS_CONTROL; @@ -88,6 +89,7 @@ import static org.eclipse.leshan.core.LwM2mId.SECURITY; import static org.eclipse.leshan.core.LwM2mId.SERVER; import static org.eclipse.leshan.core.LwM2mId.SOFTWARE_MANAGEMENT; import static org.eclipse.leshan.core.node.codec.DefaultLwM2mEncoder.getDefaultPathEncoder; +import static org.thingsboard.server.transport.AbstractTransportIntegrationTest.DEFAULT_WAIT_TIMEOUT_SECONDS; import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.serverId; import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.serverIdBs; import static org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest.shortServerId; @@ -118,6 +120,7 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INST import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.TEMPERATURE_SENSOR; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.lwm2mClientResources; import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.setDtlsConnectorConfigCidLength; +import static org.thingsboard.server.utils.PortFinder.isUDPPortAvailable; @Slf4j @@ -140,12 +143,14 @@ public class LwM2MTestClient { private LwM2mClientContext clientContext; private LwM2mTemperatureSensor lwM2mTemperatureSensor12; private String deviceIdStr; + private int clientPort; - public void init(Security security, Security securityBs, int port, boolean isRpc, + public void init(Security security, Security securityBs, int clientPort, boolean isRpc, LwM2mUplinkMsgHandler defaultLwM2mUplinkMsgHandler, LwM2mClientContext clientContext, Integer cIdLength, boolean queueMode, boolean supportFormatOnly_SenMLJSON_SenMLCBOR, Integer value3_0_9) throws InvalidDDFFileException, IOException { Assert.assertNull("client already initialized", leshanClient); + this.clientPort = clientPort; this.defaultLwM2mUplinkMsgHandlerTest = defaultLwM2mUplinkMsgHandler; this.clientContext = clientContext; @@ -266,7 +271,7 @@ public class LwM2MTestClient { // Set Californium Configuration endpointsBuilder.setConfiguration(clientCoapConfig); - endpointsBuilder.setClientAddress(new InetSocketAddress(port).getAddress()); + endpointsBuilder.setClientAddress(new InetSocketAddress(clientPort).getAddress()); // creates EndpointsProvider @@ -461,10 +466,19 @@ public class LwM2MTestClient { if (lwM2MTemperatureSensor != null) { lwM2MTemperatureSensor.destroy(); } + if (lwM2mTemperatureSensor12 != null) { + lwM2mTemperatureSensor12.destroy(); + } } public void start(boolean isStartLw) { if (leshanClient != null) { + if (clientPort > 0) { + log.error("Await UDP clientPort {} to be available before leshanClient.start()", clientPort); + await("Await UDP clientPort " + clientPort + " to be available before leshanClient.start()") + .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) + .until(() -> isUDPPortAvailable(clientPort)); + } leshanClient.start(); if (isStartLw) { this.awaitClientAfterStartConnectLw(); @@ -477,6 +491,12 @@ public class LwM2MTestClient { public void stop(boolean deregister) { if (leshanClient != null) { leshanClient.stop(deregister); + if (clientPort > 0) { + log.error("Await UDP clientPort {} to disconnect after leshanClient.stop(deregister)", clientPort); + await("Await client UDP port " + clientPort + " to disconnect after leshanClient.stop(deregister)") + .atMost(DEFAULT_WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS) + .until(() -> isUDPPortAvailable(clientPort)); + } } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mTemperatureSensor.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mTemperatureSensor.java index 64978af44d..bca551e989 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mTemperatureSensor.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2mTemperatureSensor.java @@ -169,6 +169,7 @@ public class LwM2mTemperatureSensor extends BaseInstanceEnabler implements Destr @Override public void destroy() { + this.leshanClient = null; } private void sendCollected() { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index d6e9e2d9b0..4adc398fa8 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -359,8 +359,8 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M } bootstrapServerCredential.setShortServerId(isBootstrap ? shortServerIdBs0 : shortServerId); bootstrapServerCredential.setBootstrapServerIs(isBootstrap); - bootstrapServerCredential.setHost(isBootstrap ? hostBs : host); - bootstrapServerCredential.setPort(isBootstrap ? securityPortBs : securityPort); + bootstrapServerCredential.setHost(isBootstrap ? LWM2M_BOOTSTRAP_HOST : LWM2M_HOST); + bootstrapServerCredential.setPort(isBootstrap ? LWM2MS_BOOTSTRAP_PORT : LWM2MS_PORT); return bootstrapServerCredential; } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index 420ebd16b2..29beace952 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -136,7 +136,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes ON_REGISTRATION_SUCCESS, true); - awaitObserveReadAll(1, lwm2mDevice.getId().getId().toString()); + awaitObserveReadAll(1, lwm2mDevice.getId().getId().toString(), "before client stops for the first time"); lwM2MTestClient.stop(true); DeviceProfile foundDeviceProfile = doGet("/api/deviceProfile/" + lwm2mDevice.getDeviceProfileId().getId().toString(), DeviceProfile.class); @@ -146,7 +146,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes Assert.assertNotNull(lwm2mDeviceProfileManyParams); lwM2MTestClient.start(true); - awaitObserveReadAll(1, lwm2mDevice.getId().getId().toString()); + awaitObserveReadAll(1, lwm2mDevice.getId().getId().toString(), "second after client restart"); awaitUpdateReg(3); } diff --git a/pom.xml b/pom.xml index 58e0c32e43..8f5708bcec 100755 --- a/pom.xml +++ b/pom.xml @@ -172,6 +172,16 @@ true + + default-surefire-java-opts + + + !env.SUREFIRE_JAVA_OPTS + + + + + @@ -664,8 +674,9 @@ -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=200 --add-opens=java.base/java.lang.reflect=ALL-UNNAMED - -Dqueue.edqs.local.rocksdb_path="target/rocks/fork_${surefire.forkNumber}/edqs" - -Dqueue.calculated_fields.rocks_db_path="target/rocks/fork_${surefire.forkNumber}/cf" + -Dqueue.edqs.local.rocksdb_path="target/rocksdb/fork_${surefire.forkNumber}/edqs" + -Dqueue.calculated_fields.rocks_db_path="target/rocksdb/fork_${surefire.forkNumber}/cf" + ${env.SUREFIRE_JAVA_OPTS}