From efa5d9296de783d1811a29c1b8d206a08e0bbb44 Mon Sep 17 00:00:00 2001 From: imbeacon Date: Mon, 28 Nov 2022 15:29:34 +0200 Subject: [PATCH] Added blackbox coap tests for provisioning feature and COAP client to blackbox tests --- msa/black-box-tests/pom.xml | 10 ++ .../server/msa/TestCoapClient.java | 106 ++++++++++++++++++ .../server/msa/TestCoapClientCallback.java | 53 +++++++++ .../msa/connectivity/CoapClientTest.java | 105 +++++++++++++++++ .../msa/connectivity/HttpClientTest.java | 1 - 5 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index 49f4c959e9..239f062cd9 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -92,6 +92,10 @@ awaitility test + + org.eclipse.californium + californium-core + ch.qos.logback logback-classic @@ -160,6 +164,12 @@ snmp docker-info + + org.thingsboard.common + message + 3.4.2PE-SNAPSHOT + test + diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java new file mode 100644 index 0000000000..50bef3d1b8 --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClient.java @@ -0,0 +1,106 @@ +package org.thingsboard.server.msa; + +import java.io.IOException; +import org.eclipse.californium.core.CoapClient; +import org.eclipse.californium.core.CoapHandler; +import org.eclipse.californium.core.CoapObserveRelation; +import org.eclipse.californium.core.CoapResponse; +import org.eclipse.californium.core.coap.CoAP; +import org.eclipse.californium.core.coap.MediaTypeRegistry; +import org.eclipse.californium.core.coap.Request; +import org.eclipse.californium.elements.exception.ConnectorException; +import org.thingsboard.server.common.msg.session.FeatureType; + +public class TestCoapClient { + + private static final String COAP_BASE_URL = "coap://localhost:5683/api/v1/"; + private static final long CLIENT_REQUEST_TIMEOUT = 60000L; + + private final CoapClient client; + + public TestCoapClient(){ + this.client = createClient(); + } + + public TestCoapClient(String accessToken, FeatureType featureType) { + this.client = createClient(getFeatureTokenUrl(accessToken, featureType)); + } + + public TestCoapClient(String featureTokenUrl) { + this.client = createClient(featureTokenUrl); + } + + public void connectToCoap(String accessToken) { + setURI(accessToken, null); + } + + public void connectToCoap(String accessToken, FeatureType featureType) { + setURI(accessToken, featureType); + } + + public void disconnect() { + if (client != null) { + client.shutdown(); + } + } + + public CoapResponse postMethod(String requestBody) throws ConnectorException, IOException { + return this.postMethod(requestBody.getBytes()); + } + + public CoapResponse postMethod(byte[] requestBodyBytes) throws ConnectorException, IOException { + return client.setTimeout(CLIENT_REQUEST_TIMEOUT).post(requestBodyBytes, MediaTypeRegistry.APPLICATION_JSON); + } + + public void postMethod(CoapHandler handler, String payload, int format) { + client.post(handler, payload, format); + } + + public void postMethod(CoapHandler handler, byte[] payload, int format) { + client.post(handler, payload, format); + } + + public CoapResponse getMethod() throws ConnectorException, IOException { + return client.setTimeout(CLIENT_REQUEST_TIMEOUT).get(); + } + + public CoapObserveRelation getObserveRelation(TestCoapClientCallback callback){ + Request request = Request.newGet().setObserve(); + request.setType(CoAP.Type.CON); + return client.observe(request, callback); + } + + public void setURI(String featureTokenUrl) { + if (client == null) { + throw new RuntimeException("Failed to connect! CoapClient is not initialized!"); + } + client.setURI(featureTokenUrl); + } + + public void setURI(String accessToken, FeatureType featureType) { + if (featureType == null){ + featureType = FeatureType.ATTRIBUTES; + } + setURI(getFeatureTokenUrl(accessToken, featureType)); + } + + private CoapClient createClient() { + return new CoapClient(); + } + + private CoapClient createClient(String featureTokenUrl) { + return new CoapClient(featureTokenUrl); + } + + public static String getFeatureTokenUrl(FeatureType featureType) { + return COAP_BASE_URL + featureType.name().toLowerCase(); + } + + public static String getFeatureTokenUrl(String token, FeatureType featureType) { + return COAP_BASE_URL + token + "/" + featureType.name().toLowerCase(); + } + + public static String getFeatureTokenUrl(String token, FeatureType featureType, int requestId) { + return COAP_BASE_URL + token + "/" + featureType.name().toLowerCase() + "/" + requestId; + } +} diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java new file mode 100644 index 0000000000..7209560d2d --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestCoapClientCallback.java @@ -0,0 +1,53 @@ +package org.thingsboard.server.msa; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.californium.core.CoapHandler; +import org.eclipse.californium.core.CoapResponse; +import org.eclipse.californium.core.coap.CoAP; + +import java.util.concurrent.CountDownLatch; + +@Slf4j +@Data +public class TestCoapClientCallback implements CoapHandler { + + protected final CountDownLatch latch; + protected Integer observe; + protected byte[] payloadBytes; + protected CoAP.ResponseCode responseCode; + + public TestCoapClientCallback() { + this.latch = new CountDownLatch(1); + } + + public TestCoapClientCallback(int subscribeCount) { + this.latch = new CountDownLatch(subscribeCount); + } + + public Integer getObserve() { + return observe; + } + + public byte[] getPayloadBytes() { + return payloadBytes; + } + + public CoAP.ResponseCode getResponseCode() { + return responseCode; + } + + @Override + public void onLoad(CoapResponse response) { + observe = response.getOptions().getObserve(); + payloadBytes = response.getPayload(); + responseCode = response.getCode(); + latch.countDown(); + } + + @Override + public void onError() { + log.warn("Command Response Ack Error, No connect"); + } + +} diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java new file mode 100644 index 0000000000..cb509d9fa0 --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/CoapClientTest.java @@ -0,0 +1,105 @@ +package org.thingsboard.server.msa.connectivity; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.gson.JsonObject; +import io.restassured.path.json.JsonPath; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.msg.session.FeatureType; +import org.thingsboard.server.msa.AbstractContainerTest; +import org.thingsboard.server.msa.TestCoapClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.thingsboard.server.msa.prototypes.DevicePrototypes.defaultDevicePrototype; + +public class CoapClientTest extends AbstractContainerTest { + private TestCoapClient client; + + private Device device; + @BeforeMethod + public void setUp() throws Exception { + testRestClient.login("tenant@thingsboard.org", "tenant"); + device = testRestClient.postDevice("", defaultDevicePrototype("http_")); + } + + @AfterMethod + public void tearDown() { + testRestClient.deleteDeviceIfExists(device.getId()); + } + + @Test + public void provisionRequestForDeviceWithPreProvisionedStrategy() throws Exception { + + DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId()); + deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.CHECK_PRE_PROVISIONED_DEVICES); + + DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId()); + + JsonNode provisionResponse = JacksonUtil.fromBytes(createCoapClientAndPublish(device.getName())); + + assertThat(provisionResponse.get("credentialsType").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsType().name()); + assertThat(provisionResponse.get("credentialsValue").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsId()); + assertThat(provisionResponse.get("status").asText()).isEqualTo("SUCCESS"); + + updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED); + } + + @Test + public void provisionRequestForDeviceWithAllowToCreateNewDevicesStrategy() throws Exception { + + String testDeviceName = "test_provision_device"; + + DeviceProfile deviceProfile = testRestClient.getDeviceProfileById(device.getDeviceProfileId()); + + deviceProfile = updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.ALLOW_CREATE_NEW_DEVICES); + + JsonNode provisionResponse = JacksonUtil.fromBytes(createCoapClientAndPublish(testDeviceName)); + + testRestClient.deleteDeviceIfExists(device.getId()); + device = testRestClient.getDeviceByName(testDeviceName); + + DeviceCredentials expectedDeviceCredentials = testRestClient.getDeviceCredentialsByDeviceId(device.getId()); + + assertThat(provisionResponse.get("credentialsType").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsType().name()); + assertThat(provisionResponse.get("credentialsValue").asText()).isEqualTo(expectedDeviceCredentials.getCredentialsId()); + assertThat(provisionResponse.get("status").asText()).isEqualTo("SUCCESS"); + + updateDeviceProfileWithProvisioningStrategy(deviceProfile, DeviceProfileProvisionType.DISABLED); + } + + @Test + public void provisionRequestForDeviceWithDisabledProvisioningStrategy() throws Exception { + + JsonObject provisionRequest = new JsonObject(); + provisionRequest.addProperty("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY); + provisionRequest.addProperty("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET); + + JsonNode response = JacksonUtil.fromBytes(createCoapClientAndPublish(null)); + + assertThat(response.get("status").asText()).isEqualTo("NOT_FOUND"); + } + + private byte[] createCoapClientAndPublish(String deviceName) throws Exception { + String provisionRequestMsg = createTestProvisionMessage(deviceName); + client = new TestCoapClient(TestCoapClient.getFeatureTokenUrl(FeatureType.PROVISION)); + return client.postMethod(provisionRequestMsg.getBytes()).getPayload(); + } + + private String createTestProvisionMessage(String deviceName) { + ObjectNode provisionRequest = JacksonUtil.newObjectNode(); + provisionRequest.put("provisionDeviceKey", TEST_PROVISION_DEVICE_KEY); + provisionRequest.put("provisionDeviceSecret", TEST_PROVISION_DEVICE_SECRET); + if (deviceName != null) { + provisionRequest.put("deviceName", deviceName); + } + return provisionRequest.toString(); + } + +} diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java index bf5e4ba7b9..adaefa887a 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java @@ -96,7 +96,6 @@ public class HttpClientTest extends AbstractContainerTest { assertThat(attributes3.get("client").get("stringKey")).isEqualTo(clientAttribute.get("stringKey")); } - @Test public void provisionRequestForDeviceWithPreProvisionedStrategy() throws Exception {