From 02857b70bcdd2149392ca6ed1717c2847be896f9 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 27 Feb 2025 17:31:46 +0200 Subject: [PATCH] fixed flaky test, code refactoring --- .../subscription/TbAlarmDataSubCtx.java | 3 +- .../entitiy/EdqsEntityServiceTest.java | 7 +++ .../service/entitiy/EntityServiceTest.java | 56 ++++++++----------- .../server/dao/entity/BaseEntityService.java | 2 +- .../server/msa/TestRestClient.java | 15 ++++- .../msa/edqs/EdqsEntityDataQueryTest.java | 21 +++++-- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java index c471c84b11..f6b4067543 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAlarmDataSubCtx.java @@ -39,6 +39,7 @@ import org.thingsboard.server.dao.alarm.AlarmService; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.sql.query.EntityKeyMapping; import org.thingsboard.server.service.ws.WebSocketService; import org.thingsboard.server.service.ws.WebSocketSessionRef; import org.thingsboard.server.service.ws.telemetry.cmd.v2.AlarmDataUpdate; @@ -359,7 +360,7 @@ public class TbAlarmDataSubCtx extends TbAbstractDataSubCtx { EntityDataSortOrder sortOrder = query.getPageLink().getSortOrder(); EntityDataSortOrder entitiesSortOrder; if (sortOrder == null || sortOrder.getKey().getType().equals(EntityKeyType.ALARM_FIELD)) { - entitiesSortOrder = new EntityDataSortOrder(new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime")); + entitiesSortOrder = new EntityDataSortOrder(new EntityKey(EntityKeyType.ENTITY_FIELD, EntityKeyMapping.CREATED_TIME)); } else { entitiesSortOrder = sortOrder; } diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java index b9cd7dbac2..f4cdf3038b 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/EdqsEntityServiceTest.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.query.EntityCountQuery; import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityDataQuery; +import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.query.RelationsQueryFilter; import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; @@ -106,6 +107,12 @@ public class EdqsEntityServiceTest extends EntityServiceTest { result -> result.getTotalElements() == expectedResultSize); } + @Override + protected List findByQueryAndCheckTelemetry(EntityDataQuery query, EntityKeyType entityKeyType, String key, List expectedTelemetries) { + return await().atMost(15, TimeUnit.SECONDS).until(() -> findEntitiesTelemetry(query, entityKeyType, key, expectedTelemetries), + loadedTelemetry -> loadedTelemetry.containsAll(expectedTelemetries)); + } + @Override protected long countByQueryAndCheck(EntityCountQuery countQuery, int expectedResult) { return countByQueryAndCheck(new CustomerId(CustomerId.NULL_UUID), countQuery, expectedResult); diff --git a/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java b/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java index 0297281b68..76d3ac1659 100644 --- a/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/entitiy/EntityServiceTest.java @@ -116,7 +116,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertEquals; import static org.thingsboard.server.common.data.query.EntityKeyType.ATTRIBUTE; import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD; @@ -1571,47 +1570,19 @@ public class EntityServiceTest extends AbstractControllerTest { for (EntityKeyType currentAttributeKeyType : attributesEntityTypes) { List latestValues = Collections.singletonList(new EntityKey(currentAttributeKeyType, "temperature")); EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, null); - PageData data = findByQueryAndCheck(query, 67); - List loadedEntities = new ArrayList<>(data.getData()); - while (data.hasNext()) { - query = query.next(); - data = findByQuery(query); - loadedEntities.addAll(data.getData()); - } - Assert.assertEquals(67, loadedEntities.size()); - List loadedTemperatures = new ArrayList<>(); - for (Device device : devices) { - loadedTemperatures.add(loadedEntities.stream().filter(entityData -> entityData.getEntityId().equals(device.getId())).findFirst().orElse(null) - .getLatest().get(currentAttributeKeyType).get("temperature").getValue()); - } - List deviceTemperatures = temperatures.stream().map(aLong -> Long.toString(aLong)).collect(Collectors.toList()); - assertThat(loadedTemperatures).containsExactlyInAnyOrderElementsOf(deviceTemperatures); + List deviceTemperatures = temperatures.stream().map(aLong -> Long.toString(aLong)).toList(); + findByQueryAndCheckTelemetry(query, currentAttributeKeyType, "temperature", deviceTemperatures); pageLink = new EntityDataPageLink(10, 0, null, sortOrder); KeyFilter highTemperatureFilter = createNumericKeyFilter("temperature", currentAttributeKeyType, NumericFilterPredicate.NumericOperation.GREATER, 45); List keyFiltersHighTemperature = Collections.singletonList(highTemperatureFilter); query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, keyFiltersHighTemperature); - data = findByQueryAndCheck(query, highTemperatures.size()); - - loadedEntities = new ArrayList<>(data.getData()); - while (data.hasNext()) { - query = query.next(); - data = findByQuery(query); - loadedEntities.addAll(data.getData()); - } - Assert.assertEquals(highTemperatures.size(), loadedEntities.size()); - - List loadedHighTemperatures = loadedEntities.stream().map(entityData -> - entityData.getLatest().get(currentAttributeKeyType).get("temperature").getValue()).collect(Collectors.toList()); - List deviceHighTemperatures = highTemperatures.stream().map(aLong -> Long.toString(aLong)).collect(Collectors.toList()); - - assertThat(loadedHighTemperatures).containsExactlyInAnyOrderElementsOf(deviceHighTemperatures); + findByQueryAndCheckTelemetry(query, currentAttributeKeyType, "temperature", highTemperatures.stream().map(Object::toString).toList()); } deviceService.deleteDevicesByTenantId(tenantId); } - @Test public void testBuildNumericPredicateQueryOperations() throws ExecutionException, InterruptedException { @@ -2519,7 +2490,7 @@ public class EntityServiceTest extends AbstractControllerTest { findByQueryAndCheck(new CustomerId(EntityId.NULL_UUID), query, 0); } - private PageData findByQuery(EntityDataQuery query) { + protected PageData findByQuery(EntityDataQuery query) { return findByQuery(new CustomerId(CustomerId.NULL_UUID), query); } @@ -2527,7 +2498,7 @@ public class EntityServiceTest extends AbstractControllerTest { return entityService.findEntityDataByQuery(tenantId, customerId, query); } - private PageData findByQueryAndCheck(EntityDataQuery query, long expectedResultSize) { + protected PageData findByQueryAndCheck(EntityDataQuery query, long expectedResultSize) { return findByQueryAndCheck(new CustomerId(CustomerId.NULL_UUID), query, expectedResultSize); } @@ -2537,6 +2508,23 @@ public class EntityServiceTest extends AbstractControllerTest { return result; } + protected List findByQueryAndCheckTelemetry(EntityDataQuery query, EntityKeyType entityKeyType, String key, List expectedTelemetry) { + List entitiesTelemetry = findEntitiesTelemetry(query, entityKeyType, key, expectedTelemetry); + assertThat(entitiesTelemetry).containsExactlyInAnyOrderElementsOf(expectedTelemetry); + return entitiesTelemetry; + } + + protected List findEntitiesTelemetry(EntityDataQuery query, EntityKeyType entityKeyType, String key, List expectedTelemetries) { + PageData data = findByQueryAndCheck(query, expectedTelemetries.size()); + List loadedEntities = new ArrayList<>(data.getData()); + while (data.hasNext()) { + query = query.next(); + data = findByQuery(query); + loadedEntities.addAll(data.getData()); + } + return loadedEntities.stream().map(entityData -> entityData.getLatest().get(entityKeyType).get(key).getValue()).toList(); + } + protected long countByQuery(CustomerId customerId, EntityCountQuery query) { return entityService.countEntitiesByQuery(tenantId, customerId, query); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index bbe21341a4..3e398f9746 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -112,7 +112,7 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe validateId(customerId, id -> INCORRECT_CUSTOMER_ID + id); validateEntityDataQuery(query); - if (edqsApiService.isEnabled() && validForEdqs(query) && !tenantId.isSysTenantId()) { + if (edqsApiService.isEnabled() && validForEdqs(query)) { EdqsRequest request = EdqsRequest.builder() .entityDataQuery(query) .build(); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java index ed4b54f2fc..d74438a428 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java @@ -237,6 +237,15 @@ public class TestRestClient { .as(JsonNode.class); } + public JsonNode getLatestTelemetry(EntityId entityId) { + return given().spec(requestSpec) + .get("/api/plugins/telemetry/" + entityId.getEntityType().name() + "/" + entityId.getId() + "/values/timeseries") + .then() + .statusCode(HTTP_OK) + .extract() + .as(JsonNode.class); + } + public JsonPath postProvisionRequest(String provisionRequest) { return given().spec(requestSpec) .body(provisionRequest) @@ -498,13 +507,13 @@ public class TestRestClient { public UserId createUserAndLogin(User user, String password) { UserId userId = postUser(user).getId(); - getAndSetUserToken(userId.getId().toString()); + getAndSetUserToken(userId); return userId; } - public void getAndSetUserToken(String id) { + public void getAndSetUserToken(UserId id) { ObjectNode tokenInfo = given().spec(requestSpec) - .get("/api/user/" + id + "/token") + .get("/api/user/" + id.getId().toString() + "/token") .then() .extract() .as(ObjectNode.class); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java index 6c0a507431..8e77b315e6 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/edqs/EdqsEntityDataQueryTest.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.query.EntityDataSortOrder; import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.query.EntityTypeFilter; +import org.thingsboard.server.common.data.query.TsValue; import org.thingsboard.server.msa.AbstractContainerTest; import org.thingsboard.server.msa.DisableUIListeners; import org.thingsboard.server.msa.ui.utils.EntityPrototypes; @@ -44,6 +45,7 @@ import org.thingsboard.server.msa.ui.utils.EntityPrototypes; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; @@ -111,16 +113,16 @@ public class EdqsEntityDataQueryTest extends AbstractContainerTest { EntityCountQuery query = new EntityCountQuery(allDeviceFilter); await("Waiting for total device count") .atMost(30, TimeUnit.SECONDS) - .until(() -> testRestClient.postCountDataQuery(query).compareTo(97L * 2) >= 0); + .until(() -> testRestClient.postCountDataQuery(query).equals(97L * 2)); - testRestClient.getAndSetUserToken(tenantAdminId.getId().toString()); + testRestClient.getAndSetUserToken(tenantAdminId); await("Waiting for total device count") .atMost(30, TimeUnit.SECONDS) .until(() -> testRestClient.postCountDataQuery(query).equals(97L)); testRestClient.resetToken(); testRestClient.login("sysadmin@thingsboard.org", "sysadmin"); - testRestClient.getAndSetUserToken(tenant2AdminId.getId().toString()); + testRestClient.getAndSetUserToken(tenant2AdminId); await("Waiting for total device count") .atMost(30, TimeUnit.SECONDS) .until(() -> testRestClient.postCountDataQuery(query).equals(97L)); @@ -129,17 +131,17 @@ public class EdqsEntityDataQueryTest extends AbstractContainerTest { @Test public void testRetrieveTenantDevicesByDeviceTypeFilter() { // login tenant admin - testRestClient.getAndSetUserToken(tenantAdminId.getId().toString()); + testRestClient.getAndSetUserToken(tenantAdminId); checkUserDevices(tenantDevices); // login customer user - testRestClient.getAndSetUserToken(customerUserId.getId().toString()); + testRestClient.getAndSetUserToken(customerUserId); checkUserDevices(tenantDevices.subList(0, 12)); // login other tenant admin testRestClient.resetToken(); testRestClient.login("sysadmin@thingsboard.org", "sysadmin"); - testRestClient.getAndSetUserToken(tenant2AdminId.getId().toString()); + testRestClient.getAndSetUserToken(tenant2AdminId); checkUserDevices(tenant2Devices); } @@ -168,6 +170,13 @@ public class EdqsEntityDataQueryTest extends AbstractContainerTest { assertThat(retrievedDevices).hasSize(10); List retrievedDeviceNames = retrievedDevices.stream().map(entityData -> entityData.getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue()).toList(); assertThat(retrievedDeviceNames).containsExactlyInAnyOrderElementsOf(devices.stream().map(Device::getName).toList().subList(0, 10)); + + //check temperature + for (int i = 0; i < 10; i++) { + Map> latest = retrievedDevices.get(i).getLatest(); + String name = latest.get(EntityKeyType.ENTITY_FIELD).get("name").getValue(); + //assertThat(latest.get(EntityKeyType.TIME_SERIES).get("temperature").getValue()).isEqualTo(name.substring(name.length() - 1)); + } } private String createDevices(String deviceType, List tenantDevices, int deviceCount) throws InterruptedException {