From 148dd17ce1e3c1a50bd5ee4d8e4aeb53f4fcccd8 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Fri, 6 Mar 2026 09:07:06 +0100 Subject: [PATCH] Fix flaky TenantControllerTest by draining housekeeper before teardown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tests like testFindTenantsByTitle create 261 tenants and delete them via deleteEntitiesAsync, which only waits for HTTP responses — not housekeeper completion. Each tenant deletion submits ~30 TenantEntitiesDeletionHousekeeper tasks (~7800 tasks total), which cascade further. The teardown's deleteTenant then waits for lag==0 with a 90s timeout, which is insufficient for this backlog and causes ConditionTimeoutException. Fix: add awaitHousekeeperDrained() (5-min timeout) called at the start of teardownWebTest so any pending housekeeper work from the test body drains before per-tenant teardown deletions begin. Co-Authored-By: Claude Sonnet 4.6 --- .../thingsboard/server/controller/AbstractWebTest.java | 9 +++++++++ .../src/test/resources/application-test.properties | 1 + 2 files changed, 10 insertions(+) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 3b7286cf01..5f4b7e952f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -405,6 +405,10 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { public void teardownWebTest() throws Exception { log.debug("Executing web test teardown"); + // Drain any pending housekeeper work left by the test body (e.g., bulk tenant deletes) + // before proceeding with teardown deletions, to avoid 90s per-tenant wait timing out. + awaitHousekeeperDrained(); + loginSysAdmin(); deleteTenant(tenantId); deleteDifferentTenant(); @@ -436,6 +440,11 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { .until(() -> storage.getLag("tb_housekeeper") == 0); } + protected void awaitHousekeeperDrained() { + Awaitility.await("housekeeper drained").atMost(5, TimeUnit.MINUTES).during(300, TimeUnit.MILLISECONDS) + .until(() -> storage.getLag("tb_housekeeper") == 0); + } + private List getAllTenants() throws Exception { List loadedTenants = new ArrayList<>(); PageLink pageLink = new PageLink(10); diff --git a/application/src/test/resources/application-test.properties b/application/src/test/resources/application-test.properties index e79289340c..7f0ab964d6 100644 --- a/application/src/test/resources/application-test.properties +++ b/application/src/test/resources/application-test.properties @@ -44,6 +44,7 @@ queue.transport_api.response_poll_interval=5 queue.transport.poll_interval=5 queue.core.poll-interval=5 queue.core.partitions=2 +queue.core.housekeeper.task-reprocessing-delay-ms=0 queue.rule-engine.poll-interval=5 queue.rule-engine.stats.enabled=true