diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java index 9eb74b5627..84bbafe825 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java @@ -15,20 +15,21 @@ */ package org.thingsboard.rule.engine.metadata; -import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.Futures; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.provider.Arguments; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.thingsboard.common.util.AbstractListeningExecutor; import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.TbMsgSource; @@ -43,7 +44,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.msg.TbMsgType; -import org.thingsboard.server.common.data.util.TbPair; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.dao.attributes.AttributesService; @@ -51,25 +51,26 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) -public class TbGetAttributesNodeTest { +public class TbGetAttributesNodeTest extends AbstractRuleNodeUpgradeTest { - private static final EntityId ORIGINATOR = new DeviceId(Uuids.timeBased()); - private static final TenantId TENANT_ID = TenantId.fromUUID(Uuids.timeBased()); + private final EntityId ORIGINATOR_ID = new DeviceId(UUID.fromString("965f2975-787a-4f21-87e6-9aa4738186ff")); + private final TenantId TENANT_ID = TenantId.fromUUID(UUID.fromString("befd3239-79b8-4263-a8d1-95b69f44f798")); private AbstractListeningExecutor dbExecutor; @Mock @@ -84,6 +85,8 @@ public class TbGetAttributesNodeTest { private List sharedAttributes; private List tsKeys; private long ts; + + @Spy private TbGetAttributesNode node; @BeforeEach @@ -107,16 +110,16 @@ public class TbGetAttributesNodeTest { tsKeys = List.of("temperature", "humidity", "unknown"); ts = System.currentTimeMillis(); - lenient().when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, AttributeScope.CLIENT_SCOPE, clientAttributes)) + lenient().when(attributesServiceMock.find(TENANT_ID, ORIGINATOR_ID, AttributeScope.CLIENT_SCOPE, clientAttributes)) .thenReturn(Futures.immediateFuture(getListAttributeKvEntry(clientAttributes, ts))); - lenient().when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, AttributeScope.SERVER_SCOPE, serverAttributes)) + lenient().when(attributesServiceMock.find(TENANT_ID, ORIGINATOR_ID, AttributeScope.SERVER_SCOPE, serverAttributes)) .thenReturn(Futures.immediateFuture(getListAttributeKvEntry(serverAttributes, ts))); - lenient().when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, AttributeScope.SHARED_SCOPE, sharedAttributes)) + lenient().when(attributesServiceMock.find(TENANT_ID, ORIGINATOR_ID, AttributeScope.SHARED_SCOPE, sharedAttributes)) .thenReturn(Futures.immediateFuture(getListAttributeKvEntry(sharedAttributes, ts))); - lenient().when(timeseriesServiceMock.findLatest(TENANT_ID, ORIGINATOR, tsKeys)) + lenient().when(timeseriesServiceMock.findLatest(TENANT_ID, ORIGINATOR_ID, tsKeys)) .thenReturn(Futures.immediateFuture(getListTsKvEntry(tsKeys, ts))); } @@ -129,7 +132,7 @@ public class TbGetAttributesNodeTest { public void givenFetchAttributesToMetadata_whenOnMsg_thenShouldTellSuccess() throws Exception { // GIVEN node = initNode(TbMsgSource.METADATA, false, false); - var msg = getTbMsg(ORIGINATOR); + var msg = getTbMsg(ORIGINATOR_ID); // WHEN node.onMsg(ctxMock, msg); @@ -148,7 +151,7 @@ public class TbGetAttributesNodeTest { public void givenFetchLatestTimeseriesToMetadata_whenOnMsg_thenShouldTellSuccess() throws Exception { // GIVEN node = initNode(TbMsgSource.METADATA, true, false); - var msg = getTbMsg(ORIGINATOR); + var msg = getTbMsg(ORIGINATOR_ID); // WHEN node.onMsg(ctxMock, msg); @@ -167,7 +170,7 @@ public class TbGetAttributesNodeTest { public void givenFetchAttributesToData_whenOnMsg_thenShouldTellSuccess() throws Exception { // GIVEN node = initNode(TbMsgSource.DATA, false, false); - var msg = getTbMsg(ORIGINATOR); + var msg = getTbMsg(ORIGINATOR_ID); // WHEN node.onMsg(ctxMock, msg); @@ -186,7 +189,7 @@ public class TbGetAttributesNodeTest { public void givenFetchLatestTimeseriesToData_whenOnMsg_thenShouldTellSuccess() throws Exception { // GIVEN node = initNode(TbMsgSource.DATA, true, false); - var msg = getTbMsg(ORIGINATOR); + var msg = getTbMsg(ORIGINATOR_ID); // WHEN node.onMsg(ctxMock, msg); @@ -205,7 +208,7 @@ public class TbGetAttributesNodeTest { public void givenFetchAttributesToMetadata_whenOnMsg_thenShouldTellFailure() throws Exception { // GIVEN node = initNode(TbMsgSource.METADATA, false, true); - var msg = getTbMsg(ORIGINATOR); + var msg = getTbMsg(ORIGINATOR_ID); // WHEN node.onMsg(ctxMock, msg); @@ -224,7 +227,7 @@ public class TbGetAttributesNodeTest { public void givenFetchLatestTimeseriesToData_whenOnMsg_thenShouldTellFailure() throws Exception { // GIVEN node = initNode(TbMsgSource.DATA, true, true); - var msg = getTbMsg(ORIGINATOR); + var msg = getTbMsg(ORIGINATOR_ID); // WHEN node.onMsg(ctxMock, msg); @@ -243,7 +246,7 @@ public class TbGetAttributesNodeTest { public void givenFetchLatestTimeseriesToDataAndDataIsNotJsonObject_whenOnMsg_thenException() throws Exception { // GIVEN node = initNode(TbMsgSource.DATA, true, true); - var msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ORIGINATOR, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_ARRAY); + var msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, ORIGINATOR_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_ARRAY); // WHEN var exception = assertThrows(IllegalArgumentException.class, () -> node.onMsg(ctxMock, msg)); @@ -253,56 +256,6 @@ public class TbGetAttributesNodeTest { assertThat(exception.getMessage()).isEqualTo("Message body is not an object!"); } - @Test - public void givenOldConfig_whenUpgrade_thenShouldReturnTrueResultWithNewConfig() throws Exception { - var defaultConfig = new TbGetAttributesNodeConfiguration().defaultConfiguration(); - var node = new TbGetAttributesNode(); - String oldConfig = "{\"fetchToData\":false," + - "\"clientAttributeNames\":[]," + - "\"sharedAttributeNames\":[]," + - "\"serverAttributeNames\":[]," + - "\"latestTsKeyNames\":[]," + - "\"tellFailureIfAbsent\":true," + - "\"getLatestValueWithTs\":false}"; - JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); - TbPair upgrade = node.upgrade(0, configJson); - Assertions.assertTrue(upgrade.getFirst()); - Assertions.assertEquals(defaultConfig, JacksonUtil.treeToValue(upgrade.getSecond(), defaultConfig.getClass())); - } - - @Test - public void givenOldConfigWithNoFetchToDataProperty_whenUpgrade_thenShouldReturnTrueResultWithNewConfig() throws Exception { - var defaultConfig = new TbGetAttributesNodeConfiguration().defaultConfiguration(); - var node = new TbGetAttributesNode(); - String oldConfig = "{\"clientAttributeNames\":[]," + - "\"sharedAttributeNames\":[]," + - "\"serverAttributeNames\":[]," + - "\"latestTsKeyNames\":[]," + - "\"tellFailureIfAbsent\":true," + - "\"getLatestValueWithTs\":false}"; - JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); - TbPair upgrade = node.upgrade(0, configJson); - Assertions.assertTrue(upgrade.getFirst()); - Assertions.assertEquals(defaultConfig, JacksonUtil.treeToValue(upgrade.getSecond(), defaultConfig.getClass())); - } - - @Test - public void givenOldConfigWithNullFetchToDataProperty_whenUpgrade_thenShouldReturnTrueResultWithNewConfig() throws Exception { - var defaultConfig = new TbGetAttributesNodeConfiguration().defaultConfiguration(); - var node = new TbGetAttributesNode(); - String oldConfig = "{\"fetchToData\":null," + - "\"clientAttributeNames\":[]," + - "\"sharedAttributeNames\":[]," + - "\"serverAttributeNames\":[]," + - "\"latestTsKeyNames\":[]," + - "\"tellFailureIfAbsent\":true," + - "\"getLatestValueWithTs\":false}"; - JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); - TbPair upgrade = node.upgrade(0, configJson); - Assertions.assertTrue(upgrade.getFirst()); - Assertions.assertEquals(defaultConfig, JacksonUtil.treeToValue(upgrade.getSecond(), defaultConfig.getClass())); - } - private TbMsg checkMsg(boolean checkSuccess) { var msgCaptor = ArgumentCaptor.forClass(TbMsg.class); if (checkSuccess) { @@ -421,4 +374,117 @@ public class TbGetAttributesNodeTest { return kvEntriesList; } + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // config for version 1 with upgrade from version 0 + Arguments.of(0, + """ + { + "fetchToData":false, + "clientAttributeNames":[], + "sharedAttributeNames":[], + "serverAttributeNames":[], + "latestTsKeyNames":[], + "tellFailureIfAbsent":true, + "getLatestValueWithTs":false + } + """, + true, + """ + { + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ), + // config for version 1 with upgrade from version 0 (old config with no fetchToData property) + Arguments.of(0, + """ + { + "clientAttributeNames":[], + "sharedAttributeNames":[],"serverAttributeNames":[], + "latestTsKeyNames":[], + "tellFailureIfAbsent":true, + "getLatestValueWithTs":false + } + """, + true, + """ + { + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ), + // config for version 1 with upgrade from version 0 (old config with null fetchToData property) + Arguments.of(0, + """ + { + "fetchToData":null, + "clientAttributeNames":[], + "sharedAttributeNames":[], + "serverAttributeNames":[], + "latestTsKeyNames":[], + "tellFailureIfAbsent":true, + "getLatestValueWithTs":false + } + """, + true, + """ + { + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ), + // config for version 1 with upgrade from version 1 + Arguments.of(1, + """ + { + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """, + false, + """ + { + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ) + ); + + } + + @Override + protected TbNode getTestNode() { + return node; + } + } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java index ac6bb38be5..8cacf33f79 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetDeviceAttrNodeTest.java @@ -15,68 +15,236 @@ */ package org.thingsboard.rule.engine.metadata; -import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.util.concurrent.Futures; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.provider.Arguments; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import org.thingsboard.common.util.JacksonUtil; -import org.thingsboard.server.common.data.util.TbPair; +import org.thingsboard.common.util.ListeningExecutor; +import org.thingsboard.rule.engine.AbstractRuleNodeUpgradeTest; +import org.thingsboard.rule.engine.TestDbCallbackExecutor; +import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.rule.engine.api.TbNode; +import org.thingsboard.rule.engine.api.TbNodeConfiguration; +import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.rule.engine.data.DeviceRelationsQuery; +import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.device.DeviceSearchQuery; +import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.msg.TbMsgType; +import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.EntitySearchDirection; +import org.thingsboard.server.common.msg.TbMsg; +import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.dao.device.DeviceService; -public class TbGetDeviceAttrNodeTest { +import java.util.Arrays; +import java.util.Collections; +import java.util.NoSuchElementException; +import java.util.UUID; +import java.util.stream.Stream; - @Test - public void givenOldConfig_whenUpgrade_thenShouldReturnTrueResultWithNewConfig() throws Exception { - var defaultConfig = new TbGetDeviceAttrNodeConfiguration().defaultConfiguration(); - var node = new TbGetDeviceAttrNode(); - String oldConfig = "{\"fetchToData\":false," + - "\"clientAttributeNames\":[]," + - "\"sharedAttributeNames\":[]," + - "\"serverAttributeNames\":[]," + - "\"latestTsKeyNames\":[]," + - "\"tellFailureIfAbsent\":true," + - "\"getLatestValueWithTs\":false," + - "\"deviceRelationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1,\"relationType\":\"Contains\",\"deviceTypes\":[\"default\"]," + - "\"fetchLastLevelOnly\":false}}"; - JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); - TbPair upgrade = node.upgrade(0, configJson); - Assertions.assertTrue(upgrade.getFirst()); - Assertions.assertEquals(defaultConfig, JacksonUtil.treeToValue(upgrade.getSecond(), defaultConfig.getClass())); +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.spy; +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class TbGetDeviceAttrNodeTest extends AbstractRuleNodeUpgradeTest { + + private final TenantId TENANT_ID = new TenantId(UUID.fromString("5aea576c-66c4-4732-86b8-dc6bfcde7443")); + private final DeviceId DEVICE_ID = new DeviceId(UUID.fromString("40b6b393-6ddf-47f9-973a-18550ca70384")); + private final ListeningExecutor executor = new TestDbCallbackExecutor(); + + + private TbGetDeviceAttrNode node; + private TbGetDeviceAttrNodeConfiguration config; + + @Mock + private TbContext ctxMock; + @Mock + private DeviceService deviceServiceMock; + + @BeforeEach + public void setUp() { + node = spy(new TbGetDeviceAttrNode()); + config = new TbGetDeviceAttrNodeConfiguration().defaultConfiguration(); } @Test - public void givenOldConfigWithNoFetchToDataProperty_whenUpgrade_thenShouldReturnTrueResultWithNewConfig() throws Exception { - var defaultConfig = new TbGetDeviceAttrNodeConfiguration().defaultConfiguration(); - var node = new TbGetDeviceAttrNode(); - String oldConfig = "{\"clientAttributeNames\":[]," + - "\"sharedAttributeNames\":[]," + - "\"serverAttributeNames\":[]," + - "\"latestTsKeyNames\":[]," + - "\"tellFailureIfAbsent\":true," + - "\"getLatestValueWithTs\":false," + - "\"deviceRelationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1,\"relationType\":\"Contains\",\"deviceTypes\":[\"default\"]," + - "\"fetchLastLevelOnly\":false}}"; - JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); - TbPair upgrade = node.upgrade(0, configJson); - Assertions.assertTrue(upgrade.getFirst()); - Assertions.assertEquals(defaultConfig, JacksonUtil.treeToValue(upgrade.getSecond(), defaultConfig.getClass())); + public void verifyDefaultConfig() { + assertThat(config.getClientAttributeNames()).isEmpty(); + assertThat(config.getSharedAttributeNames()).isEmpty(); + assertThat(config.getServerAttributeNames()).isEmpty(); + assertThat(config.getLatestTsKeyNames()).isEmpty(); + assertThat(config.isTellFailureIfAbsent()).isTrue(); + assertThat(config.isGetLatestValueWithTs()).isFalse(); + assertThat(config.getFetchTo()).isEqualTo(TbMsgSource.METADATA); + + var deviceRelationsQuery = new DeviceRelationsQuery(); + deviceRelationsQuery.setDirection(EntitySearchDirection.FROM); + deviceRelationsQuery.setMaxLevel(1); + deviceRelationsQuery.setRelationType(EntityRelation.CONTAINS_TYPE); + deviceRelationsQuery.setDeviceTypes(Collections.singletonList("default")); + + assertThat(config.getDeviceRelationsQuery()).isEqualTo(deviceRelationsQuery); } @Test - public void givenOldConfigWithNullFetchToDataProperty_whenUpgrade_thenShouldReturnTrueResultWithNewConfig() throws Exception { - var defaultConfig = new TbGetDeviceAttrNodeConfiguration().defaultConfiguration(); - var node = new TbGetDeviceAttrNode(); - String oldConfig = "{\"fetchToData\":null," + - "\"clientAttributeNames\":[]," + - "\"sharedAttributeNames\":[]," + - "\"serverAttributeNames\":[]," + - "\"latestTsKeyNames\":[]," + - "\"tellFailureIfAbsent\":true," + - "\"getLatestValueWithTs\":false," + - "\"deviceRelationsQuery\":{\"direction\":\"FROM\",\"maxLevel\":1,\"relationType\":\"Contains\",\"deviceTypes\":[\"default\"]," + - "\"fetchLastLevelOnly\":false}}"; - JsonNode configJson = JacksonUtil.toJsonNode(oldConfig); - TbPair upgrade = node.upgrade(0, configJson); - Assertions.assertTrue(upgrade.getFirst()); - Assertions.assertEquals(defaultConfig, JacksonUtil.treeToValue(upgrade.getSecond(), defaultConfig.getClass())); + public void givenFetchToIsNull_whenInit_thenThrowsException() { + config.setFetchTo(null); + assertThatThrownBy(() -> node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config)))) + .isInstanceOf(TbNodeException.class) + .hasMessage("FetchTo option can't be null! Allowed values: " + Arrays.toString(TbMsgSource.values())); + } + + @Test + public void givenDeviceDoesNotExist_whenOnMsg_thenTellFailure() throws TbNodeException { + node.init(ctxMock, new TbNodeConfiguration(JacksonUtil.valueToTree(config))); + + given(ctxMock.getDeviceService()).willReturn(deviceServiceMock); + given(ctxMock.getTenantId()).willReturn(TENANT_ID); + given(deviceServiceMock.findDevicesByQuery(any(TenantId.class), any(DeviceSearchQuery.class))).willReturn(Futures.immediateFuture(Collections.emptyList())); + given(ctxMock.getDbCallbackExecutor()).willReturn(executor); + + TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, DEVICE_ID, TbMsgMetaData.EMPTY, TbMsg.EMPTY_JSON_OBJECT); + node.onMsg(ctxMock, msg); + + ArgumentCaptor actualException = ArgumentCaptor.forClass(Throwable.class); + then(ctxMock).should().tellFailure(eq(msg), actualException.capture()); + assertThat(actualException.getValue()) + .isInstanceOf(NoSuchElementException.class) + .hasMessage("Failed to find related device to message originator using relation query specified in the configuration!"); + } + + private static Stream givenFromVersionAndConfig_whenUpgrade_thenVerifyHasChangesAndConfig() { + return Stream.of( + // config for version 1 with upgrade from version 0 + Arguments.of(0, + """ + { + "fetchToData":false, + "clientAttributeNames":[], + "sharedAttributeNames":[], + "serverAttributeNames":[], + "latestTsKeyNames":[], + "tellFailureIfAbsent":true, + "getLatestValueWithTs":false, + "deviceRelationsQuery":{"direction":"FROM","maxLevel":1,"relationType":"Contains","deviceTypes":["default"],"fetchLastLevelOnly":false} + } + """, + true, + """ + { + "deviceRelationsQuery": {"direction": "FROM","maxLevel": 1, "relationType": "Contains","deviceTypes": ["default"],"fetchLastLevelOnly": false}, + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ), + // config for version 1 with upgrade from version 0 (old config with no fetchToData property) + Arguments.of(0, + """ + { + "clientAttributeNames":[], + "sharedAttributeNames":[], + "serverAttributeNames":[], + "latestTsKeyNames":[], + "tellFailureIfAbsent":true, + "getLatestValueWithTs":false, + "deviceRelationsQuery":{"direction":"FROM","maxLevel":1,"relationType":"Contains","deviceTypes":["default"],"fetchLastLevelOnly":false} + } + """, + true, + """ + { + "deviceRelationsQuery": {"direction": "FROM","maxLevel": 1, "relationType": "Contains","deviceTypes": ["default"],"fetchLastLevelOnly": false}, + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ), + // config for version 1 with upgrade from version 0 (old config with null fetchToData property) + Arguments.of(0, + """ + { + "fetchToData":null, + "clientAttributeNames":[], + "sharedAttributeNames":[], + "serverAttributeNames":[], + "latestTsKeyNames":[], + "tellFailureIfAbsent":true, + "getLatestValueWithTs":false, + "deviceRelationsQuery":{"direction":"FROM","maxLevel":1,"relationType":"Contains","deviceTypes":["default"],"fetchLastLevelOnly":false} + } + """, + true, + """ + { + "deviceRelationsQuery": {"direction": "FROM","maxLevel": 1, "relationType": "Contains","deviceTypes": ["default"],"fetchLastLevelOnly": false}, + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ), + // config for version 1 with upgrade from version 1 + Arguments.of(1, + """ + { + "deviceRelationsQuery": {"direction": "FROM","maxLevel": 1, "relationType": "Contains","deviceTypes": ["default"],"fetchLastLevelOnly": false}, + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """, + false, + """ + { + "deviceRelationsQuery": {"direction": "FROM","maxLevel": 1, "relationType": "Contains","deviceTypes": ["default"],"fetchLastLevelOnly": false}, + "tellFailureIfAbsent": true, + "fetchTo": "METADATA", + "clientAttributeNames": [], + "sharedAttributeNames": [], + "serverAttributeNames": [], + "latestTsKeyNames": [], + "getLatestValueWithTs": false + } + """ + ) + ); + + } + + @Override + protected TbNode getTestNode() { + return node; } }