Commit 32dd7f0437053fdbb42227ff939dc9f2e7be17d1

Authored by Viacheslav Kukhtyn
1 parent cdc72653

Black box tests update

Showing 12 changed files with 80 additions and 48 deletions
  1 +
  2 +## Black box tests execution
  3 +To run the black box tests with using Docker, the local Docker images of Thingsboard's microservices should be built. <br />
  4 +- Build the local Docker images in the directory with the Thingsboard's main [pom.xml](./../../pom.xml):
  5 +
  6 + mvn clean install -Ddockerfile.skip=false
  7 +- Verify that the new local images were built:
  8 +
  9 + docker image ls
  10 +As result, in REPOSITORY column, next images should be present:
  11 +
  12 + thingsboard/tb-coap-transport
  13 + thingsboard/tb-http-transport
  14 + thingsboard/tb-mqtt-transport
  15 + thingsboard/tb-node
  16 + thingsboard/tb-web-ui
  17 + thingsboard/tb-js-executor
  18 +
  19 +- Run the black box tests in the [msa/black-box-tests](../black-box-tests) directory:
  20 +
  21 + mvn clean install -DblackBoxTests.skip=false
\ No newline at end of file
... ...
msa/black-box-tests/pom.xml renamed from msa/integration-tests/pom.xml
... ... @@ -25,16 +25,16 @@
25 25 <artifactId>msa</artifactId>
26 26 </parent>
27 27 <groupId>org.thingsboard.msa</groupId>
28   - <artifactId>integration-tests</artifactId>
  28 + <artifactId>black-box-tests</artifactId>
29 29
30   - <name>ThingsBoard Integration Tests</name>
  30 + <name>ThingsBoard Black Box Tests</name>
31 31 <url>https://thingsboard.io</url>
32   - <description>Project for ThingsBoard integration tests with using Docker</description>
  32 + <description>Project for ThingsBoard black box testing with using Docker</description>
33 33
34 34 <properties>
35 35 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
36 36 <main.dir>${basedir}/../..</main.dir>
37   - <integrationTests.skip>true</integrationTests.skip>
  37 + <blackBoxTests.skip>true</blackBoxTests.skip>
38 38 <testcontainers.version>1.9.1</testcontainers.version>
39 39 <java-websocket.version>1.3.9</java-websocket.version>
40 40 <httpclient.version>4.5.6</httpclient.version>
... ... @@ -95,7 +95,7 @@
95 95 <includes>
96 96 <include>**/*TestSuite.java</include>
97 97 </includes>
98   - <skipTests>${integrationTests.skip}</skipTests>
  98 + <skipTests>${blackBoxTests.skip}</skipTests>
99 99 </configuration>
100 100 </plugin>
101 101 </plugins>
... ...
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/AbstractContainerTest.java
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java
... ... @@ -22,15 +22,18 @@ import org.testcontainers.containers.DockerComposeContainer;
22 22 import org.testcontainers.containers.wait.strategy.Wait;
23 23
24 24 import java.io.File;
  25 +import java.time.Duration;
25 26
26 27 @RunWith(ClasspathSuite.class)
27   -@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*"})
  28 +@ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*Test"})
28 29 public class ContainerTestSuite {
29 30
30 31 @ClassRule
31   - public static DockerComposeContainer composeContainer = new DockerComposeContainer(new File("./../docker/docker-compose.yml"))
  32 + public static DockerComposeContainer composeContainer = new DockerComposeContainer(
  33 + new File("./../../docker/docker-compose.yml"),
  34 + new File("./../../docker/docker-compose.postgres.yml"))
32 35 .withPull(false)
33 36 .withLocalCompose(true)
34 37 .withTailChildContainers(true)
35   - .withExposedService("tb-web-ui1", 8080, Wait.forHttp("/login"));
  38 + .withExposedService("tb-web-ui1", 8080, Wait.forHttp("/login").withStartupTimeout(Duration.ofSeconds(120)));
36 39 }
... ...
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/WsClient.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/WsClient.java
... ... @@ -15,13 +15,23 @@
15 15 */
16 16 package org.thingsboard.server.msa;
17 17
  18 +import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import lombok.extern.slf4j.Slf4j;
18 20 import org.java_websocket.client.WebSocketClient;
19 21 import org.java_websocket.handshake.ServerHandshake;
  22 +import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
20 23
  24 +import java.io.IOException;
21 25 import java.net.URI;
  26 +import java.util.concurrent.CountDownLatch;
  27 +import java.util.concurrent.TimeUnit;
22 28
  29 +@Slf4j
23 30 public class WsClient extends WebSocketClient {
24   - private String message;
  31 + private static final ObjectMapper mapper = new ObjectMapper();
  32 + private WsTelemetryResponse message;
  33 +
  34 + private CountDownLatch latch = new CountDownLatch(1);;
25 35
26 36 public WsClient(URI serverUri) {
27 37 super(serverUri);
... ... @@ -33,11 +43,20 @@ public class WsClient extends WebSocketClient {
33 43
34 44 @Override
35 45 public void onMessage(String message) {
36   - this.message = message;
  46 + try {
  47 + WsTelemetryResponse response = mapper.readValue(message, WsTelemetryResponse.class);
  48 + if (!response.getData().isEmpty()) {
  49 + this.message = response;
  50 + latch.countDown();
  51 + }
  52 + } catch (IOException e) {
  53 + log.error("ws message can't be read");
  54 + }
37 55 }
38 56
39 57 @Override
40 58 public void onClose(int code, String reason, boolean remote) {
  59 + log.info("ws is closed, due to [{}]", reason);
41 60 }
42 61
43 62 @Override
... ... @@ -45,7 +64,13 @@ public class WsClient extends WebSocketClient {
45 64 ex.printStackTrace();
46 65 }
47 66
48   - public String getLastMessage() {
49   - return this.message;
  67 + public WsTelemetryResponse getLastMessage() {
  68 + try {
  69 + latch.await(10, TimeUnit.SECONDS);
  70 + return this.message;
  71 + } catch (InterruptedException e) {
  72 + log.error("Timeout, ws message wasn't received");
  73 + }
  74 + return null;
50 75 }
51 76 }
... ...
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/connectivity/HttpClientTest.java
... ... @@ -25,12 +25,10 @@ import org.thingsboard.server.msa.AbstractContainerTest;
25 25 import org.thingsboard.server.msa.WsClient;
26 26 import org.thingsboard.server.msa.mapper.WsTelemetryResponse;
27 27
28   -import java.util.concurrent.TimeUnit;
29   -
30 28 public class HttpClientTest extends AbstractContainerTest {
31 29
32 30 @Test
33   - public void telemetryUpdate() throws Exception {
  31 + public void telemetryUpload() throws Exception {
34 32 restClient.login("tenant@thingsboard.org", "tenant");
35 33
36 34 Device device = createDevice("http_");
... ... @@ -43,8 +41,8 @@ public class HttpClientTest extends AbstractContainerTest {
43 41 ResponseEntity.class,
44 42 deviceCredentials.getCredentialsId());
45 43 Assert.assertTrue(deviceTelemetryResponse.getStatusCode().is2xxSuccessful());
46   - TimeUnit.SECONDS.sleep(1);
47   - WsTelemetryResponse actualLatestTelemetry = mapper.readValue(wsClient.getLastMessage(), WsTelemetryResponse.class);
  44 + WsTelemetryResponse actualLatestTelemetry = wsClient.getLastMessage();
  45 + wsClient.closeBlocking();
48 46
49 47 Assert.assertEquals(Sets.newHashSet("booleanKey", "stringKey", "doubleKey", "longKey"),
50 48 actualLatestTelemetry.getLatestValues().keySet());
... ...
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java
... ... @@ -23,7 +23,9 @@ import com.google.common.util.concurrent.MoreExecutors;
23 23 import com.google.gson.JsonObject;
24 24 import io.netty.buffer.ByteBuf;
25 25 import io.netty.buffer.Unpooled;
  26 +import io.netty.handler.codec.mqtt.MqttQoS;
26 27 import lombok.Data;
  28 +import lombok.extern.slf4j.Slf4j;
27 29 import org.apache.commons.lang3.RandomStringUtils;
28 30 import org.junit.*;
29 31 import org.springframework.core.ParameterizedTypeReference;
... ... @@ -50,6 +52,7 @@ import java.nio.charset.StandardCharsets;
50 52 import java.util.*;
51 53 import java.util.concurrent.*;
52 54
  55 +@Slf4j
53 56 public class MqttClientTest extends AbstractContainerTest {
54 57
55 58 @Test
... ... @@ -61,8 +64,8 @@ public class MqttClientTest extends AbstractContainerTest {
61 64 WsClient wsClient = subscribeToWebSocket(device.getId(), "LATEST_TELEMETRY", CmdsType.TS_SUB_CMDS);
62 65 MqttClient mqttClient = getMqttClient(deviceCredentials, null);
63 66 mqttClient.publish("v1/devices/me/telemetry", Unpooled.wrappedBuffer(createPayload().toString().getBytes()));
64   - TimeUnit.SECONDS.sleep(1);
65   - WsTelemetryResponse actualLatestTelemetry = mapper.readValue(wsClient.getLastMessage(), WsTelemetryResponse.class);
  67 + WsTelemetryResponse actualLatestTelemetry = wsClient.getLastMessage();
  68 + wsClient.closeBlocking();
66 69
67 70 Assert.assertEquals(4, actualLatestTelemetry.getData().size());
68 71 Assert.assertEquals(Sets.newHashSet("booleanKey", "stringKey", "doubleKey", "longKey"),
... ... @@ -87,8 +90,8 @@ public class MqttClientTest extends AbstractContainerTest {
87 90 WsClient wsClient = subscribeToWebSocket(device.getId(), "LATEST_TELEMETRY", CmdsType.TS_SUB_CMDS);
88 91 MqttClient mqttClient = getMqttClient(deviceCredentials, null);
89 92 mqttClient.publish("v1/devices/me/telemetry", Unpooled.wrappedBuffer(createPayload(ts).toString().getBytes()));
90   - TimeUnit.SECONDS.sleep(1);
91   - WsTelemetryResponse actualLatestTelemetry = mapper.readValue(wsClient.getLastMessage(), WsTelemetryResponse.class);
  93 + WsTelemetryResponse actualLatestTelemetry = wsClient.getLastMessage();
  94 + wsClient.closeBlocking();
92 95
93 96 Assert.assertEquals(4, actualLatestTelemetry.getData().size());
94 97 Assert.assertEquals(getExpectedLatestValues(ts), actualLatestTelemetry.getLatestValues());
... ... @@ -116,8 +119,8 @@ public class MqttClientTest extends AbstractContainerTest {
116 119 clientAttributes.addProperty("attr3", 42.0);
117 120 clientAttributes.addProperty("attr4", 73);
118 121 mqttClient.publish("v1/devices/me/attributes", Unpooled.wrappedBuffer(clientAttributes.toString().getBytes()));
119   - TimeUnit.SECONDS.sleep(1);
120   - WsTelemetryResponse actualLatestTelemetry = mapper.readValue(wsClient.getLastMessage(), WsTelemetryResponse.class);
  122 + WsTelemetryResponse actualLatestTelemetry = wsClient.getLastMessage();
  123 + wsClient.closeBlocking();
121 124
122 125 Assert.assertEquals(4, actualLatestTelemetry.getData().size());
123 126 Assert.assertEquals(Sets.newHashSet("attr1", "attr2", "attr3", "attr4"),
... ... @@ -157,7 +160,7 @@ public class MqttClientTest extends AbstractContainerTest {
157 160 Assert.assertTrue(sharedAttributesResponse.getStatusCode().is2xxSuccessful());
158 161
159 162 // Subscribe to attributes response
160   - mqttClient.on("v1/devices/me/attributes/response/+", listener);
  163 + mqttClient.on("v1/devices/me/attributes/response/+", listener, MqttQoS.AT_LEAST_ONCE);
161 164 // Request attributes
162 165 JsonObject request = new JsonObject();
163 166 request.addProperty("clientKeys", "clientAttr");
... ... @@ -183,7 +186,7 @@ public class MqttClientTest extends AbstractContainerTest {
183 186
184 187 MqttMessageListener listener = new MqttMessageListener();
185 188 MqttClient mqttClient = getMqttClient(deviceCredentials, listener);
186   - mqttClient.on("v1/devices/me/attributes", listener);
  189 + mqttClient.on("v1/devices/me/attributes", listener, MqttQoS.AT_LEAST_ONCE);
187 190
188 191 String sharedAttributeName = "sharedAttr";
189 192
... ... @@ -226,13 +229,12 @@ public class MqttClientTest extends AbstractContainerTest {
226 229
227 230 MqttMessageListener listener = new MqttMessageListener();
228 231 MqttClient mqttClient = getMqttClient(deviceCredentials, listener);
229   - mqttClient.on("v1/devices/me/rpc/request/+", listener);
  232 + mqttClient.on("v1/devices/me/rpc/request/+", listener, MqttQoS.AT_LEAST_ONCE);
230 233
231 234 // Send an RPC from the server
232 235 JsonObject serverRpcPayload = new JsonObject();
233 236 serverRpcPayload.addProperty("method", "getValue");
234 237 serverRpcPayload.addProperty("params", true);
235   - serverRpcPayload.addProperty("timeout", 1000);
236 238 ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
237 239 ListenableFuture<ResponseEntity> future = service.submit(() -> {
238 240 try {
... ... @@ -271,7 +273,7 @@ public class MqttClientTest extends AbstractContainerTest {
271 273
272 274 MqttMessageListener listener = new MqttMessageListener();
273 275 MqttClient mqttClient = getMqttClient(deviceCredentials, listener);
274   - mqttClient.on("v1/devices/me/rpc/request/+", listener);
  276 + mqttClient.on("v1/devices/me/rpc/request/+", listener, MqttQoS.AT_LEAST_ONCE);
275 277
276 278 // Get the default rule chain id to make it root again after test finished
277 279 RuleChainId defaultRuleChainId = getDefaultRuleChainId();
... ... @@ -377,6 +379,7 @@ public class MqttClientTest extends AbstractContainerTest {
377 379
378 380 @Override
379 381 public void onMessage(String topic, ByteBuf message) {
  382 + log.info("MQTT message [{}], topic [{}]", message.toString(StandardCharsets.UTF_8), topic);
380 383 events.add(new MqttEvent(topic, message.toString(StandardCharsets.UTF_8)));
381 384 }
382 385 }
... ...
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/mapper/AttributesResponse.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/mapper/AttributesResponse.java
msa/black-box-tests/src/test/java/org/thingsboard/server/msa/mapper/WsTelemetryResponse.java renamed from msa/integration-tests/src/test/java/org/thingsboard/server/msa/mapper/WsTelemetryResponse.java
msa/black-box-tests/src/test/resources/RpcResponseRuleChainMetadata.json renamed from msa/integration-tests/src/test/resources/RpcResponseRuleChainMetadata.json
1   -
2   -## Integration tests execution
3   -To run the integration tests with using Docker, the local Docker images of Thingsboard's microservices should be built. <br />
4   -- Build the local Docker images in the directory with the Thingsboard's main [pom.xml](./../../pom.xml):
5   -
6   - mvn clean install -Ddockerfile.skip=false
7   -- Verify that the new local images were built:
8   -
9   - docker image ls
10   -As result, in REPOSITORY column, next images should be present:
11   -
12   - local-maven-build/tb-node
13   - local-maven-build/tb-web-ui
14   - local-maven-build/tb-web-ui
15   -
16   -- Run the integration tests in the [msa/integration-tests](../integration-tests) directory:
17   -
18   - mvn clean install -DintegrationTests.skip=false
\ No newline at end of file
... ... @@ -16,7 +16,7 @@
16 16
17 17 -->
18 18 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19   - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20 20 <modelVersion>4.0.0</modelVersion>
21 21 <parent>
22 22 <groupId>org.thingsboard</groupId>
... ... @@ -41,7 +41,7 @@
41 41 <module>web-ui</module>
42 42 <module>tb-node</module>
43 43 <module>transport</module>
44   - <module>integration-tests</module>
  44 + <module>black-box-tests</module>
45 45 </modules>
46 46
47 47 <build>
... ...