From 5af56899d0709928cedfe91091368698b2288aad Mon Sep 17 00:00:00 2001 From: Dmytro Skarzhynets Date: Thu, 29 Jan 2026 16:21:26 +0200 Subject: [PATCH] refactor: remove unreliable performance tests Remove environment-dependent performance tests that use arbitrary time thresholds. These tests are flaky in CI and don't provide meaningful assertions. Co-Authored-By: Claude Opus 4.5 --- .../dao/service/ConstraintValidatorTest.java | 18 +- .../sql/LatestTimeseriesPerformanceTest.java | 154 ------------------ 2 files changed, 1 insertion(+), 171 deletions(-) delete mode 100644 dao/src/test/java/org/thingsboard/server/dao/service/timeseries/sql/LatestTimeseriesPerformanceTest.java diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/ConstraintValidatorTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/ConstraintValidatorTest.java index 0609d4a57f..46f89ce494 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/ConstraintValidatorTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/ConstraintValidatorTest.java @@ -16,16 +16,12 @@ package org.thingsboard.server.dao.service; import org.junit.Assert; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.dao.exception.DataValidationException; class ConstraintValidatorTest { - private static final int MIN_IN_MS = 60000; - private static final int _1M = 1_000_000; - @Test void validateFields() { StringDataEntry stringDataEntryValid = new StringDataEntry("key", "value"); @@ -35,16 +31,4 @@ class ConstraintValidatorTest { ConstraintValidator.validateFields(stringDataEntryValid); } - @Test - void validatePerMinute() { - StringDataEntry stringDataEntryValid = new StringDataEntry("key", "value"); - - long start = System.currentTimeMillis(); - for (int i = 0; i < _1M; i++) { - ConstraintValidator.validateFields(stringDataEntryValid); - } - long end = System.currentTimeMillis(); - - Assertions.assertTrue(MIN_IN_MS > end - start); - } -} \ No newline at end of file +} diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/sql/LatestTimeseriesPerformanceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/sql/LatestTimeseriesPerformanceTest.java deleted file mode 100644 index 100ef1c11e..0000000000 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/sql/LatestTimeseriesPerformanceTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/** - * Copyright © 2016-2026 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.service.timeseries.sql; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.common.util.concurrent.MoreExecutors; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.kv.BasicTsKvEntry; -import org.thingsboard.server.common.data.kv.BooleanDataEntry; -import org.thingsboard.server.common.data.kv.DoubleDataEntry; -import org.thingsboard.server.common.data.kv.LongDataEntry; -import org.thingsboard.server.common.data.kv.StringDataEntry; -import org.thingsboard.server.common.data.kv.TsKvEntry; -import org.thingsboard.server.dao.service.AbstractServiceTest; -import org.thingsboard.server.dao.service.DaoSqlTest; -import org.thingsboard.server.dao.timeseries.TimeseriesLatestDao; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -@DaoSqlTest -@Slf4j -public class LatestTimeseriesPerformanceTest extends AbstractServiceTest { - - private static final String STRING_KEY = "stringKey"; - private static final String LONG_KEY = "longKey"; - private static final String DOUBLE_KEY = "doubleKey"; - private static final String BOOLEAN_KEY = "booleanKey"; - private static final int AMOUNT_OF_UNIQ_KEY = 10000; - private static final int TIMEOUT = 100; - - private final Random random = new Random(); - - @Autowired - private TimeseriesLatestDao timeseriesLatestDao; - - private ListeningExecutorService testExecutor; - - private EntityId entityId; - - private AtomicLong saveCounter; - - @Before - public void before() { - Tenant tenant = new Tenant(); - tenant.setTitle("My tenant"); - Tenant savedTenant = tenantService.saveTenant(tenant); - Assert.assertNotNull(savedTenant); - tenantId = savedTenant.getId(); - entityId = new DeviceId(UUID.randomUUID()); - saveCounter = new AtomicLong(0); - testExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(200, ThingsBoardThreadFactory.forName(getClass().getSimpleName() + "-test-scope"))); - } - - @After - public void after() { - tenantService.deleteTenant(tenantId); - if (testExecutor != null) { - testExecutor.shutdownNow(); - } - } - - @Test - public void test_save_latest_timeseries() throws Exception { - warmup(); - saveCounter.set(0); - - long startTime = System.currentTimeMillis(); - List> futures = new ArrayList<>(); - for (int i = 0; i < 25_000; i++) { - futures.add(save(generateStrEntry(getRandomKey()))); - futures.add(save(generateLngEntry(getRandomKey()))); - futures.add(save(generateDblEntry(getRandomKey()))); - futures.add(save(generateBoolEntry(getRandomKey()))); - } - Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS); - long endTime = System.currentTimeMillis(); - - long totalTime = endTime - startTime; - - log.info("Total time: {}", totalTime); - log.info("Saved count: {}", saveCounter.get()); - log.warn("Saved per 1 sec: {}", saveCounter.get() * 1000 / totalTime); - } - - private void warmup() throws Exception { - List> futures = new ArrayList<>(); - for (int i = 0; i < AMOUNT_OF_UNIQ_KEY; i++) { - futures.add(save(generateStrEntry(i))); - futures.add(save(generateLngEntry(i))); - futures.add(save(generateDblEntry(i))); - futures.add(save(generateBoolEntry(i))); - } - Futures.allAsList(futures).get(TIMEOUT, TimeUnit.SECONDS); - } - - private ListenableFuture save(TsKvEntry tsKvEntry) { - return Futures.transformAsync(testExecutor.submit(() -> timeseriesLatestDao.saveLatest(tenantId, entityId, tsKvEntry)), result -> { - saveCounter.incrementAndGet(); - return result; - }, testExecutor); - } - - private TsKvEntry generateStrEntry(int keyIndex) { - return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(STRING_KEY + keyIndex, RandomStringUtils.random(10))); - } - - private TsKvEntry generateLngEntry(int keyIndex) { - return new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(LONG_KEY + keyIndex, random.nextLong())); - } - - private TsKvEntry generateDblEntry(int keyIndex) { - return new BasicTsKvEntry(System.currentTimeMillis(), new DoubleDataEntry(DOUBLE_KEY + keyIndex, random.nextDouble())); - } - - private TsKvEntry generateBoolEntry(int keyIndex) { - return new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(BOOLEAN_KEY + keyIndex, random.nextBoolean())); - } - - private int getRandomKey() { - return random.nextInt(AMOUNT_OF_UNIQ_KEY); - } - -}