Showing
12 changed files
with
80 additions
and
48 deletions
msa/black-box-tests/README.md
0 → 100644
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
msa/integration-tests/README.md
deleted
100644 → 0
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> | ... | ... |