Browse Source

Merge pull request #14681 from irynamatveieva/entity-agg-cf/improvements

Entity aggregation calculated field: improvements
pull/14708/head
Viacheslav Klimov 7 months ago
committed by GitHub
parent
commit
9cb468bdda
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java
  2. 2
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ArgumentEntry.java
  3. 8
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/BaseCalculatedFieldState.java
  4. 2
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SingleValueArgumentEntry.java
  5. 2
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntry.java
  6. 5
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/RelatedEntitiesArgumentEntry.java
  7. 68
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationArgumentEntry.java
  8. 9
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationCalculatedFieldState.java
  9. 6
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java
  10. 3
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/geofencing/GeofencingArgumentEntry.java
  11. 3
      application/src/main/java/org/thingsboard/server/service/cf/ctx/state/propagation/PropagationArgumentEntry.java
  12. 53
      application/src/test/java/org/thingsboard/server/cf/EntityAggregationCalculatedFieldTest.java
  13. 25
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/GeofencingValueArgumentEntryTest.java
  14. 33
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/PropagationArgumentEntryTest.java
  15. 15
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/RelatedEntitiesArgumentEntryTest.java
  16. 23
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/SingleValueArgumentEntryTest.java
  17. 17
      application/src/test/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntryTest.java

15
application/src/main/java/org/thingsboard/server/actors/calculatedField/CalculatedFieldEntityMessageProcessor.java

@ -572,24 +572,24 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
}
private Map<String, ArgumentEntry> mapToArguments(CalculatedFieldCtx ctx, List<TsKvProto> data) {
return mapToArguments(entityId, ctx.getMainEntityArguments(), Collections.emptyMap(), data);
return mapToArguments(entityId, ctx, ctx.getMainEntityArguments(), Collections.emptyMap(), data);
}
private Map<String, ArgumentEntry> mapToArguments(CalculatedFieldCtx ctx, EntityId entityId, List<TsKvProto> data) {
return mapToArguments(entityId, ctx.getLinkedAndDynamicArgs(entityId), ctx.getRelatedEntityArguments(), data);
return mapToArguments(entityId, ctx, ctx.getLinkedAndDynamicArgs(entityId), ctx.getRelatedEntityArguments(), data);
}
private Map<String, ArgumentEntry> mapToArguments(EntityId originator, Map<ReferencedEntityKey, Set<String>> args, Map<ReferencedEntityKey, Set<String>> relatedEntityArgs, List<TsKvProto> data) {
private Map<String, ArgumentEntry> mapToArguments(EntityId originator, CalculatedFieldCtx ctx, Map<ReferencedEntityKey, Set<String>> args, Map<ReferencedEntityKey, Set<String>> relatedEntityArgs, List<TsKvProto> data) {
Map<String, ArgumentEntry> arguments = new HashMap<>();
if (!relatedEntityArgs.isEmpty() || !args.isEmpty()) {
for (TsKvProto item : data) {
ReferencedEntityKey key = new ReferencedEntityKey(item.getKv().getKey(), ArgumentType.TS_LATEST, null);
SingleValueArgumentEntry relatedArgIncoming = new SingleValueArgumentEntry(originator, item);
mapLatest(relatedArgIncoming, relatedEntityArgs.get(key), arguments);
mapLatest(ctx, relatedArgIncoming, relatedEntityArgs.get(key), arguments);
SingleValueArgumentEntry incoming = new SingleValueArgumentEntry(item);
mapLatest(incoming, args.get(key), arguments);
mapLatest(ctx, incoming, args.get(key), arguments);
key = new ReferencedEntityKey(item.getKv().getKey(), ArgumentType.TS_ROLLING, null);
mapRolling(item, args.get(key), arguments);
@ -598,7 +598,8 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
return arguments;
}
private void mapLatest(SingleValueArgumentEntry incoming,
private void mapLatest(CalculatedFieldCtx ctx,
SingleValueArgumentEntry incoming,
Set<String> argNames,
Map<String, ArgumentEntry> arguments) {
if (argNames != null) {
@ -606,7 +607,7 @@ public class CalculatedFieldEntityMessageProcessor extends AbstractContextAwareM
if (existing == null) {
return incoming;
}
existing.updateEntry(incoming);
existing.updateEntry(incoming, ctx);
return existing;
}));
}

2
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/ArgumentEntry.java

@ -52,7 +52,7 @@ public interface ArgumentEntry {
Object getValue();
boolean updateEntry(ArgumentEntry entry);
boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx);
boolean isEmpty();

8
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/BaseCalculatedFieldState.java

@ -86,13 +86,13 @@ public abstract class BaseCalculatedFieldState implements CalculatedFieldState,
validateNewEntry(key, newEntry);
if (existingEntry instanceof RelatedEntitiesArgumentEntry ||
existingEntry instanceof EntityAggregationArgumentEntry) {
updateEntry(existingEntry, newEntry);
updateEntry(existingEntry, newEntry, ctx);
} else {
arguments.put(key, newEntry);
}
entryUpdated = true;
} else {
entryUpdated = updateEntry(existingEntry, newEntry);
entryUpdated = updateEntry(existingEntry, newEntry, ctx);
}
if (entryUpdated) {
@ -111,8 +111,8 @@ public abstract class BaseCalculatedFieldState implements CalculatedFieldState,
return updatedArguments;
}
protected boolean updateEntry(ArgumentEntry existingEntry, ArgumentEntry newEntry) {
return existingEntry.updateEntry(newEntry);
protected boolean updateEntry(ArgumentEntry existingEntry, ArgumentEntry newEntry, CalculatedFieldCtx ctx) {
return existingEntry.updateEntry(newEntry, ctx);
}
@Override

2
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/SingleValueArgumentEntry.java

@ -159,7 +159,7 @@ public class SingleValueArgumentEntry implements ArgumentEntry {
}
@Override
public boolean updateEntry(ArgumentEntry entry) {
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (entry instanceof SingleValueArgumentEntry singleValueEntry) {
if (singleValueEntry.getTs() < this.ts) {
return false;

2
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntry.java

@ -100,7 +100,7 @@ public class TsRollingArgumentEntry implements ArgumentEntry, HasLatestTs {
}
@Override
public boolean updateEntry(ArgumentEntry entry) {
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (entry instanceof TsRollingArgumentEntry tsRollingEntry) {
updateTsRollingEntry(tsRollingEntry);
} else if (entry instanceof SingleValueArgumentEntry singleValueEntry) {

5
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/RelatedEntitiesArgumentEntry.java

@ -23,6 +23,7 @@ import org.thingsboard.script.api.tbel.TbelCfSingleValueArg;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntryType;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import org.thingsboard.server.service.cf.ctx.state.HasLatestTs;
import org.thingsboard.server.service.cf.ctx.state.SingleValueArgumentEntry;
@ -63,7 +64,7 @@ public class RelatedEntitiesArgumentEntry implements ArgumentEntry, HasLatestTs
}
@Override
public boolean updateEntry(ArgumentEntry entry) {
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (entry instanceof RelatedEntitiesArgumentEntry relatedEntitiesArgumentEntry) {
entityInputs.putAll(relatedEntitiesArgumentEntry.entityInputs);
return true;
@ -74,7 +75,7 @@ public class RelatedEntitiesArgumentEntry implements ArgumentEntry, HasLatestTs
}
ArgumentEntry argumentEntry = entityInputs.get(singleValueArgumentEntry.getEntityId());
if (argumentEntry != null) {
argumentEntry.updateEntry(singleValueArgumentEntry);
argumentEntry.updateEntry(singleValueArgumentEntry, ctx);
} else {
entityInputs.put(singleValueArgumentEntry.getEntityId(), singleValueArgumentEntry);
}

68
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationArgumentEntry.java

@ -19,11 +19,18 @@ import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.script.api.tbel.TbelCfArg;
import org.thingsboard.server.common.data.cf.configuration.aggregation.single.EntityAggregationCalculatedFieldConfiguration;
import org.thingsboard.server.common.data.cf.configuration.aggregation.single.interval.AggInterval;
import org.thingsboard.server.common.data.cf.configuration.aggregation.single.interval.Watermark;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntryType;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import org.thingsboard.server.service.cf.ctx.state.SingleValueArgumentEntry;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Data
public class EntityAggregationArgumentEntry implements ArgumentEntry {
@ -47,28 +54,63 @@ public class EntityAggregationArgumentEntry implements ArgumentEntry {
}
@Override
public boolean updateEntry(ArgumentEntry entry) {
boolean updated = false;
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (entry instanceof EntityAggregationArgumentEntry entityAggEntry) {
aggIntervals.putAll(entityAggEntry.getAggIntervals());
return true;
} else if (entry instanceof SingleValueArgumentEntry singleValueArgEntry) {
long entryTs = singleValueArgEntry.getTs();
long argUpdateTs = System.currentTimeMillis();
for (Map.Entry<AggIntervalEntry, AggIntervalEntryStatus> aggIntervalEntry : aggIntervals.entrySet()) {
if (singleValueArgEntry.isForceResetPrevious()) {
aggIntervalEntry.getValue().setLastArgsRefreshTs(argUpdateTs);
updated = true;
continue;
}
if (aggIntervalEntry.getKey().belongsToInterval(entryTs)) {
aggIntervalEntry.getValue().setLastArgsRefreshTs(argUpdateTs);
return true;
}
long now = System.currentTimeMillis();
if (updateExistingIntervals(singleValueArgEntry, entryTs, now)) {
return true;
}
return createNewInterval(entryTs, now, ctx);
}
return false;
}
private boolean updateExistingIntervals(SingleValueArgumentEntry entry, long entryTs, long now) {
boolean updated = false;
for (Map.Entry<AggIntervalEntry, AggIntervalEntryStatus> aggIntervalEntry : aggIntervals.entrySet()) {
AggIntervalEntry interval = aggIntervalEntry.getKey();
AggIntervalEntryStatus status = aggIntervalEntry.getValue();
if (entry.isForceResetPrevious()) {
status.setLastArgsRefreshTs(now);
updated = true;
continue;
}
if (interval.belongsToInterval(entryTs)) {
status.setLastArgsRefreshTs(now);
return true;
}
}
return updated;
}
private boolean createNewInterval(long entryTs, long now, CalculatedFieldCtx ctx) {
if (!(ctx.getCalculatedField().getConfiguration() instanceof EntityAggregationCalculatedFieldConfiguration config)) {
return false;
}
AggInterval interval = config.getInterval();
Watermark watermark = config.getWatermark();
long watermarkDuration = watermark == null ? 0 : TimeUnit.SECONDS.toMillis(watermark.getDuration());
ZonedDateTime zdt = ZonedDateTime.ofInstant(Instant.ofEpochMilli(entryTs), interval.getZoneId());
long startTs = interval.getDateTimeIntervalStartTs(zdt);
long endTs = interval.getDateTimeIntervalEndTs(zdt);
if (now - endTs > watermarkDuration) {
return false;
}
AggIntervalEntry newInterval = new AggIntervalEntry(startTs, endTs);
aggIntervals.computeIfAbsent(newInterval, i -> new AggIntervalEntryStatus(now));
return true;
}
@Override
public boolean isEmpty() {
return aggIntervals.isEmpty();

9
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/aggregation/single/EntityAggregationCalculatedFieldState.java

@ -154,8 +154,10 @@ public class EntityAggregationCalculatedFieldState extends BaseCalculatedFieldSt
}
private void fillMissingIntervals() {
long now = System.currentTimeMillis();
ZoneId zoneId = interval.getZoneId();
long currentIntervalEndTs = interval.getCurrentIntervalEndTs();
long watermarkThresholdTs = now - watermarkDuration;
Map<AggIntervalEntry, Map<String, AggIntervalEntryStatus>> intervals = getIntervals();
AggIntervalEntry lastIntervalEntry = intervals.keySet().stream().max(Comparator.comparing(AggIntervalEntry::getEndTs)).orElse(null);
@ -169,6 +171,13 @@ public class EntityAggregationCalculatedFieldState extends BaseCalculatedFieldSt
while (nextEnd.toInstant().toEpochMilli() <= currentIntervalEndTs) {
long nextStartTs = nextStart.toInstant().toEpochMilli();
long nextEndTs = nextEnd.toInstant().toEpochMilli();
if (nextEndTs < watermarkThresholdTs) {
nextStart = nextEnd;
nextEnd = interval.getNextIntervalStart(nextStart);
continue;
}
AggIntervalEntry missing = new AggIntervalEntry(nextStartTs, nextEndTs);
arguments.forEach((argName, argumentEntry) -> {

6
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/alarm/AlarmCalculatedFieldState.java

@ -225,17 +225,17 @@ public class AlarmCalculatedFieldState extends BaseCalculatedFieldState {
}
@Override
protected boolean updateEntry(ArgumentEntry existingArgumentEntry, ArgumentEntry newArgumentEntry) {
protected boolean updateEntry(ArgumentEntry existingArgumentEntry, ArgumentEntry newArgumentEntry, CalculatedFieldCtx ctx) {
if (!(existingArgumentEntry instanceof SingleValueArgumentEntry existingEntry) ||
!(newArgumentEntry instanceof SingleValueArgumentEntry newEntry)) {
return super.updateEntry(existingArgumentEntry, newArgumentEntry);
return super.updateEntry(existingArgumentEntry, newArgumentEntry, ctx);
}
if (newEntry.getTs() < existingEntry.getTs()) {
if (existingEntry.isDefaultValue()) {
existingEntry.setTs(newEntry.getTs());
}
}
return super.updateEntry(existingEntry, newEntry);
return super.updateEntry(existingEntry, newEntry, ctx);
}
public void processAlarmAction(Alarm alarm, ActionType action) {

3
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/geofencing/GeofencingArgumentEntry.java

@ -25,6 +25,7 @@ import org.thingsboard.server.common.util.ProtoUtils;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntryType;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import org.thingsboard.server.service.cf.ctx.state.HasLatestTs;
import java.util.Map;
@ -68,7 +69,7 @@ public class GeofencingArgumentEntry implements ArgumentEntry, HasLatestTs {
}
@Override
public boolean updateEntry(ArgumentEntry entry) {
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (!(entry instanceof GeofencingArgumentEntry geofencingArgumentEntry)) {
throw new IllegalArgumentException("Unsupported argument entry type for geofencing argument entry: " + entry.getType());
}

3
application/src/main/java/org/thingsboard/server/service/cf/ctx/state/propagation/PropagationArgumentEntry.java

@ -21,6 +21,7 @@ import org.thingsboard.script.api.tbel.TbelCfPropagationArg;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntry;
import org.thingsboard.server.service.cf.ctx.state.ArgumentEntryType;
import org.thingsboard.server.service.cf.ctx.state.CalculatedFieldCtx;
import java.util.ArrayList;
import java.util.Collection;
@ -59,7 +60,7 @@ public class PropagationArgumentEntry implements ArgumentEntry {
}
@Override
public boolean updateEntry(ArgumentEntry entry) {
public boolean updateEntry(ArgumentEntry entry, CalculatedFieldCtx ctx) {
if (!(entry instanceof PropagationArgumentEntry updated)) {
throw new IllegalArgumentException("Unsupported argument entry type for propagation argument entry: " + entry.getType());
}

53
application/src/test/java/org/thingsboard/server/cf/EntityAggregationCalculatedFieldTest.java

@ -55,6 +55,8 @@ import static org.thingsboard.server.cf.CalculatedFieldIntegrationTest.POLL_INTE
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class EntityAggregationCalculatedFieldTest extends AbstractControllerTest {
private final String TZ = "Europe/Kyiv";
private Tenant savedTenant;
@Before
@ -93,7 +95,7 @@ public class EntityAggregationCalculatedFieldTest extends AbstractControllerTest
public void testCreateCfAndNoTelemetryDuringInterval_checkAggregation() throws Exception {
Device device = createDevice("Device", "1234567890111");
CustomInterval customInterval = new CustomInterval("Europe/Kyiv", 0L, 5L);
CustomInterval customInterval = new CustomInterval(TZ, 0L, 5L);
createConsumptionCF(device.getId(), customInterval, null);
long interval = customInterval.getCurrentIntervalDurationMillis();
@ -113,7 +115,7 @@ public class EntityAggregationCalculatedFieldTest extends AbstractControllerTest
public void testCreateCfWithoutWatermark_checkAggregation() throws Exception {
Device device = createDevice("Device", "1234567890111");
CustomInterval customInterval = new CustomInterval("Europe/Kyiv", 0L, 5L);
CustomInterval customInterval = new CustomInterval(TZ, 0L, 5L);
createConsumptionCF(device.getId(), customInterval, null);
long currentIntervalStartTs = customInterval.getCurrentIntervalStartTs();
@ -156,7 +158,7 @@ public class EntityAggregationCalculatedFieldTest extends AbstractControllerTest
public void testCreateCfWithWatermark_checkAggregationDuringWatermark() throws Exception {
Device device = createDevice("Device", "1234567890111");
CustomInterval customInterval = new CustomInterval("Europe/Kyiv", 0L, 5L);
CustomInterval customInterval = new CustomInterval(TZ, 0L, 5L);
Watermark watermark = new Watermark(10);
createConsumptionCF(device.getId(), customInterval, watermark);
@ -196,6 +198,51 @@ public class EntityAggregationCalculatedFieldTest extends AbstractControllerTest
});
}
@Test
public void testSendFutureTelemetry_checkAggregation() throws Exception {
Device device = createDevice("Device", "1234567890111");
CustomInterval customInterval = new CustomInterval(TZ, 0L, 2L);
createConsumptionCF(device.getId(), customInterval, null);
long currentIntervalStartTs = customInterval.getCurrentIntervalStartTs();
long tsBeforeInterval = currentIntervalStartTs - 1000;
long tsInInterval_1 = currentIntervalStartTs + 1000;
long tsInInterval_2 = currentIntervalStartTs + 500;
long tsInInterval_3 = currentIntervalStartTs + 200;
postTelemetry(device.getId(), String.format("{\"ts\": \"%s\", \"values\": {\"energy\":120}}", tsBeforeInterval));
postTelemetry(device.getId(), String.format("{\"ts\": \"%s\", \"values\": {\"energy\":100}}", tsInInterval_1));
postTelemetry(device.getId(), String.format("{\"ts\": \"%s\", \"values\": {\"energy\":180}}", tsInInterval_2));
postTelemetry(device.getId(), String.format("{\"ts\": \"%s\", \"values\": {\"energy\":120}}", tsInInterval_3));
long interval = customInterval.getCurrentIntervalDurationMillis();
await().alias("create CF -> perform aggregation after interval end")
.atMost(2 * interval, TimeUnit.MILLISECONDS)
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS)
.untilAsserted(() -> {
ObjectNode result = getLatestTelemetry(device.getId(), "consumption", "avgConsumption");
assertThat(result).isNotNull();
assertThat(result.get("consumption").get(0).get("value").asText()).isEqualTo("400");
assertThat(result.get("avgConsumption").get(0).get("value").asText()).isEqualTo("133");
});
postTelemetry(device.getId(), String.format("{\"ts\": \"%s\", \"values\": {\"energy\":500}}", currentIntervalStartTs + 4500L));
await().alias("update telemetry that belongs to future interval -> check aggregation ")
.atMost(3 * interval, TimeUnit.MILLISECONDS)
.pollInterval(POLL_INTERVAL, TimeUnit.SECONDS)
.untilAsserted(() -> {
ObjectNode result = getLatestTelemetry(device.getId(), "consumption", "avgConsumption");
assertThat(result).isNotNull();
assertThat(result.get("consumption").get(0).get("value").asText()).isEqualTo("500");
assertThat(result.get("consumption").get(0).get("ts").asLong()).isEqualTo(currentIntervalStartTs + 4000L);
assertThat(result.get("avgConsumption").get(0).get("value").asText()).isEqualTo("500");
assertThat(result.get("avgConsumption").get(0).get("ts").asLong()).isEqualTo(currentIntervalStartTs + 4000L);
});
}
private CalculatedField createConsumptionCF(EntityId entityId, AggInterval aggInterval, Watermark watermark) {
Map<String, Argument> arguments = new HashMap<>();
Argument argument = new Argument();

25
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/GeofencingValueArgumentEntryTest.java

@ -18,6 +18,9 @@ package org.thingsboard.server.service.cf.ctx.state;
import io.hypersistence.utils.hibernate.type.json.internal.JacksonUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.common.util.geo.PerimeterDefinition;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.EntityId;
@ -33,6 +36,7 @@ import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ExtendWith(MockitoExtension.class)
public class GeofencingValueArgumentEntryTest {
private final AssetId ZONE_1_ID = new AssetId(UUID.fromString("c0e3031c-7df1-45e4-9590-cfd621a4d714"));
@ -46,6 +50,9 @@ public class GeofencingValueArgumentEntryTest {
private GeofencingArgumentEntry entry;
@Mock
private CalculatedFieldCtx ctx;
@BeforeEach
void setUp() {
entry = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, allowedZoneAttributeKvEntry, ZONE_2_ID, restrictedZoneAttributeKvEntry));
@ -58,14 +65,14 @@ public class GeofencingValueArgumentEntryTest {
@Test
void testUpdateEntryWhenSingleEntryPassed() {
assertThatThrownBy(() -> entry.updateEntry(new SingleValueArgumentEntry()))
assertThatThrownBy(() -> entry.updateEntry(new SingleValueArgumentEntry(), ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported argument entry type for geofencing argument entry: SINGLE_VALUE");
}
@Test
void testUpdateEntryWhenRollingEntryPassed() {
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L)))
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L), ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported argument entry type for geofencing argument entry: TS_ROLLING");
}
@ -74,7 +81,7 @@ public class GeofencingValueArgumentEntryTest {
void testUpdateEntryWithTheSameTs() {
BaseAttributeKvEntry differentValueSameTs = new BaseAttributeKvEntry(new JsonDataEntry("zone", "[[50.472001, 30.504001], [50.472001, 30.506001], [50.474001, 30.506001], [50.474001, 30.504001]]"), 363L, 156L);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, differentValueSameTs, ZONE_2_ID, restrictedZoneAttributeKvEntry));
assertThat(entry.updateEntry(updated)).isFalse();
assertThat(entry.updateEntry(updated, ctx)).isFalse();
}
@Test
@ -83,7 +90,7 @@ public class GeofencingValueArgumentEntryTest {
BaseAttributeKvEntry differentValueNewVersionIsNull = new BaseAttributeKvEntry(new JsonDataEntry("zone", "[[50.472001, 30.504001], [50.472001, 30.506001], [50.474001, 30.506001], [50.474001, 30.504001]]"), 364L, null);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, differentValueNewVersionIsNull, ZONE_2_ID, restrictedZoneAttributeKvEntry));
assertThat(entry.updateEntry(updated)).isTrue();
assertThat(entry.updateEntry(updated, ctx)).isTrue();
assertThat(entry.getValue()).isInstanceOf(Map.class);
Map<EntityId, GeofencingZoneState> value = (Map<EntityId, GeofencingZoneState>) entry.getValue();
@ -105,7 +112,7 @@ public class GeofencingValueArgumentEntryTest {
BaseAttributeKvEntry differentValueNewVersionIsSet = new BaseAttributeKvEntry(new JsonDataEntry("zone", "[[50.472001, 30.504001], [50.472001, 30.506001], [50.474001, 30.506001], [50.474001, 30.504001]]"), 364L, 156L);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, differentValueNewVersionIsSet, ZONE_2_ID, restrictedZoneAttributeKvEntry));
assertThat(entry.updateEntry(updated)).isTrue();
assertThat(entry.updateEntry(updated, ctx)).isTrue();
assertThat(entry.getValue()).isInstanceOf(Map.class);
Map<EntityId, GeofencingZoneState> value = (Map<EntityId, GeofencingZoneState>) entry.getValue();
@ -126,7 +133,7 @@ public class GeofencingValueArgumentEntryTest {
BaseAttributeKvEntry differentValueNewVersionIsSet = new BaseAttributeKvEntry(new JsonDataEntry("zone", "[[50.472001, 30.504001], [50.472001, 30.506001], [50.474001, 30.506001], [50.474001, 30.504001]]"), 364L, 154L);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, differentValueNewVersionIsSet, ZONE_2_ID, restrictedZoneAttributeKvEntry));
assertThat(entry.updateEntry(updated)).isFalse();
assertThat(entry.updateEntry(updated, ctx)).isFalse();
}
@Test
@ -134,7 +141,7 @@ public class GeofencingValueArgumentEntryTest {
BaseAttributeKvEntry newTsAndTheSameValue = new BaseAttributeKvEntry(allowedZoneDataEntry, 364L, 156L);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, newTsAndTheSameValue, ZONE_2_ID, restrictedZoneAttributeKvEntry));
assertThat(entry.updateEntry(updated)).isTrue();
assertThat(entry.updateEntry(updated, ctx)).isTrue();
}
@Test
@ -142,7 +149,7 @@ public class GeofencingValueArgumentEntryTest {
BaseAttributeKvEntry oldTsAndTheSameValue = new BaseAttributeKvEntry(allowedZoneDataEntry, 362L, 156L);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, oldTsAndTheSameValue, ZONE_2_ID, restrictedZoneAttributeKvEntry));
assertThat(entry.updateEntry(updated)).isFalse();
assertThat(entry.updateEntry(updated, ctx)).isFalse();
}
@Test
@ -150,7 +157,7 @@ public class GeofencingValueArgumentEntryTest {
final AssetId NEW_ZONE_ID = new AssetId(UUID.fromString("a3eacf1a-6af3-4e9f-87c4-502bb25c7dc3"));
BaseAttributeKvEntry newZone = new BaseAttributeKvEntry(new JsonDataEntry("zone", "[[50.472001, 30.504001], [50.472001, 30.506001], [50.474001, 30.506001], [50.474001, 30.504001]]"), 364L, 156L);
var updated = new GeofencingArgumentEntry(Map.of(ZONE_1_ID, allowedZoneAttributeKvEntry, ZONE_2_ID, restrictedZoneAttributeKvEntry, NEW_ZONE_ID, newZone));
assertThat(entry.updateEntry(updated)).isTrue();
assertThat(entry.updateEntry(updated, ctx)).isTrue();
}
@Test

33
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/PropagationArgumentEntryTest.java

@ -17,6 +17,9 @@ package org.thingsboard.server.service.cf.ctx.state;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.script.api.tbel.TbelCfArg;
import org.thingsboard.script.api.tbel.TbelCfPropagationArg;
import org.thingsboard.server.common.data.id.AssetId;
@ -31,6 +34,7 @@ import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ExtendWith(MockitoExtension.class)
public class PropagationArgumentEntryTest {
private final AssetId ENTITY_1_ID = new AssetId(UUID.fromString("b0a8637d-6d67-43d5-a483-c0e391afe805"));
@ -39,6 +43,9 @@ public class PropagationArgumentEntryTest {
private PropagationArgumentEntry entry;
@Mock
private CalculatedFieldCtx ctx;
@BeforeEach
void setUp() {
List<EntityId> propagationEntityIds = new ArrayList<>();
@ -68,14 +75,14 @@ public class PropagationArgumentEntryTest {
@Test
void testUpdateEntryWhenSingleEntryPassed() {
assertThatThrownBy(() -> entry.updateEntry(new SingleValueArgumentEntry()))
assertThatThrownBy(() -> entry.updateEntry(new SingleValueArgumentEntry(), ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported argument entry type for propagation argument entry: SINGLE_VALUE");
}
@Test
void testUpdateEntryWhenRollingEntryPassed() {
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L)))
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L), ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported argument entry type for propagation argument entry: TS_ROLLING");
}
@ -85,7 +92,7 @@ public class PropagationArgumentEntryTest {
var newIds = new ArrayList<EntityId>(List.of(ENTITY_3_ID, ENTITY_1_ID));
var updated = new PropagationArgumentEntry(newIds);
boolean changed = entry.updateEntry(updated);
boolean changed = entry.updateEntry(updated, ctx);
assertThat(changed).isTrue();
assertThat(entry.getEntityIds()).containsExactlyElementsOf(newIds);
@ -95,7 +102,7 @@ public class PropagationArgumentEntryTest {
void testUpdateEntryClearsWhenNewEntryIsEmpty() {
var updatedEmpty = new PropagationArgumentEntry(List.of());
boolean changed = entry.updateEntry(updatedEmpty);
boolean changed = entry.updateEntry(updatedEmpty, ctx);
assertThat(changed).isTrue();
assertThat(entry.getEntityIds()).isEmpty();
@ -106,7 +113,7 @@ public class PropagationArgumentEntryTest {
var added = new PropagationArgumentEntry();
added.setAdded(List.of(ENTITY_3_ID));
boolean changed = entry.updateEntry(added);
boolean changed = entry.updateEntry(added, ctx);
assertThat(changed).isTrue();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID, ENTITY_2_ID, ENTITY_3_ID);
@ -118,7 +125,7 @@ public class PropagationArgumentEntryTest {
var added = new PropagationArgumentEntry();
added.setAdded(List.of(ENTITY_2_ID));
boolean changed = entry.updateEntry(added);
boolean changed = entry.updateEntry(added, ctx);
assertThat(changed).isFalse();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID, ENTITY_2_ID);
@ -130,7 +137,7 @@ public class PropagationArgumentEntryTest {
var removed = new PropagationArgumentEntry();
removed.setRemoved(ENTITY_2_ID);
boolean changed = entry.updateEntry(removed);
boolean changed = entry.updateEntry(removed, ctx);
assertThat(changed).isTrue();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID);
@ -142,7 +149,7 @@ public class PropagationArgumentEntryTest {
var removed = new PropagationArgumentEntry();
removed.setRemoved(ENTITY_3_ID);
boolean changed = entry.updateEntry(removed);
boolean changed = entry.updateEntry(removed, ctx);
assertThat(changed).isFalse();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID, ENTITY_2_ID);
@ -154,7 +161,7 @@ public class PropagationArgumentEntryTest {
var restore = new PropagationArgumentEntry(List.of(ENTITY_1_ID, ENTITY_2_ID, ENTITY_3_ID));
restore.setIgnoreRemovedEntities(true);
boolean changed = entry.updateEntry(restore);
boolean changed = entry.updateEntry(restore, ctx);
assertThat(changed).isTrue();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID, ENTITY_2_ID, ENTITY_3_ID);
@ -168,7 +175,7 @@ public class PropagationArgumentEntryTest {
var restore = new PropagationArgumentEntry(List.of(ENTITY_1_ID));
restore.setIgnoreRemovedEntities(true);
boolean changed = entry.updateEntry(restore);
boolean changed = entry.updateEntry(restore, ctx);
assertThat(changed).isFalse(); // expected no change, since we consider the removal of stale ids as no-op
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID);
@ -182,7 +189,7 @@ public class PropagationArgumentEntryTest {
var restore = new PropagationArgumentEntry(List.of(ENTITY_1_ID, ENTITY_3_ID));
restore.setIgnoreRemovedEntities(true);
boolean changed = entry.updateEntry(restore);
boolean changed = entry.updateEntry(restore, ctx);
assertThat(changed).isTrue();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID, ENTITY_3_ID);
@ -197,7 +204,7 @@ public class PropagationArgumentEntryTest {
var restore = new PropagationArgumentEntry(List.of(ENTITY_1_ID, ENTITY_2_ID));
restore.setIgnoreRemovedEntities(true);
boolean changed = entry.updateEntry(restore);
boolean changed = entry.updateEntry(restore, ctx);
assertThat(changed).isFalse();
assertThat(entry.getEntityIds()).containsExactlyInAnyOrder(ENTITY_1_ID, ENTITY_2_ID);
@ -211,7 +218,7 @@ public class PropagationArgumentEntryTest {
var restore = new PropagationArgumentEntry(List.of());
restore.setIgnoreRemovedEntities(true);
boolean changed = entry.updateEntry(restore);
boolean changed = entry.updateEntry(restore, ctx);
assertThat(changed).isFalse(); // expected no change, since we consider the removal of stale ids as no-op
assertThat(entry.getEntityIds()).isEmpty();

15
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/RelatedEntitiesArgumentEntryTest.java

@ -17,6 +17,9 @@ package org.thingsboard.server.service.cf.ctx.state;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.kv.BasicTsKvEntry;
@ -30,10 +33,14 @@ import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ExtendWith(MockitoExtension.class)
public class RelatedEntitiesArgumentEntryTest {
private RelatedEntitiesArgumentEntry entry;
@Mock
private CalculatedFieldCtx ctx;
private final DeviceId device1 = new DeviceId(UUID.fromString("1984e5f4-9ff0-4187-84ae-e4438bba4c8a"));
private final DeviceId device2 = new DeviceId(UUID.fromString("937fc062-1a9d-438f-aa22-55a93fc908b7"));
@ -50,7 +57,7 @@ public class RelatedEntitiesArgumentEntryTest {
@Test
void testUpdateEntryWhenNotAggEntryPassed() {
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L)))
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L), ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported argument entry type for aggregation argument entry: " + ArgumentEntryType.TS_ROLLING);
}
@ -65,7 +72,7 @@ public class RelatedEntitiesArgumentEntryTest {
device4, new SingleValueArgumentEntry(device4, new BasicTsKvEntry(ts - 60, new LongDataEntry("key", 23L), 7L))
), false);
assertThat(entry.updateEntry(relatedEntitiesArgumentEntry)).isTrue();
assertThat(entry.updateEntry(relatedEntitiesArgumentEntry, ctx)).isTrue();
Map<EntityId, ArgumentEntry> aggInputs = entry.getEntityInputs();
assertThat(aggInputs.size()).isEqualTo(4);
@ -79,7 +86,7 @@ public class RelatedEntitiesArgumentEntryTest {
SingleValueArgumentEntry singleEntityArgumentEntry = new SingleValueArgumentEntry(device3, new BasicTsKvEntry(ts - 50, new LongDataEntry("key", 18L), 10L));
assertThat(entry.updateEntry(singleEntityArgumentEntry)).isTrue();
assertThat(entry.updateEntry(singleEntityArgumentEntry, ctx)).isTrue();
Map<EntityId, ArgumentEntry> aggInputs = entry.getEntityInputs();
assertThat(aggInputs.size()).isEqualTo(3);
@ -90,7 +97,7 @@ public class RelatedEntitiesArgumentEntryTest {
void testUpdateEntryWhenSingleValueArgumentEntryPassedAndEntryByIdExist() {
SingleValueArgumentEntry singleEntityArgumentEntry = new SingleValueArgumentEntry(device2, new BasicTsKvEntry(ts - 50, new LongDataEntry("key", 18L), 10L));
assertThat(entry.updateEntry(singleEntityArgumentEntry)).isTrue();
assertThat(entry.updateEntry(singleEntityArgumentEntry, ctx)).isTrue();
Map<EntityId, ArgumentEntry> aggInputs = entry.getEntityInputs();
assertThat(aggInputs.size()).isEqualTo(2);

23
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/SingleValueArgumentEntryTest.java

@ -17,6 +17,9 @@ package org.thingsboard.server.service.cf.ctx.state;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.script.api.tbel.TbelCfArg;
import org.thingsboard.script.api.tbel.TbelCfSingleValueArg;
import org.thingsboard.server.common.data.kv.JsonDataEntry;
@ -29,10 +32,14 @@ import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ExtendWith(MockitoExtension.class)
public class SingleValueArgumentEntryTest {
private SingleValueArgumentEntry entry;
@Mock
private CalculatedFieldCtx ctx;
private final long ts = System.currentTimeMillis();
@BeforeEach
@ -47,48 +54,48 @@ public class SingleValueArgumentEntryTest {
@Test
void testUpdateEntryWhenRollingEntryPassed() {
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L)))
assertThatThrownBy(() -> entry.updateEntry(new TsRollingArgumentEntry(5, 30000L), ctx))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unsupported argument entry type for single value argument entry: " + ArgumentEntryType.TS_ROLLING);
}
@Test
void testUpdateEntryWithTheSameTs() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts, new LongDataEntry("key", 13L), 363L))).isFalse();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts, new LongDataEntry("key", 13L), 363L), ctx)).isFalse();
}
@Test
void testUpdateEntryWithTheSameTsAndDifferentVersion() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts, new LongDataEntry("key", 13L), 364L))).isTrue();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts, new LongDataEntry("key", 13L), 364L), ctx)).isTrue();
}
@Test
void testUpdateEntryWhenNewVersionIsNull() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 16, new LongDataEntry("key", 13L), null))).isTrue();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 16, new LongDataEntry("key", 13L), null), ctx)).isTrue();
assertThat(entry.getValue()).isEqualTo(13L);
assertThat(entry.getVersion()).isNull();
}
@Test
void testUpdateEntryWhenNewVersionIsGreaterThanCurrent() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 18, new LongDataEntry("key", 18L), 369L))).isTrue();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 18, new LongDataEntry("key", 18L), 369L), ctx)).isTrue();
assertThat(entry.getValue()).isEqualTo(18L);
assertThat(entry.getVersion()).isEqualTo(369L);
}
@Test
void testUpdateEntryWhenNewVersionIsLessThanCurrent() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 18, new LongDataEntry("key", 18L), 234L))).isFalse();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 18, new LongDataEntry("key", 18L), 234L), ctx)).isFalse();
}
@Test
void testUpdateEntryWhenValueWasNotChanged() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 18, new LongDataEntry("key", 11L), 364L))).isTrue();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts + 18, new LongDataEntry("key", 11L), 364L), ctx)).isTrue();
}
@Test
void testUpdateEntryWithOldTs() {
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts - 10, new LongDataEntry("key", 14L), 365L))).isFalse();
assertThat(entry.updateEntry(new SingleValueArgumentEntry(ts - 10, new LongDataEntry("key", 14L), 365L), ctx)).isFalse();
}
@Test

17
application/src/test/java/org/thingsboard/server/service/cf/ctx/state/TsRollingArgumentEntryTest.java

@ -17,6 +17,9 @@ package org.thingsboard.server.service.cf.ctx.state;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.thingsboard.server.common.data.kv.DoubleDataEntry;
import org.thingsboard.server.common.data.kv.StringDataEntry;
@ -26,10 +29,14 @@ import java.util.TreeMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ExtendWith(MockitoExtension.class)
public class TsRollingArgumentEntryTest {
private TsRollingArgumentEntry entry;
@Mock
private CalculatedFieldCtx ctx;
private final long ts = System.currentTimeMillis();
@BeforeEach
@ -51,7 +58,7 @@ public class TsRollingArgumentEntryTest {
void testUpdateEntryWhenSingleValueEntryPassed() {
SingleValueArgumentEntry newEntry = new SingleValueArgumentEntry(ts - 10, new DoubleDataEntry("key", 23.0), 123L);
assertThat(entry.updateEntry(newEntry)).isTrue();
assertThat(entry.updateEntry(newEntry, ctx)).isTrue();
assertThat(entry.getTsRecords()).hasSize(4);
assertThat(entry.getTsRecords().get(ts - 10)).isEqualTo(23.0);
}
@ -64,7 +71,7 @@ public class TsRollingArgumentEntryTest {
values.put(ts - 5, 1.0);
newEntry.setTsRecords(values);
assertThat(entry.updateEntry(newEntry)).isTrue();
assertThat(entry.updateEntry(newEntry, ctx)).isTrue();
assertThat(entry.getTsRecords()).hasSize(5);
assertThat(entry.getTsRecords()).isEqualTo(Map.of(
ts - 40, 10.0,
@ -79,7 +86,7 @@ public class TsRollingArgumentEntryTest {
void testUpdateEntryWhenValueIsNotNumber() {
SingleValueArgumentEntry newEntry = new SingleValueArgumentEntry(ts - 10, new StringDataEntry("key", "string"), 123L);
assertThat(entry.updateEntry(newEntry)).isTrue();
assertThat(entry.updateEntry(newEntry, ctx)).isTrue();
assertThat(entry.getTsRecords().get(ts - 10)).isNaN();
}
@ -93,7 +100,7 @@ public class TsRollingArgumentEntryTest {
newEntry.setTsRecords(values);
entry = new TsRollingArgumentEntry(3, 30000L);
assertThat(entry.updateEntry(newEntry)).isTrue();
assertThat(entry.updateEntry(newEntry, ctx)).isTrue();
assertThat(entry.getTsRecords()).hasSize(1);
assertThat(entry.getTsRecords()).isEqualTo(Map.of(
ts - 5, 0.0
@ -111,7 +118,7 @@ public class TsRollingArgumentEntryTest {
newEntry.setTsRecords(values);
entry = new TsRollingArgumentEntry(3, 30000L);
assertThat(entry.updateEntry(newEntry)).isTrue();
assertThat(entry.updateEntry(newEntry, ctx)).isTrue();
assertThat(entry.getTsRecords()).hasSize(3);
assertThat(entry.getTsRecords()).isEqualTo(Map.of(
ts - 18, 0.0,

Loading…
Cancel
Save