fixed flaky test, code refactoring

This commit is contained in:
dashevchenko 2025-02-27 17:31:46 +02:00
parent e360f56721
commit 02857b70bc
6 changed files with 59 additions and 45 deletions

View File

@ -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<AlarmDataQuery> {
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;
}

View File

@ -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<String> findByQueryAndCheckTelemetry(EntityDataQuery query, EntityKeyType entityKeyType, String key, List<String> 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);

View File

@ -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<EntityKey> latestValues = Collections.singletonList(new EntityKey(currentAttributeKeyType, "temperature"));
EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, null);
PageData<EntityData> data = findByQueryAndCheck(query, 67);
List<EntityData> loadedEntities = new ArrayList<>(data.getData());
while (data.hasNext()) {
query = query.next();
data = findByQuery(query);
loadedEntities.addAll(data.getData());
}
Assert.assertEquals(67, loadedEntities.size());
List<String> 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<String> deviceTemperatures = temperatures.stream().map(aLong -> Long.toString(aLong)).collect(Collectors.toList());
assertThat(loadedTemperatures).containsExactlyInAnyOrderElementsOf(deviceTemperatures);
List<String> 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<KeyFilter> 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<String> loadedHighTemperatures = loadedEntities.stream().map(entityData ->
entityData.getLatest().get(currentAttributeKeyType).get("temperature").getValue()).collect(Collectors.toList());
List<String> 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<EntityData> findByQuery(EntityDataQuery query) {
protected PageData<EntityData> 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<EntityData> findByQueryAndCheck(EntityDataQuery query, long expectedResultSize) {
protected PageData<EntityData> 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<String> findByQueryAndCheckTelemetry(EntityDataQuery query, EntityKeyType entityKeyType, String key, List<String> expectedTelemetry) {
List<String> entitiesTelemetry = findEntitiesTelemetry(query, entityKeyType, key, expectedTelemetry);
assertThat(entitiesTelemetry).containsExactlyInAnyOrderElementsOf(expectedTelemetry);
return entitiesTelemetry;
}
protected List<String> findEntitiesTelemetry(EntityDataQuery query, EntityKeyType entityKeyType, String key, List<String> expectedTelemetries) {
PageData<EntityData> data = findByQueryAndCheck(query, expectedTelemetries.size());
List<EntityData> 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);
}

View File

@ -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();

View File

@ -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);

View File

@ -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<String> 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<EntityKeyType, Map<String, TsValue>> 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<Device> tenantDevices, int deviceCount) throws InterruptedException {