Browse Source

Merge pull request #12366 from smatvienko-tb/feature/tbel-test-refactor

tbel test refactoring
pull/12377/merge
Viacheslav Klimov 2 years ago
committed by GitHub
parent
commit
c4925bd8af
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      application/src/main/java/org/thingsboard/server/service/ttl/AlarmsCleanUpService.java
  2. 31
      application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java
  3. 5
      application/src/test/java/org/thingsboard/server/service/script/AbstractTbelInvokeTest.java
  4. 2
      application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java
  5. 19
      application/src/test/java/org/thingsboard/server/service/script/TbelInvokeServiceTest.java
  6. 17
      application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java

10
application/src/main/java/org/thingsboard/server/service/ttl/AlarmsCleanUpService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.service.ttl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -66,7 +67,7 @@ public class AlarmsCleanUpService {
try { try {
cleanUp(tenantId); cleanUp(tenantId);
} catch (Exception e) { } catch (Exception e) {
log.warn("Failed to clean up alarms by ttl for tenant {}", tenantId, e); getLogger().warn("Failed to clean up alarms by ttl for tenant {}", tenantId, e);
} }
} }
} }
@ -105,8 +106,13 @@ public class AlarmsCleanUpService {
alarmService.delAlarmTypes(tenantId, typesToRemove); alarmService.delAlarmTypes(tenantId, typesToRemove);
if (totalRemoved > 0) { if (totalRemoved > 0) {
log.info("Removed {} outdated alarm(s) for tenant {} older than {}", totalRemoved, tenantId, new Date(expirationTime)); getLogger().info("Removed {} outdated alarm(s) for tenant {} older than {}", totalRemoved, tenantId, new Date(expirationTime));
} }
} }
// wrapper for tests to spy on static logger
Logger getLogger() {
return log;
}
} }

31
application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java

@ -149,10 +149,6 @@ import org.thingsboard.server.service.security.auth.rest.LoginRequest;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
import java.io.IOException; import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
@ -1053,33 +1049,6 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
throw new AssertionError("Unexpected status " + mvcResult.getResponse().getStatus()); throw new AssertionError("Unexpected status " + mvcResult.getResponse().getStatus());
} }
protected static <T> T getFieldValue(Object target, String fieldName) throws Exception {
Field field = target.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (T) field.get(target);
}
protected static void setStaticFieldValue(Class<?> targetCls, String fieldName, Object value) throws Exception {
Field field = targetCls.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(null, value);
}
protected static void setStaticFinalFieldValue(Class<?> targetCls, String fieldName, Object value) throws Exception {
Field field = targetCls.getDeclaredField(fieldName);
field.setAccessible(true);
// Get the VarHandle for the 'modifiers' field in the Field class
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
VarHandle modifiersHandle = lookup.findVarHandle(Field.class, "modifiers", int.class);
// Remove the final modifier from the field
int currentModifiers = field.getModifiers();
modifiersHandle.set(field, currentModifiers & ~Modifier.FINAL);
// Set the new value
field.set(null, value);
}
protected int getDeviceActorSubscriptionCount(DeviceId deviceId, FeatureType featureType) { protected int getDeviceActorSubscriptionCount(DeviceId deviceId, FeatureType featureType) {
DeviceActorMessageProcessor processor = getDeviceActorProcessor(deviceId); DeviceActorMessageProcessor processor = getDeviceActorProcessor(deviceId);
Map<UUID, SessionInfo> subscriptions = (Map<UUID, SessionInfo>) ReflectionTestUtils.getField(processor, getMapName(featureType)); Map<UUID, SessionInfo> subscriptions = (Map<UUID, SessionInfo>) ReflectionTestUtils.getField(processor, getMapName(featureType));

5
application/src/test/java/org/thingsboard/server/service/script/AbstractTbelInvokeTest.java

@ -16,8 +16,10 @@
package org.thingsboard.server.service.script; package org.thingsboard.server.service.script;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.ScriptType; import org.thingsboard.script.api.ScriptType;
import org.thingsboard.script.api.tbel.DefaultTbelInvokeService;
import org.thingsboard.script.api.tbel.TbelInvokeService; import org.thingsboard.script.api.tbel.TbelInvokeService;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.controller.AbstractControllerTest; import org.thingsboard.server.controller.AbstractControllerTest;
@ -28,7 +30,8 @@ import java.util.concurrent.ExecutionException;
import static org.thingsboard.server.common.data.msg.TbMsgType.POST_TELEMETRY_REQUEST; import static org.thingsboard.server.common.data.msg.TbMsgType.POST_TELEMETRY_REQUEST;
public abstract class AbstractTbelInvokeTest extends AbstractControllerTest { @SpringBootTest(classes = DefaultTbelInvokeService.class)
public abstract class AbstractTbelInvokeTest {
@Autowired @Autowired
protected TbelInvokeService invokeService; protected TbelInvokeService invokeService;

2
application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java

@ -18,7 +18,6 @@ package org.thingsboard.server.service.script;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.tbel.TbDate; import org.thingsboard.script.api.tbel.TbDate;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
@ -34,7 +33,6 @@ import java.util.concurrent.atomic.AtomicReference;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@DaoSqlTest
class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest {
private String decoderStr; private String decoderStr;

19
application/src/test/java/org/thingsboard/server/service/script/TbelInvokeServiceTest.java

@ -22,9 +22,9 @@ import org.junit.Ignore;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import org.springframework.test.util.ReflectionTestUtils;
import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.tbel.TbelScript; import org.thingsboard.script.api.tbel.TbelScript;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
@ -38,7 +38,6 @@ import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
@DaoSqlTest
@TestPropertySource(properties = { @TestPropertySource(properties = {
"tbel.max_script_body_size=100", "tbel.max_script_body_size=100",
"tbel.max_total_args_size=50", "tbel.max_total_args_size=50",
@ -120,9 +119,9 @@ class TbelInvokeServiceTest extends AbstractTbelInvokeTest {
scriptsIds.add(scriptId); scriptsIds.add(scriptId);
} }
Map<UUID, String> scriptIdToHash = getFieldValue(invokeService, "scriptIdToHash"); Map<UUID, String> scriptIdToHash = (Map<UUID, String>) ReflectionTestUtils.getField(invokeService, "scriptIdToHash");
Map<String, TbelScript> scriptMap = getFieldValue(invokeService, "scriptMap"); Map<String, TbelScript> scriptMap = (Map<String, TbelScript>) ReflectionTestUtils.getField(invokeService, "scriptMap");
Cache<String, Serializable> compiledScriptsCache = getFieldValue(invokeService, "compiledScriptsCache"); Cache<String, Serializable> compiledScriptsCache = (Cache<String, Serializable>) ReflectionTestUtils.getField(invokeService, "compiledScriptsCache");
String scriptHash = scriptIdToHash.get(scriptsIds.get(0)); String scriptHash = scriptIdToHash.get(scriptsIds.get(0));
@ -140,9 +139,9 @@ class TbelInvokeServiceTest extends AbstractTbelInvokeTest {
scriptsIds.add(scriptId); scriptsIds.add(scriptId);
} }
Map<UUID, String> scriptIdToHash = getFieldValue(invokeService, "scriptIdToHash"); Map<UUID, String> scriptIdToHash = (Map<UUID, String>) ReflectionTestUtils.getField(invokeService, "scriptIdToHash");
Map<String, TbelScript> scriptMap = getFieldValue(invokeService, "scriptMap"); Map<String, TbelScript> scriptMap = (Map<String, TbelScript>) ReflectionTestUtils.getField(invokeService, "scriptMap");
Cache<String, Serializable> compiledScriptsCache = getFieldValue(invokeService, "compiledScriptsCache"); Cache<String, Serializable> compiledScriptsCache = (Cache<String, Serializable>) ReflectionTestUtils.getField(invokeService, "compiledScriptsCache");
String scriptHash = scriptIdToHash.get(scriptsIds.get(0)); String scriptHash = scriptIdToHash.get(scriptsIds.get(0));
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
@ -163,8 +162,8 @@ class TbelInvokeServiceTest extends AbstractTbelInvokeTest {
@Ignore("This test is based on assumption that Caffeine cache is LRU based but in fact it is based on " + @Ignore("This test is based on assumption that Caffeine cache is LRU based but in fact it is based on " +
"Tiny LFU which is the cause that the tests fail sometime: https://arxiv.org/pdf/1512.00727.pdf") "Tiny LFU which is the cause that the tests fail sometime: https://arxiv.org/pdf/1512.00727.pdf")
public void whenCompiledScriptsCacheIsTooBig_thenRemoveRarelyUsedScripts() throws Exception { public void whenCompiledScriptsCacheIsTooBig_thenRemoveRarelyUsedScripts() throws Exception {
Map<UUID, String> scriptIdToHash = getFieldValue(invokeService, "scriptIdToHash"); Map<UUID, String> scriptIdToHash = (Map<UUID, String>) ReflectionTestUtils.getField(invokeService, "scriptIdToHash");
Cache<String, Serializable> compiledScriptsCache = getFieldValue(invokeService, "compiledScriptsCache"); Cache<String, Serializable> compiledScriptsCache = (Cache<String, Serializable>) ReflectionTestUtils.getField(invokeService, "compiledScriptsCache");
List<UUID> scriptsIds = new ArrayList<>(); List<UUID> scriptsIds = new ArrayList<>();
for (int i = 0; i < 110; i++) { // tbel.compiled_scripts_cache_size = 100 for (int i = 0; i < 110; i++) { // tbel.compiled_scripts_cache_size = 100

17
application/src/test/java/org/thingsboard/server/service/ttl/AlarmsCleanUpServiceTest.java

@ -15,7 +15,7 @@
*/ */
package org.thingsboard.server.service.ttl; package org.thingsboard.server.service.ttl;
import org.junit.BeforeClass; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -40,6 +40,7 @@ import java.util.concurrent.TimeUnit;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.startsWith; import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.BDDMockito.willReturn;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -49,19 +50,19 @@ import static org.mockito.Mockito.verify;
}) })
public class AlarmsCleanUpServiceTest extends AbstractControllerTest { public class AlarmsCleanUpServiceTest extends AbstractControllerTest {
@Autowired @SpyBean
private AlarmsCleanUpService alarmsCleanUpService; private AlarmsCleanUpService alarmsCleanUpService;
@SpyBean @SpyBean
private AlarmService alarmService; private AlarmService alarmService;
@Autowired @Autowired
private AlarmDao alarmDao; private AlarmDao alarmDao;
private static Logger cleanUpServiceLogger; private Logger cleanUpServiceLoggerSpy;
@BeforeClass @Before
public static void before() throws Exception { public void beforeEach() throws Exception {
cleanUpServiceLogger = Mockito.spy(LoggerFactory.getLogger(AlarmsCleanUpService.class)); cleanUpServiceLoggerSpy = Mockito.spy(LoggerFactory.getLogger(AlarmsCleanUpService.class));
setStaticFinalFieldValue(AlarmsCleanUpService.class, "log", cleanUpServiceLogger); willReturn(cleanUpServiceLoggerSpy).given(alarmsCleanUpService).getLogger();
} }
@Test @Test
@ -110,7 +111,7 @@ public class AlarmsCleanUpServiceTest extends AbstractControllerTest {
verify(alarmService, never()).delAlarm(eq(tenantId), eq(freshAlarm), eq(false)); verify(alarmService, never()).delAlarm(eq(tenantId), eq(freshAlarm), eq(false));
} }
verify(cleanUpServiceLogger).info(startsWith("Removed {} outdated alarm"), eq((long) count), eq(tenantId), any()); verify(cleanUpServiceLoggerSpy).info(startsWith("Removed {} outdated alarm"), eq((long) count), eq(tenantId), any());
} }
} }

Loading…
Cancel
Save