test fixes, refactoring

This commit is contained in:
dashevchenko 2022-11-07 13:19:17 +02:00
parent 62d6ffd715
commit c5e1c5a1a5
7 changed files with 93 additions and 39 deletions

View File

@ -70,25 +70,21 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.23.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -55,7 +55,6 @@ public abstract class AbstractContainerTest {
@BeforeSuite
public void beforeSuite() {
RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
if ("false".equals(System.getProperty("runLocal", "false"))) {
containerTestSuite.start();
}

View File

@ -38,7 +38,7 @@ public class TestProperties {
if (instance.isActive()) {
return WSS_URL;
}
return getProperty("tb.baseUrl");
return getProperty("tb.wsUrl");
}
private static String getProperty(String propertyName) {

View File

@ -16,13 +16,21 @@
package org.thingsboard.server.msa;
import com.fasterxml.jackson.databind.JsonNode;
import io.restassured.RestAssured;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.common.mapper.TypeRef;
import io.restassured.config.HeaderConfig;
import io.restassured.config.HttpClientConfig;
import io.restassured.config.RestAssuredConfig;
import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.log.ResponseLoggingFilter;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import org.hamcrest.Matchers;
import org.springframework.http.HttpStatus;
import org.thingsboard.rest.client.RestClient;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
@ -40,24 +48,33 @@ import java.util.List;
import java.util.Map;
import static io.restassured.RestAssured.given;
import static org.apache.http.params.CoreConnectionPNames.CONNECTION_TIMEOUT;
import static org.apache.http.params.CoreConnectionPNames.SO_TIMEOUT;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.AnyOf.anyOf;
import static org.thingsboard.server.common.data.StringUtils.isEmpty;
import static org.thingsboard.server.msa.AbstractContainerTest.getRequestFactoryForSelfSignedCert;
public class TestRestClient {
private static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization";
private final String baseURL;
private String token;
private String refreshToken;
private RequestSpecification spec;
private RequestSpecification requestSpec;
private ResponseSpecification responseSpec;
protected static final String ACTIVATE_TOKEN_REGEX = "/api/noauth/activate?activateToken=";
public TestRestClient(String url) {
RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
baseURL = url;
spec = given().baseUri(baseURL).contentType(ContentType.JSON);
requestSpec = given().baseUri(baseURL)
.contentType(ContentType.JSON)
.config(RestAssuredConfig.config()
.headerConfig(HeaderConfig.headerConfig()
.overwriteHeadersWithName(JWT_TOKEN_HEADER_PARAM)));
if (url.matches("^(https)://.*$")) {
spec.relaxedHTTPSValidation();
requestSpec.relaxedHTTPSValidation();
}
}
@ -70,12 +87,11 @@ public class TestRestClient {
.getBody().jsonPath();
token = jsonPath.get("token");
refreshToken = jsonPath.get("refreshToken");
spec.header(JWT_TOKEN_HEADER_PARAM, "Bearer " + token)
.contentType(ContentType.JSON);
requestSpec.header(JWT_TOKEN_HEADER_PARAM, "Bearer " + token);
}
public Device postDevice(String accessToken, Device device) {
return given().spec(spec).body(device)
return given().spec(requestSpec).body(device)
.pathParams("accessToken", accessToken)
.post("/api/device?accessToken={accessToken}")
.then()
@ -85,7 +101,7 @@ public class TestRestClient {
}
public ValidatableResponse getDeviceById(DeviceId deviceId, int statusCode) {
return given().spec(spec)
return given().spec(requestSpec)
.pathParams("deviceId", deviceId.getId())
.get("/api/device/{deviceId}")
.then()
@ -97,7 +113,7 @@ public class TestRestClient {
.as(Device.class);
}
public DeviceCredentials getDeviceCredentialsByDeviceId(DeviceId deviceId) {
return given().spec(spec).get("/api/device/{deviceId}/credentials", deviceId.getId())
return given().spec(requestSpec).get("/api/device/{deviceId}/credentials", deviceId.getId())
.then()
.assertThat()
.statusCode(HttpStatus.OK.value())
@ -106,41 +122,41 @@ public class TestRestClient {
}
public ValidatableResponse postTelemetry(String credentialsId, JsonNode telemetry) {
return given().spec(spec).body(telemetry)
return given().spec(requestSpec).body(telemetry)
.post("/api/v1/{credentialsId}/telemetry", credentialsId)
.then()
.statusCode(HttpStatus.OK.value());
}
public ValidatableResponse deleteDevice(DeviceId deviceId) {
return given().spec(spec)
return given().spec(requestSpec)
.delete("/api/device/{deviceId}", deviceId.getId())
.then()
.statusCode(HttpStatus.OK.value());
}
public ValidatableResponse deleteDeviceIfExists(DeviceId deviceId) {
return given().spec(spec)
return given().spec(requestSpec)
.delete("/api/device/{deviceId}", deviceId.getId())
.then()
.statusCode(anyOf(is(HttpStatus.OK.value()),is(HttpStatus.NOT_FOUND.value())));
}
public ValidatableResponse postTelemetryAttribute(String entityType, DeviceId deviceId, String scope, JsonNode attribute) {
return given().spec(spec).body(attribute)
return given().spec(requestSpec).body(attribute)
.post("/api/plugins/telemetry/{entityType}/{entityId}/attributes/{scope}", entityType, deviceId.getId(), scope)
.then()
.statusCode(HttpStatus.OK.value());
}
public ValidatableResponse postAttribute(String accessToken, JsonNode attribute) {
return given().spec(spec).body(attribute)
return given().spec(requestSpec).body(attribute)
.post("/api/v1/{accessToken}/attributes/", accessToken)
.then()
.statusCode(HttpStatus.OK.value());
}
public JsonNode getAttributes(String accessToken, String clientKeys, String sharedKeys) {
return given().spec(spec)
return given().spec(requestSpec)
.queryParam("clientKeys", clientKeys)
.queryParam("sharedKeys", sharedKeys)
.get("/api/v1/{accessToken}/attributes", accessToken)
@ -153,7 +169,7 @@ public class TestRestClient {
public PageData<RuleChain> getRuleChains(PageLink pageLink) {
Map<String, String> params = new HashMap<>();
addPageLinkToParam(params, pageLink);
return given().spec(spec).queryParams(params)
return given().spec(requestSpec).queryParams(params)
.get("/api/ruleChains")
.then()
.statusCode(HttpStatus.OK.value())
@ -162,7 +178,7 @@ public class TestRestClient {
}
public RuleChain postRootRuleChain(RuleChain ruleChain) {
return given().spec(spec)
return given().spec(requestSpec)
.body(ruleChain)
.post("/api/ruleChain")
.then()
@ -172,7 +188,7 @@ public class TestRestClient {
}
public RuleChainMetaData postRuleChainMetadata(RuleChainMetaData ruleChainMetaData) {
return given().spec(spec)
return given().spec(requestSpec)
.body(ruleChainMetaData)
.post("/api/ruleChain/metadata")
.then()
@ -182,14 +198,14 @@ public class TestRestClient {
}
public void setRootRuleChain(RuleChainId ruleChainId) {
given().spec(spec)
given().spec(requestSpec)
.post("/api/ruleChain/{ruleChainId}/root", ruleChainId.getId())
.then()
.statusCode(HttpStatus.OK.value());
}
public void deleteRuleChain(RuleChainId ruleChainId) {
given().spec(spec)
given().spec(requestSpec)
.delete("/api/ruleChain/{ruleChainId}", ruleChainId.getId())
.then()
.statusCode(HttpStatus.OK.value());
@ -224,7 +240,7 @@ public class TestRestClient {
params.put("fromType", fromId.getEntityType().name());
params.put("relationTypeGroup", relationTypeGroup.name());
return given().spec(spec)
return given().spec(requestSpec)
.pathParams(params)
.get("/api/relations?fromId={fromId}&fromType={fromType}&relationTypeGroup={relationTypeGroup}")
.then()
@ -234,7 +250,7 @@ public class TestRestClient {
}
public JsonNode postServerSideRpc(DeviceId deviceId, JsonNode serverRpcPayload) {
return given().spec(spec)
return given().spec(requestSpec)
.body(serverRpcPayload)
.post("/api/rpc/twoway/{deviceId}", deviceId.getId())
.then()

View File

@ -16,6 +16,9 @@
package org.thingsboard.server.msa.connectivity;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@ -24,11 +27,15 @@ import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.MqttQoS;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.common.util.ThingsBoardThreadFactory;
import org.thingsboard.mqtt.MqttClient;
import org.thingsboard.mqtt.MqttClientConfig;
import org.thingsboard.mqtt.MqttHandler;
@ -44,12 +51,10 @@ import org.thingsboard.server.msa.AbstractContainerTest;
import org.thingsboard.server.msa.WsClient;
import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.thingsboard.server.common.data.DataConstants.DEVICE;
@ -187,7 +192,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
event = listener.getEvents().poll(10 * timeoutMultiplier, TimeUnit.SECONDS);
responseData = jsonParser.parse(Objects.requireNonNull(event).getMessage()).getAsJsonObject();
assertThat(responseData.has("value")).isTrue();
assertThat(responseData.has("values")).isTrue();
assertThat(responseData.get("values").getAsJsonObject().get("attr1").getAsString()).isEqualTo(sharedAttributes.get("attr1").getAsString());
assertThat(responseData.get("values").getAsJsonObject().get("attr2").getAsString()).isEqualTo(sharedAttributes.get("attr2").getAsString());
@ -304,11 +309,19 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
JsonObject serverRpcPayload = new JsonObject();
serverRpcPayload.addProperty("method", "getValue");
serverRpcPayload.addProperty("params", true);
JsonNode response = testRestClient.postServerSideRpc(createdDevice.getId(), mapper.readTree(serverRpcPayload.toString()));
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName(getClass().getSimpleName())));
ListenableFuture<JsonNode> future = service.submit(() -> {
try {
return testRestClient.postServerSideRpc(createdDevice.getId(), mapper.readTree(serverRpcPayload.toString()));
} catch (IOException e) {
return null;
}
});
// Wait for RPC call from the server and send the response
MqttEvent requestFromServer = listener.getEvents().poll(10 * timeoutMultiplier, TimeUnit.SECONDS);
service.shutdownNow();
assertThat(requestFromServer).isNotNull();
assertThat(requestFromServer.getMessage()).isNotNull();
JsonNode requestFromServerJson = JacksonUtil.toJsonNode(requestFromServer.getMessage());
@ -326,8 +339,9 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
// Send a response to the server's RPC request
mqttClient.publish(gatewayRpcTopic, Unpooled.wrappedBuffer(gatewayResponse.toString().getBytes())).get();
JsonNode serverResponse = future.get(5 * timeoutMultiplier, TimeUnit.SECONDS);
assertThat(response).isEqualTo(clientResponse.getAsJsonObject());
assertThat(serverResponse).isEqualTo(mapper.readTree(clientResponse.toString()));
}
@Test
@ -366,7 +380,7 @@ public class MqttGatewayClientTest extends AbstractContainerTest {
TimeUnit.SECONDS.sleep(30);
}
String deviceName = "mqtt_device";
String deviceName = "mqtt_device" + RandomStringUtils.randomAlphabetic(5);
mqttClient.publish("v1/gateway/connect", Unpooled.wrappedBuffer(createGatewayConnectPayload(deviceName).toString().getBytes()), MqttQoS.AT_LEAST_ONCE).get();
if (timeoutMultiplier > 1) {

View File

@ -17,6 +17,7 @@ package org.thingsboard.server.msa.prototypes;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.Device;
@ -33,7 +34,7 @@ public class DevicePrototypes {
String isGateway = "{\"gateway\":true}";
JsonNode additionalInfo = JacksonUtil.valueToTree(isGateway);
Device gatewayDeviceTemplate = new Device();
gatewayDeviceTemplate.setName("mqtt_gateway " + RandomStringUtils.randomAlphabetic(5));
gatewayDeviceTemplate.setName("mqtt_gateway_" + RandomStringUtils.randomAlphabetic(5));
gatewayDeviceTemplate.setType("gateway");
gatewayDeviceTemplate.setAdditionalInfo(additionalInfo);
return gatewayDeviceTemplate;

28
pom.xml
View File

@ -133,6 +133,10 @@
<spring-test-dbunit.version>1.3.0</spring-test-dbunit.version> <!-- 2016 -->
<takari-cpsuite.version>1.2.7</takari-cpsuite.version> <!-- 2015 -->
<!-- BLACKBOX TEST SCOPE -->
<testng.version>7.6.1</testng.version>
<assertj.version>3.23.1</assertj.version>
<rest-assured.version>5.2.0</rest-assured.version>
<hamcrest.version>1.3</hamcrest.version>
<testcontainers.version>1.17.3</testcontainers.version>
<zeroturnaround.version>1.12</zeroturnaround.version>
<opensmpp.version>3.0.0</opensmpp.version>
@ -1618,6 +1622,30 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>${hamcrest}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>