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));
+  }
 }

Reply via email to