This is an automated email from the ASF dual-hosted git repository.
dlmarion pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push:
new 069c4f4705 Added more tests to ResourceGroupConfigIT (#5864)
069c4f4705 is described below
commit 069c4f47052ce82c00474916ae0d836cae7a1dd9
Author: Dave Marion <[email protected]>
AuthorDate: Mon Sep 8 13:18:42 2025 -0400
Added more tests to ResourceGroupConfigIT (#5864)
Related to #5859
---
.../ClusterServerConfiguration.java | 10 +
.../MiniAccumuloClusterControl.java | 11 ++
.../accumulo/test/conf/ResourceGroupConfigIT.java | 220 +++++++++++++++++++++
3 files changed, 241 insertions(+)
diff --git
a/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/ClusterServerConfiguration.java
b/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/ClusterServerConfiguration.java
index 13fa4b9389..e37ad98053 100644
---
a/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/ClusterServerConfiguration.java
+++
b/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/ClusterServerConfiguration.java
@@ -101,6 +101,16 @@ public class ClusterServerConfiguration {
}
}
+ public void clearSServerResourceGroups() {
+ Iterator<String> iter = sservers.keySet().iterator();
+ while (iter.hasNext()) {
+ String resourceGroup = iter.next();
+ if (!resourceGroup.equals(Constants.DEFAULT_RESOURCE_GROUP_NAME)) {
+ iter.remove();
+ }
+ }
+ }
+
public void clearTServerResourceGroups() {
Iterator<String> iter = tservers.keySet().iterator();
while (iter.hasNext()) {
diff --git
a/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterControl.java
b/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterControl.java
index bd24aeb596..fc6762d730 100644
---
a/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterControl.java
+++
b/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterControl.java
@@ -282,6 +282,17 @@ public class MiniAccumuloClusterControl implements
ClusterControl {
}
}
+ public void stopScanServerGroup(String sserverResourceGroup) {
+ synchronized (scanServerProcesses) {
+ var group = scanServerProcesses.get(sserverResourceGroup);
+ if (group == null) {
+ return;
+ }
+ cluster.stopProcessesWithTimeout(ServerType.SCAN_SERVER, group, 30,
TimeUnit.SECONDS);
+ scanServerProcesses.remove(sserverResourceGroup);
+ }
+ }
+
public void stopTabletServerGroup(String tserverResourceGroup) {
synchronized (tabletServerProcesses) {
var group = tabletServerProcesses.get(tserverResourceGroup);
diff --git
a/test/src/main/java/org/apache/accumulo/test/conf/ResourceGroupConfigIT.java
b/test/src/main/java/org/apache/accumulo/test/conf/ResourceGroupConfigIT.java
index 27af8a62c4..fd52c42bc2 100644
---
a/test/src/main/java/org/apache/accumulo/test/conf/ResourceGroupConfigIT.java
+++
b/test/src/main/java/org/apache/accumulo/test/conf/ResourceGroupConfigIT.java
@@ -22,21 +22,28 @@ import static
org.apache.accumulo.harness.AccumuloITBase.MINI_CLUSTER_ONLY;
import static org.apache.accumulo.harness.AccumuloITBase.SUNNY_DAY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.time.Duration;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.function.Consumer;
+import org.apache.accumulo.cluster.ClusterUser;
import org.apache.accumulo.core.Constants;
import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.ResourceGroupNotFoundException;
import org.apache.accumulo.core.client.admin.InstanceOperations;
import org.apache.accumulo.core.client.admin.ResourceGroupOperations;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
+import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.clientImpl.ClientContext;
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.core.data.ResourceGroupId;
@@ -45,6 +52,7 @@ import
org.apache.accumulo.core.lock.ServiceLockPaths.AddressSelector;
import org.apache.accumulo.core.lock.ServiceLockPaths.ResourceGroupPredicate;
import org.apache.accumulo.core.lock.ServiceLockPaths.ServiceLockPath;
import org.apache.accumulo.core.rpc.clients.TServerClient;
+import org.apache.accumulo.core.security.SystemPermission;
import org.apache.accumulo.harness.MiniClusterConfigurationCallback;
import org.apache.accumulo.harness.SharedMiniClusterBase;
import org.apache.accumulo.miniclusterImpl.MiniAccumuloConfigImpl;
@@ -177,6 +185,24 @@ public class ResourceGroupConfigIT extends
SharedMiniClusterBase {
() -> rgOps.removeProperty(invalid,
Property.COMPACTION_WARN_TIME.getKey()));
assertThrows(ResourceGroupNotFoundException.class, () ->
rgOps.remove(invalid));
+ getCluster().getClusterControl().stopCompactorGroup(RG);
+ getCluster().getClusterControl().stopScanServerGroup(RG);
+ getCluster().getClusterControl().stopTabletServerGroup(RG);
+
+
getCluster().getConfig().getClusterServerConfiguration().clearCompactorResourceGroups();
+
getCluster().getConfig().getClusterServerConfiguration().clearSServerResourceGroups();
+
getCluster().getConfig().getClusterServerConfiguration().clearTServerResourceGroups();
+
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getCompactor(ResourceGroupPredicate.exact(rgid),
AddressSelector.all(), true).size()
+ == 0);
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getScanServer(ResourceGroupPredicate.exact(rgid),
AddressSelector.all(), true).size()
+ == 0);
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getTabletServer(ResourceGroupPredicate.exact(rgid),
AddressSelector.all(), true).size()
+ == 0);
+
rgOps.remove(rgid);
assertFalse(zrw.exists(rgpk.getPath()));
assertFalse(zrw.exists(rgpk.getPath()));
@@ -207,4 +233,198 @@ public class ResourceGroupConfigIT extends
SharedMiniClusterBase {
System.clearProperty(TServerClient.DEBUG_HOST);
}
+ @Test
+ public void testDefaultResourceGroup() throws Exception {
+ try (var client = Accumulo.newClient().from(getClientProps()).build()) {
+ Set<ResourceGroupId> rgs = client.resourceGroupOperations().list();
+ assertEquals(1, rgs.size());
+ assertEquals(ResourceGroupId.DEFAULT, rgs.iterator().next());
+ client.resourceGroupOperations().create(ResourceGroupId.DEFAULT);
+ assertThrows(AccumuloException.class,
+ () ->
client.resourceGroupOperations().remove(ResourceGroupId.DEFAULT));
+ }
+ }
+
+ @Test
+ public void testDuplicateCreatesRemovals()
+ throws AccumuloException, AccumuloSecurityException,
ResourceGroupNotFoundException {
+ final var rgid = ResourceGroupId.of("DUPES");
+ try (var client = Accumulo.newClient().from(getClientProps()).build()) {
+ Set<ResourceGroupId> rgs = client.resourceGroupOperations().list();
+ assertEquals(1, rgs.size());
+ assertEquals(ResourceGroupId.DEFAULT, rgs.iterator().next());
+ client.resourceGroupOperations().create(rgid);
+ Set<ResourceGroupId> rgs2 = new
HashSet<>(client.resourceGroupOperations().list());
+ assertEquals(2, rgs2.size());
+ assertTrue(rgs2.remove(ResourceGroupId.DEFAULT));
+ assertEquals(rgid, rgs2.iterator().next());
+ client.resourceGroupOperations().create(rgid); // creating again
succeeds doing nothing
+ client.resourceGroupOperations().remove(rgid);
+ rgs = client.resourceGroupOperations().list();
+ assertEquals(1, rgs.size());
+ assertEquals(ResourceGroupId.DEFAULT, rgs.iterator().next());
+ assertThrows(ResourceGroupNotFoundException.class,
+ () -> client.resourceGroupOperations().remove(rgid));
+ }
+ }
+
+ @Test
+ public void testPermissions() throws Exception {
+
+ ClusterUser testUser = getUser(0);
+
+ String principal = testUser.getPrincipal();
+ AuthenticationToken token = testUser.getToken();
+ PasswordToken passwordToken = null;
+ if (token instanceof PasswordToken) {
+ passwordToken = (PasswordToken) token;
+ }
+
+ ResourceGroupId rgid = ResourceGroupId.of("TEST_GROUP");
+
+ try (var client = Accumulo.newClient().from(getClientProps()).build()) {
+ client.securityOperations().createLocalUser(principal, passwordToken);
+ }
+
+ try (AccumuloClient test_user_client =
+ Accumulo.newClient().from(getClientProps()).as(principal,
token).build()) {
+ assertThrows(AccumuloSecurityException.class,
+ () -> test_user_client.resourceGroupOperations().create(rgid));
+ }
+
+ try (var client = Accumulo.newClient().from(getClientProps()).build()) {
+ client.resourceGroupOperations().create(rgid);
+ }
+
+ try (AccumuloClient test_user_client =
+ Accumulo.newClient().from(getClientProps()).as(principal,
token).build()) {
+ assertThrows(AccumuloSecurityException.class,
+ () -> test_user_client.resourceGroupOperations().remove(rgid));
+ }
+
+ try (var client = Accumulo.newClient().from(getClientProps()).build()) {
+ client.securityOperations().grantSystemPermission(principal,
SystemPermission.SYSTEM);
+ }
+
+ // Regular user with SYSTEM permission should now be able to create/remove
+ try (AccumuloClient test_user_client =
+ Accumulo.newClient().from(getClientProps()).as(principal,
token).build()) {
+ test_user_client.resourceGroupOperations().remove(rgid);
+ test_user_client.resourceGroupOperations().create(rgid);
+ }
+ }
+
+ @Test
+ public void testMultipleConfigurations() throws Exception {
+
+ final String FIRST = "FIRST";
+ final String SECOND = "SECOND";
+ final String THIRD = "THIRD";
+
+ final ResourceGroupId first = ResourceGroupId.of(FIRST);
+ final ResourceGroupId second = ResourceGroupId.of(SECOND);
+ final ResourceGroupId third = ResourceGroupId.of(THIRD);
+
+ // @formatter:off
+ Map<String,String> firstProps = Map.of(
+ Property.COMPACTION_WARN_TIME.getKey(), "1m",
+ Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey(), "4",
+ Property.TSERV_ASSIGNMENT_MAXCONCURRENT.getKey(), "10");
+
+ Map<String,String> secondProps = Map.of(
+ Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey(), "5",
+ Property.TSERV_ASSIGNMENT_MAXCONCURRENT.getKey(), "10");
+
+ Map<String,String> thirdProps = Map.of(
+ Property.COMPACTION_WARN_TIME.getKey(), "1m",
+ Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey(), "6");
+ // @formatter:off
+
+ try (var client = Accumulo.newClient().from(getClientProps()).build()) {
+
+
client.instanceOperations().setProperty(Property.COMPACTION_WARN_TIME.getKey(),
"1m");
+
+ // Set the SSERV_WAL_SORT_MAX_CONCURRENT property to 3. The default is 2
+ // and the resource groups will override to 4, 5, and 6. We should never
+ // see 2 or 3 when getting the running configurations from the processes.
+
client.instanceOperations().setProperty(Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey(),
"3");
+
+ @SuppressWarnings("resource")
+ ClientContext cc = (ClientContext) client;
+
+ final ResourceGroupOperations rgops = client.resourceGroupOperations();
+
+ rgops.create(first);
+ rgops.create(second);
+ rgops.create(third);
+
+
getCluster().getConfig().getClusterServerConfiguration().setNumDefaultCompactors(1);
+
getCluster().getConfig().getClusterServerConfiguration().addCompactorResourceGroup(FIRST,
1);
+
getCluster().getConfig().getClusterServerConfiguration().addCompactorResourceGroup(SECOND,
1);
+
getCluster().getConfig().getClusterServerConfiguration().addCompactorResourceGroup(THIRD,
1);
+ getCluster().start();
+
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getCompactor(ResourceGroupPredicate.exact(first),
AddressSelector.all(), true).size()
+ == 1);
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getCompactor(ResourceGroupPredicate.exact(second),
AddressSelector.all(), true).size()
+ == 1);
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getCompactor(ResourceGroupPredicate.exact(third),
AddressSelector.all(), true).size()
+ == 1);
+
+ rgops.modifyProperties(first, (map) -> {
+ map.putAll(firstProps);
+ });
+ rgops.modifyProperties(second, (map) -> {
+ map.putAll(secondProps);
+ });
+ rgops.modifyProperties(third, (map) -> {
+ map.putAll(thirdProps);
+ });
+
+ System.setProperty(TServerClient.DEBUG_RG, FIRST);
+ Map<String,String> sysConfig =
client.instanceOperations().getSystemConfiguration();
+ assertEquals("3",
sysConfig.get(Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey()));
+ compareConfigurations(sysConfig, firstProps,
rgops.getConfiguration(first));
+
+ System.setProperty(TServerClient.DEBUG_RG, SECOND);
+ sysConfig = client.instanceOperations().getSystemConfiguration();
+ assertEquals("3",
sysConfig.get(Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey()));
+ compareConfigurations(sysConfig, secondProps,
rgops.getConfiguration(second));
+
+ System.setProperty(TServerClient.DEBUG_RG, THIRD);
+ sysConfig = client.instanceOperations().getSystemConfiguration();
+ assertEquals("3",
sysConfig.get(Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey()));
+ compareConfigurations(sysConfig, thirdProps,
rgops.getConfiguration(third));
+
+ getCluster().getClusterControl().stopCompactorGroup(FIRST);
+ getCluster().getClusterControl().stopCompactorGroup(SECOND);
+ getCluster().getClusterControl().stopCompactorGroup(THIRD);
+
+
getCluster().getConfig().getClusterServerConfiguration().clearCompactorResourceGroups();
+
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getCompactor(ResourceGroupPredicate.exact(first),
AddressSelector.all(), true).size()
+ == 0);
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getScanServer(ResourceGroupPredicate.exact(second),
AddressSelector.all(), true).size()
+ == 0);
+ Wait.waitFor(() -> cc.getServerPaths()
+ .getTabletServer(ResourceGroupPredicate.exact(third),
AddressSelector.all(), true).size()
+ == 0);
+ }
+ }
+
+ private void compareConfigurations(Map<String,String> sysConfig,
Map<String,String> rgConfig, Map<String,String> actual) {
+
+ assertEquals("1m", actual.get(Property.COMPACTION_WARN_TIME.getKey()));
+ assertNotEquals("2",
actual.get(Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey()));
+ assertNotEquals("3",
actual.get(Property.SSERV_WAL_SORT_MAX_CONCURRENT.getKey()));
+
+ TreeMap<String,String> expected = new TreeMap<>(sysConfig);
+ expected.putAll(rgConfig);
+ assertEquals(expected, new TreeMap<>(actual));
+ }
}