This is an automated email from the ASF dual-hosted git repository.
somandal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 0dca00766ec Update the UtilizationChecker and
ResourceUtilizationManager to return an enum instead of boolean (#16255)
0dca00766ec is described below
commit 0dca00766ecc8a5abc8b2fe5c8e036503b19eacb
Author: Sonam Mandal <[email protected]>
AuthorDate: Wed Jul 2 11:16:57 2025 -0700
Update the UtilizationChecker and ResourceUtilizationManager to return an
enum instead of boolean (#16255)
---
.../helix/core/minion/PinotTaskManager.java | 8 ++--
.../validation/DiskUtilizationChecker.java | 19 ++++++--
.../RealtimeSegmentValidationManager.java | 16 +++++--
.../validation/ResourceUtilizationManager.java | 28 ++++++++---
.../controller/validation/UtilizationChecker.java | 12 ++++-
.../validation/DiskUtilizationCheckerTest.java | 56 ++++++++++++++++------
.../RealtimeSegmentValidationManagerTest.java | 27 +++++++----
.../validation/ResourceUtilizationManagerTest.java | 54 +++++++++++++++------
8 files changed, 163 insertions(+), 57 deletions(-)
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/PinotTaskManager.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/PinotTaskManager.java
index 96f9154241f..8303eb67f4f 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/PinotTaskManager.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/minion/PinotTaskManager.java
@@ -223,8 +223,8 @@ public class PinotTaskManager extends
ControllerPeriodicTask<Void> {
TableConfig tableConfig =
_pinotHelixResourceManager.getTableConfig(tableNameWithType);
LOGGER.info("Trying to create tasks of type: {}, table: {}", taskType,
tableNameWithType);
try {
- if
(!_resourceUtilizationManager.isResourceUtilizationWithinLimits(tableNameWithType,
- UtilizationChecker.CheckPurpose.TASK_GENERATION)) {
+ if
(_resourceUtilizationManager.isResourceUtilizationWithinLimits(tableNameWithType,
+ UtilizationChecker.CheckPurpose.TASK_GENERATION) ==
UtilizationChecker.CheckResult.FAIL) {
LOGGER.warn("Resource utilization is above threshold, skipping task
creation for table: {}", tableName);
_controllerMetrics.setOrUpdateTableGauge(tableName,
ControllerGauge.RESOURCE_UTILIZATION_LIMIT_EXCEEDED, 1L);
continue;
@@ -723,8 +723,8 @@ public class PinotTaskManager extends
ControllerPeriodicTask<Void> {
for (TableConfig tableConfig : enabledTableConfigs) {
String tableName = tableConfig.getTableName();
try {
- if
(!_resourceUtilizationManager.isResourceUtilizationWithinLimits(tableName,
- UtilizationChecker.CheckPurpose.TASK_GENERATION)) {
+ if
(_resourceUtilizationManager.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckPurpose.TASK_GENERATION) ==
UtilizationChecker.CheckResult.FAIL) {
String message = String.format("Skipping tasks generation as
resource utilization is not within limits for "
+ "table: %s. Disk utilization for one or more servers hosting
this table has exceeded the threshold. "
+ "Tasks won't be generated until the issue is mitigated.",
tableName);
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/DiskUtilizationChecker.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/DiskUtilizationChecker.java
index fa2f1bfbea2..45616227b85 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/DiskUtilizationChecker.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/DiskUtilizationChecker.java
@@ -63,14 +63,14 @@ public class DiskUtilizationChecker implements
UtilizationChecker {
* Check if disk utilization for the requested table is within the
configured limits.
*/
@Override
- public boolean isResourceUtilizationWithinLimits(String tableNameWithType,
UtilizationChecker.CheckPurpose purpose) {
+ public CheckResult isResourceUtilizationWithinLimits(String
tableNameWithType, CheckPurpose purpose) {
if (StringUtils.isEmpty(tableNameWithType)) {
throw new IllegalArgumentException("Table name found to be null or empty
while computing disk utilization.");
}
TableConfig tableConfig =
_helixResourceManager.getTableConfig(tableNameWithType);
if (tableConfig == null) {
LOGGER.warn("Table config for table: {} is null", tableNameWithType);
- return true; // table does not exist
+ return CheckResult.PASS; // table does not exist
}
List<String> instances;
if (TableNameBuilder.isOfflineTableResource(tableNameWithType)) {
@@ -81,10 +81,12 @@ public class DiskUtilizationChecker implements
UtilizationChecker {
return isDiskUtilizationWithinLimits(instances);
}
- private boolean isDiskUtilizationWithinLimits(List<String> instances) {
+ private CheckResult isDiskUtilizationWithinLimits(List<String> instances) {
+ int numInstancesWithStaleOrNullResults = 0;
for (String instance : instances) {
DiskUsageInfo diskUsageInfo =
ResourceUtilizationInfo.getDiskUsageInfo(instance);
if (diskUsageInfo == null) {
+ numInstancesWithStaleOrNullResults++;
LOGGER.warn("Disk utilization info for server: {} is null", instance);
continue;
}
@@ -92,6 +94,7 @@ public class DiskUtilizationChecker implements
UtilizationChecker {
// ResourceUtilizationChecker tasks frequency.
if (diskUsageInfo.getLastUpdatedTimeInEpochMs()
< System.currentTimeMillis() -
_resourceUtilizationCheckerFrequencyMs) {
+ numInstancesWithStaleOrNullResults++;
LOGGER.warn("Disk utilization info for server: {} is stale", instance);
continue;
}
@@ -99,10 +102,16 @@ public class DiskUtilizationChecker implements
UtilizationChecker {
LOGGER.warn("Disk utilization for server: {} is above threshold: {}%.
UsedBytes: {}, TotalBytes: {}",
instance, diskUsageInfo.getUsedSpaceBytes() * 100 /
diskUsageInfo.getTotalSpaceBytes(), diskUsageInfo
.getUsedSpaceBytes(), diskUsageInfo.getTotalSpaceBytes());
- return false;
+ return CheckResult.FAIL;
}
}
- return true;
+ // If results for all servers is null or stale, return the status as STALE
to indicate that the status cannot be
+ // determined.
+ // TODO: Have better handling for partial STALE results from servers. It
is possible that a subset of servers are
+ // STALE, and these are the ones that may have a resource
utilization breach, but we return TRUE here.
+ // Eventually when the status is updated, the correct value will be
returned and the correct action can be
+ // taken based on that. Temporarily the action taken may be the
wrong one.
+ return numInstancesWithStaleOrNullResults == instances.size() ?
CheckResult.UNDETERMINED : CheckResult.PASS;
}
/**
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManager.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManager.java
index 39cf6f1b75f..d5ac06062c3 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManager.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManager.java
@@ -156,10 +156,10 @@ public class RealtimeSegmentValidationManager extends
ControllerPeriodicTask<Rea
return false; // if table is paused by admin, then skip subsequent checks
}
// Perform resource utilization checks.
- boolean isResourceUtilizationWithinLimits =
+ UtilizationChecker.CheckResult isResourceUtilizationWithinLimits =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(tableNameWithType,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- if (!isResourceUtilizationWithinLimits) {
+ if (isResourceUtilizationWithinLimits ==
UtilizationChecker.CheckResult.FAIL) {
LOGGER.warn("Resource utilization limit exceeded for table: {}",
tableNameWithType);
_controllerMetrics.setOrUpdateTableGauge(tableNameWithType,
ControllerGauge.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
1L);
@@ -170,14 +170,22 @@ public class RealtimeSegmentValidationManager extends
ControllerPeriodicTask<Rea
PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
"Resource utilization limit exceeded.");
}
return false; // if resource utilization check failed, then skip
subsequent checks
+ } else if ((isResourceUtilizationWithinLimits ==
UtilizationChecker.CheckResult.PASS) && isTablePaused
+ &&
pauseStatus.getReasonCode().equals(PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED))
{
// within limits and table previously paused by resource utilization -->
unpause
- } else if (isTablePaused && pauseStatus.getReasonCode()
- .equals(PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED)) {
+ LOGGER.info("Resource utilization limit is back within limits for table:
{}", tableNameWithType);
// unset the pause state and allow consuming segment recreation.
_llcRealtimeSegmentManager.updatePauseStateInIdealState(tableNameWithType,
false,
PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED, "Resource
utilization within limits");
pauseStatus =
_llcRealtimeSegmentManager.getPauseStatusDetails(tableNameWithType);
isTablePaused = pauseStatus.getPauseFlag();
+ } else if ((isResourceUtilizationWithinLimits ==
UtilizationChecker.CheckResult.UNDETERMINED) && isTablePaused
+ &&
pauseStatus.getReasonCode().equals(PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED))
{
+ // The table was previously paused due to exceeding resource
utilization, but the current status cannot be
+ // determined. To be safe, leave it as paused and once the status is
available take the correct action
+ LOGGER.warn("Resource utilization limit could not be determined for for
table: {}, and it is paused, leave it as "
+ + "paused", tableNameWithType);
+ return false;
}
_controllerMetrics.setOrUpdateTableGauge(tableNameWithType,
ControllerGauge.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
0L);
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/ResourceUtilizationManager.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/ResourceUtilizationManager.java
index 396d6ba68c4..cda90ed71eb 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/ResourceUtilizationManager.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/ResourceUtilizationManager.java
@@ -38,22 +38,38 @@ public class ResourceUtilizationManager {
_utilizationCheckers = utilizationCheckers;
}
- public boolean isResourceUtilizationWithinLimits(String tableNameWithType,
UtilizationChecker.CheckPurpose purpose) {
+ /**
+ * Returns the status of the resource utilization check across all
UtilizationCheckers
+ * @param tableNameWithType table name with type
+ * @param purpose the purpose of the utilization check
+ * @return CheckResult, FAIL if even one resource utilization checker has
returned FALSE, UNDETERMINED if the result
+ * cannot be determined for even one UtilizationChecker and all the
others are also UNDETERMINED or PASS,
+ * and PASS if resource utilization is within limits for all
UtilizationCheckers
+ */
+ public UtilizationChecker.CheckResult
isResourceUtilizationWithinLimits(String tableNameWithType,
+ UtilizationChecker.CheckPurpose purpose) {
if (!_isResourceUtilizationCheckEnabled) {
- return true;
+ return UtilizationChecker.CheckResult.PASS;
}
if (StringUtils.isEmpty(tableNameWithType)) {
throw new IllegalArgumentException("Table name found to be null or empty
while checking resource utilization.");
}
LOGGER.info("Checking resource utilization for table: {}",
tableNameWithType);
- boolean overallIsResourceUtilizationWithinLimits = true;
+ UtilizationChecker.CheckResult overallIsResourceUtilizationWithinLimits =
UtilizationChecker.CheckResult.PASS;
for (UtilizationChecker utilizationChecker : _utilizationCheckers) {
- boolean isResourceUtilizationWithinLimits =
+ UtilizationChecker.CheckResult isResourceUtilizationWithinLimits =
utilizationChecker.isResourceUtilizationWithinLimits(tableNameWithType,
purpose);
LOGGER.info("For utilization checker: {},
isResourceUtilizationWithinLimits: {}, purpose: {}",
utilizationChecker.getName(), isResourceUtilizationWithinLimits,
purpose);
- if (!isResourceUtilizationWithinLimits) {
- overallIsResourceUtilizationWithinLimits = false;
+ if (isResourceUtilizationWithinLimits ==
UtilizationChecker.CheckResult.FAIL) {
+ // If any UtilizationChecker returns FAIL, we should mark the overall
as FAIL. FAIL should always have
+ // priority over other results
+ overallIsResourceUtilizationWithinLimits =
UtilizationChecker.CheckResult.FAIL;
+ } else if ((overallIsResourceUtilizationWithinLimits ==
UtilizationChecker.CheckResult.PASS)
+ && (isResourceUtilizationWithinLimits ==
UtilizationChecker.CheckResult.UNDETERMINED)) {
+ // If we haven't already updated the overall to a value other than
PASS, and we get an UNDETERMINED result,
+ // update the overall to UNDETERMINED. Should not update to
UNDETERMINED if we have set the overall to FAIL
+ overallIsResourceUtilizationWithinLimits =
UtilizationChecker.CheckResult.UNDETERMINED;
}
}
return overallIsResourceUtilizationWithinLimits;
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/UtilizationChecker.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/UtilizationChecker.java
index 2a4cdc9ce19..7b122bb98f1 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/validation/UtilizationChecker.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/validation/UtilizationChecker.java
@@ -32,11 +32,12 @@ public interface UtilizationChecker {
String getName();
/**
- * Returns true if the resource's utilization is within limits
+ * Returns whether the resource's utilization is within limits
* @param tableNameWithType table name with type
* @param purpose purpose of this check
+ * @return CheckResult, UNDETERMINED if result cannot be determined, PASS if
within limits, FAIL if not within limits
*/
- boolean isResourceUtilizationWithinLimits(String tableNameWithType,
CheckPurpose purpose);
+ CheckResult isResourceUtilizationWithinLimits(String tableNameWithType,
CheckPurpose purpose);
/**
* Computes the resource's utilization
@@ -55,4 +56,11 @@ public interface UtilizationChecker {
// TASK_GENERATION if the check is performed from the task generation
framework to pause creation of new tasks
REALTIME_INGESTION, TASK_GENERATION
}
+
+ enum CheckResult {
+ // PASS if the resource's utilization is within limits
+ // FAIL if the resource's utilization is not within limits
+ // UNDETERMINED if the result cannot be determined due to not having
sufficient information
+ PASS, FAIL, UNDETERMINED
+ }
}
diff --git
a/pinot-controller/src/test/java/org/apache/pinot/controller/validation/DiskUtilizationCheckerTest.java
b/pinot-controller/src/test/java/org/apache/pinot/controller/validation/DiskUtilizationCheckerTest.java
index 3e29c0c57f7..4643fc7aa04 100644
---
a/pinot-controller/src/test/java/org/apache/pinot/controller/validation/DiskUtilizationCheckerTest.java
+++
b/pinot-controller/src/test/java/org/apache/pinot/controller/validation/DiskUtilizationCheckerTest.java
@@ -80,27 +80,55 @@ public class DiskUtilizationCheckerTest {
String tableName = "test_OFFLINE";
when(_helixResourceManager.getOfflineTableConfig(tableName)).thenReturn(null);
- boolean result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckResult result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertTrue(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS);
result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertTrue(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS);
}
@Test
public void testIsDiskUtilizationWithinLimitsNonExistentRealtimeTable() {
String tableName = "test_REALTIME";
-
when(_helixResourceManager.getRealtimeTableConfig(tableName)).thenReturn(null);
+ when(_helixResourceManager.getTableConfig(tableName)).thenReturn(null);
- boolean result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckResult result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertTrue(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS);
result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertTrue(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS);
+ }
+
+ @Test
+ public void testIsDiskUtilizationStale() {
+ String tableName = "test_OFFLINE";
+
+ TableConfig mockTableConfig = mock(TableConfig.class);
+
when(_helixResourceManager.getTableConfig(tableName)).thenReturn(mockTableConfig);
+
+ List<String> mockInstances = Arrays.asList("server1", "server2");
+ when(_helixResourceManager.getServerInstancesForTable(tableName,
TableType.OFFLINE)).thenReturn(mockInstances);
+
+ // Mock disk usage
+ Map<String, DiskUsageInfo> diskUsageInfoMap = new HashMap<>();
+ DiskUsageInfo diskUsageInfo1 = new DiskUsageInfo("server1");
+ diskUsageInfoMap.put("server1", diskUsageInfo1);
+
+ DiskUsageInfo diskUsageInfo2 = new DiskUsageInfo("server2");
+ diskUsageInfoMap.put("server2", diskUsageInfo2);
+ ResourceUtilizationInfo.setDiskUsageInfo(diskUsageInfoMap);
+
+ UtilizationChecker.CheckResult result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.UNDETERMINED);
+
+ result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckPurpose.TASK_GENERATION);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.UNDETERMINED);
}
@Test
@@ -108,7 +136,7 @@ public class DiskUtilizationCheckerTest {
String tableName = "test_OFFLINE";
TableConfig mockTableConfig = mock(TableConfig.class);
-
when(_helixResourceManager.getOfflineTableConfig(tableName)).thenReturn(mockTableConfig);
+
when(_helixResourceManager.getTableConfig(tableName)).thenReturn(mockTableConfig);
List<String> mockInstances = Arrays.asList("server1", "server2");
when(_helixResourceManager.getServerInstancesForTable(tableName,
TableType.OFFLINE)).thenReturn(mockInstances);
@@ -124,13 +152,13 @@ public class DiskUtilizationCheckerTest {
diskUsageInfoMap.put("server2", diskUsageInfo2);
ResourceUtilizationInfo.setDiskUsageInfo(diskUsageInfoMap);
- boolean result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckResult result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertTrue(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS);
result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertTrue(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS);
}
@Test
@@ -154,13 +182,13 @@ public class DiskUtilizationCheckerTest {
diskUsageInfoMap.put("server2", diskUsageInfo2);
ResourceUtilizationInfo.setDiskUsageInfo(diskUsageInfoMap);
- boolean result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
+ UtilizationChecker.CheckResult result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertFalse(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.FAIL);
result =
_diskUtilizationChecker.isResourceUtilizationWithinLimits(tableName,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertFalse(result);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.FAIL);
}
@Test
diff --git
a/pinot-controller/src/test/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManagerTest.java
b/pinot-controller/src/test/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManagerTest.java
index 9c435a48e88..4c74c0bc1f3 100644
---
a/pinot-controller/src/test/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManagerTest.java
+++
b/pinot-controller/src/test/java/org/apache/pinot/controller/validation/RealtimeSegmentValidationManagerTest.java
@@ -74,29 +74,40 @@ public class RealtimeSegmentValidationManagerTest {
public Object[][] testCases() {
return new Object[][]{
// Table is paused due to admin intervention, should return false
- {true, PauseState.ReasonCode.ADMINISTRATIVE, false, false, false},
+ {true, PauseState.ReasonCode.ADMINISTRATIVE,
UtilizationChecker.CheckResult.PASS, false, false},
// Resource utilization exceeded and pause state is updated, should
return false
- {false, PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
true, false, false},
+ {false, PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
UtilizationChecker.CheckResult.FAIL, false,
+ false},
// Resource utilization is within limits but was previously paused due
to resource utilization,
// should return true
- {true, PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
false, false, true},
+ {true, PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
UtilizationChecker.CheckResult.PASS, false,
+ true},
+
+ // Resource utilization is STALE but was previously paused due to
resource utilization, should return false
+ {true, PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
UtilizationChecker.CheckResult.UNDETERMINED,
+ false, false},
+
+ // Resource utilization is STALE but was not previously paused due to
resource utilization, should return true
+ {false, PauseState.ReasonCode.RESOURCE_UTILIZATION_LIMIT_EXCEEDED,
UtilizationChecker.CheckResult.UNDETERMINED,
+ false, true},
// Resource utilization is within limits but was previously paused due
to storage quota exceeded,
// should return false
- {true, PauseState.ReasonCode.STORAGE_QUOTA_EXCEEDED, false, true,
false},
+ {true, PauseState.ReasonCode.STORAGE_QUOTA_EXCEEDED,
UtilizationChecker.CheckResult.PASS, true, false},
// Storage quota exceeded, should return false
- {false, PauseState.ReasonCode.STORAGE_QUOTA_EXCEEDED, false, true,
false},
+ {false, PauseState.ReasonCode.STORAGE_QUOTA_EXCEEDED,
UtilizationChecker.CheckResult.PASS, true, false},
// Storage quota within limits but was previously paused due to
storage quota exceeded, should return true
- {true, PauseState.ReasonCode.STORAGE_QUOTA_EXCEEDED, false, false,
true}};
+ {true, PauseState.ReasonCode.STORAGE_QUOTA_EXCEEDED,
UtilizationChecker.CheckResult.PASS, false, true}};
}
@Test(dataProvider = "testCases")
public void testShouldEnsureConsuming(boolean isTablePaused,
PauseState.ReasonCode reasonCode,
- boolean isResourceUtilizationExceeded, boolean isQuotaExceeded, boolean
expectedResult) {
+ UtilizationChecker.CheckResult isResourceUtilizationWithinLimits,
boolean isQuotaExceeded,
+ boolean expectedResult) {
String tableName = "testTable_REALTIME";
PauseStatusDetails pauseStatus = mock(PauseStatusDetails.class);
TableConfig tableConfig = mock(TableConfig.class);
@@ -105,7 +116,7 @@ public class RealtimeSegmentValidationManagerTest {
when(pauseStatus.getReasonCode()).thenReturn(reasonCode);
when(_llcRealtimeSegmentManager.getPauseStatusDetails(tableName)).thenReturn(pauseStatus);
when(_resourceUtilizationManager.isResourceUtilizationWithinLimits(tableName,
-
UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(!isResourceUtilizationExceeded);
+
UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(isResourceUtilizationWithinLimits);
when(_pinotHelixResourceManager.getTableConfig(tableName)).thenReturn(tableConfig);
when(_storageQuotaChecker.isTableStorageQuotaExceeded(tableConfig)).thenReturn(isQuotaExceeded);
diff --git
a/pinot-controller/src/test/java/org/apache/pinot/controller/validation/ResourceUtilizationManagerTest.java
b/pinot-controller/src/test/java/org/apache/pinot/controller/validation/ResourceUtilizationManagerTest.java
index 9487105d530..a371d5dff40 100644
---
a/pinot-controller/src/test/java/org/apache/pinot/controller/validation/ResourceUtilizationManagerTest.java
+++
b/pinot-controller/src/test/java/org/apache/pinot/controller/validation/ResourceUtilizationManagerTest.java
@@ -46,13 +46,15 @@ public class ResourceUtilizationManagerTest {
Mockito.when(_controllerConf.isResourceUtilizationCheckEnabled()).thenReturn(false);
_resourceUtilizationManager = new
ResourceUtilizationManager(_controllerConf, _utilizationCheckers);
- boolean result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
+ UtilizationChecker.CheckResult result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertTrue(result, "Resource utilization should be within limits
when the check is disabled");
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS,
+ "Resource utilization should be within limits when the check is
disabled");
result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertTrue(result, "Resource utilization should be within limits
when the check is disabled");
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS,
+ "Resource utilization should be within limits when the check is
disabled");
}
@Test(expectedExceptions = IllegalArgumentException.class)
@@ -95,35 +97,59 @@ public class ResourceUtilizationManagerTest {
public void testIsResourceUtilizationWithinLimitsWhenCheckIsEnabled() {
Mockito.when(_controllerConf.isResourceUtilizationCheckEnabled()).thenReturn(true);
Mockito.when(_diskUtilizationChecker.isResourceUtilizationWithinLimits(_testTable,
- UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(true);
+
UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(UtilizationChecker.CheckResult.PASS);
_resourceUtilizationManager = new
ResourceUtilizationManager(_controllerConf, _utilizationCheckers);
- boolean result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
+ UtilizationChecker.CheckResult result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertTrue(result, "Resource utilization should be within limits
when disk check and primary key count "
- + "check returns true");
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS,
+ "Resource utilization should be within limits when disk check and
primary key count check returns true");
Mockito.when(_diskUtilizationChecker.isResourceUtilizationWithinLimits(_testTable,
- UtilizationChecker.CheckPurpose.TASK_GENERATION)).thenReturn(true);
+
UtilizationChecker.CheckPurpose.TASK_GENERATION)).thenReturn(UtilizationChecker.CheckResult.PASS);
result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertTrue(result, "Resource utilization should be within limits
when disk check and primary key count "
- + "check returns true");
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.PASS,
+ "Resource utilization should be within limits when disk check and
primary key count check returns true");
}
@Test
public void testIsResourceUtilizationWithinLimitsWhenCheckFails() {
Mockito.when(_controllerConf.isResourceUtilizationCheckEnabled()).thenReturn(true);
Mockito.when(_diskUtilizationChecker.isResourceUtilizationWithinLimits(_testTable,
- UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(false);
+
UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(UtilizationChecker.CheckResult.FAIL);
+
Mockito.when(_diskUtilizationChecker.isResourceUtilizationWithinLimits(_testTable,
+
UtilizationChecker.CheckPurpose.TASK_GENERATION)).thenReturn(UtilizationChecker.CheckResult.FAIL);
+ _resourceUtilizationManager = new
ResourceUtilizationManager(_controllerConf, _utilizationCheckers);
+
+ UtilizationChecker.CheckResult result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
+ UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.FAIL,
+ "Resource utilization should not be within limits when disk check
returns false");
+
+ result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
+ UtilizationChecker.CheckPurpose.TASK_GENERATION);
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.FAIL,
+ "Resource utilization should not be within limits when disk check
returns false");
+ }
+
+ @Test
+ public void testIsResourceUtilizationWithinLimitsWhenCheckStale() {
+
Mockito.when(_controllerConf.isResourceUtilizationCheckEnabled()).thenReturn(true);
+
Mockito.when(_diskUtilizationChecker.isResourceUtilizationWithinLimits(_testTable,
+
UtilizationChecker.CheckPurpose.REALTIME_INGESTION)).thenReturn(UtilizationChecker.CheckResult.UNDETERMINED);
+
Mockito.when(_diskUtilizationChecker.isResourceUtilizationWithinLimits(_testTable,
+
UtilizationChecker.CheckPurpose.TASK_GENERATION)).thenReturn(UtilizationChecker.CheckResult.UNDETERMINED);
_resourceUtilizationManager = new
ResourceUtilizationManager(_controllerConf, _utilizationCheckers);
- boolean result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
+ UtilizationChecker.CheckResult result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
UtilizationChecker.CheckPurpose.REALTIME_INGESTION);
- Assert.assertFalse(result, "Resource utilization should not be within
limits when disk check returns false");
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.UNDETERMINED,
+ "Resource utilization should return STALE when the diskUtilization
returns STALE");
result =
_resourceUtilizationManager.isResourceUtilizationWithinLimits(_testTable,
UtilizationChecker.CheckPurpose.TASK_GENERATION);
- Assert.assertFalse(result, "Resource utilization should not be within
limits when disk check returns false");
+ Assert.assertEquals(result, UtilizationChecker.CheckResult.UNDETERMINED,
+ "Resource utilization should return STALE when the diskUtilization
returns STALE");
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]