This is an automated email from the ASF dual-hosted git repository.
pradeep pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 4d8e9f710 RANGER-5273:Adding unit tests for plugin-kms module (#621)
4d8e9f710 is described below
commit 4d8e9f710e48dbc4d1511e012ded0fc6f54af81f
Author: Chinmay Hegde <[email protected]>
AuthorDate: Thu Aug 21 17:31:21 2025 +0530
RANGER-5273:Adding unit tests for plugin-kms module (#621)
---
plugin-kms/pom.xml | 12 +
.../kms/authorizer/RangerKMSAccessRequestTest.java | 53 +++++
.../kms/authorizer/RangerKMSPluginTest.java | 54 +++++
.../kms/authorizer/RangerKMSResourceTest.java | 52 +++++
.../kms/authorizer/RangerKmsAuthorizerTest.java | 114 +++++++++
.../ranger/services/kms/RangerServiceKMSTest.java | 155 +++++++++++++
.../ranger/services/kms/client/KMSClientTest.java | 255 +++++++++++++++++++++
.../services/kms/client/KMSConnectionMgrTest.java | 81 +++++++
.../services/kms/client/KMSResourceMgrTest.java | 150 ++++++++++++
.../json/model/KMSSchedulerResponseTest.java | 193 ++++++++++++++++
10 files changed, 1119 insertions(+)
diff --git a/plugin-kms/pom.xml b/plugin-kms/pom.xml
index a35b14d66..24aaa9f8c 100644
--- a/plugin-kms/pom.xml
+++ b/plugin-kms/pom.xml
@@ -70,6 +70,18 @@
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-inline</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSAccessRequestTest.java
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSAccessRequestTest.java
new file mode 100644
index 000000000..26803e0f9
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSAccessRequestTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.authorization.kms.authorizer;
+
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class RangerKMSAccessRequestTest {
+ @Test
+ void testConstructor_SetsFieldsCorrectly() {
+ String keyName = "abc";
+ String accessType = "read";
+ String clientIp = "1.1.1.1";
+ String userName = "chegde";
+ String[] groups = {"group1", "group2"};
+ UserGroupInformation ugi =
UserGroupInformation.createUserForTesting(userName, groups);
+
+ RangerKMSAccessRequest request = new RangerKMSAccessRequest(keyName,
accessType, ugi, clientIp);
+
+ assertNotNull(request.getResource());
+ assertEquals(keyName, request.getResource().getValue("keyname"));
+ assertEquals(accessType, request.getAccessType());
+ assertEquals(userName, request.getUser());
+ Set<String> userGroups = request.getUserGroups();
+ assertNotNull(userGroups);
+ assertTrue(userGroups.contains("group1"));
+ assertTrue(userGroups.contains("group2"));
+ assertNotNull(request.getAccessTime());
+ assertEquals(clientIp, request.getClientIPAddress());
+ assertEquals(accessType, request.getAction());
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSPluginTest.java
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSPluginTest.java
new file mode 100644
index 000000000..4061316df
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSPluginTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.authorization.kms.authorizer;
+
+import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+class RangerKMSPluginTest {
+ private RangerKMSPlugin plugin;
+
+ @BeforeEach
+ void setUp() {
+ plugin = new RangerKMSPlugin();
+ }
+
+ @Test
+ void testConstructor_SetsServiceTypeAndAppId() {
+ assertEquals("kms", plugin.getServiceType());
+ assertEquals("kms", plugin.getAppId());
+ }
+
+ @Test
+ void testInitSets_ResultProcessor() {
+ RangerKMSPlugin spyPlugin = spy(new RangerKMSPlugin());
+ doNothing().when((RangerBasePlugin)
spyPlugin).setResultProcessor(any());
+
+ spyPlugin.init();
+
+ verify((RangerBasePlugin)
spyPlugin).setResultProcessor(any(RangerDefaultAuditHandler.class));
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSResourceTest.java
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSResourceTest.java
new file mode 100644
index 000000000..232c76a78
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKMSResourceTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.authorization.kms.authorizer;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class RangerKMSResourceTest {
+ @Test
+ void testConstructor_WithNonNullKeyname() {
+ String keyname = "key1";
+ RangerKMSResource resource = new RangerKMSResource(keyname);
+ assertEquals(keyname, resource.getValue("keyname"));
+ assertTrue(resource.exists("keyname"));
+ }
+
+ @Test
+ void testConstructor_WithNullKeyname() {
+ RangerKMSResource resource = new RangerKMSResource(null);
+ assertNull(resource.getValue("keyname"));
+ assertFalse(resource.exists("keyname"));
+ }
+
+ @Test
+ void testSetValue() {
+ RangerKMSResource resource = new RangerKMSResource("initial");
+ resource.setValue("key2", "updatedKey2");
+ assertEquals("updatedKey2", resource.getValue("key2"));
+ resource.setValue("key2", null);
+ assertNull(resource.getValue("key2"));
+ assertFalse(resource.exists("key2"));
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKmsAuthorizerTest.java
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKmsAuthorizerTest.java
index 6955f922c..0f6541d2e 100644
---
a/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKmsAuthorizerTest.java
+++
b/plugin-kms/src/test/java/org/apache/ranger/authorization/kms/authorizer/RangerKmsAuthorizerTest.java
@@ -17,12 +17,15 @@
package org.apache.ranger.authorization.kms.authorizer;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.crypto.key.kms.server.KMS.KMSOp;
import org.apache.hadoop.crypto.key.kms.server.KMSACLsType.Type;
import org.apache.hadoop.crypto.key.kms.server.KMSConfiguration;
import org.apache.hadoop.crypto.key.kms.server.KMSWebApp;
+import
org.apache.hadoop.crypto.key.kms.server.KeyAuthorizationKeyProvider.KeyOpType;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AuthorizationException;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@@ -42,6 +45,10 @@
import java.nio.file.Paths;
import java.security.PrivilegedExceptionAction;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
/**
* Policies available from admin via:
* <p>
@@ -380,6 +387,113 @@ public Void run() throws Exception {
});
}
+ @Test
+ public void testHasAccessToKey() {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ UserGroupInformation ugi =
UserGroupInformation.createRemoteUser("john");
+ boolean result = authorizer.hasAccessToKey("key1", ugi,
KeyOpType.MANAGEMENT);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsACLPresent() {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ boolean result = authorizer.isACLPresent("key1", KeyOpType.MANAGEMENT);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testStartAndStopReloader() {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ authorizer.startReloader();
+ // Should not throw, and executorService should not be null after start
+ authorizer.stopReloader();
+ }
+
+ @Test
+ public void testRunReloadsACLs() {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ assertDoesNotThrow(authorizer::run);
+ }
+
+ @Test
+ public void testInit() {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ Configuration conf = Mockito.mock(Configuration.class);
+ assertDoesNotThrow(() -> authorizer.init(conf));
+ }
+
+ /**
+ * @generated by copilot
+ */
+ @Test
+ public void testSetKMSACLs() {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ Configuration conf = Mockito.mock(Configuration.class);
+ Mockito.when(conf.get(Mockito.anyString())).thenReturn("user1,user2");
+ // Use reflection to call private setKMSACLs
+ assertDoesNotThrow(() -> {
+ java.lang.reflect.Method m =
RangerKmsAuthorizer.class.getDeclaredMethod("setKMSACLs", Configuration.class);
+ m.setAccessible(true);
+ m.invoke(authorizer, conf);
+ });
+ }
+
+ /**
+ * @generated by copilot
+ */
+ @Test
+ public void testHasAccess_UserInBlacklist() throws Exception {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ // Use reflection to set a blacklist for CREATE
+ java.lang.reflect.Field blacklistField =
RangerKmsAuthorizer.class.getDeclaredField("blacklistedAcls");
+ blacklistField.setAccessible(true);
+ java.util.Map<Type,
org.apache.hadoop.security.authorize.AccessControlList> blacklist = new
java.util.HashMap<>();
+ blacklist.put(Type.CREATE, new
org.apache.hadoop.security.authorize.AccessControlList("bob"));
+ blacklistField.set(authorizer, blacklist);
+ UserGroupInformation ugi =
UserGroupInformation.createRemoteUser("bob");
+ boolean result = authorizer.hasAccess(Type.CREATE, ugi, "127.0.0.1");
+ assertFalse(result, "User in blacklist should not have access");
+ }
+
+ /**
+ * @generated by copilot
+ */
+ @Test
+ public void testHasAccess_WithPluginAllows() throws Exception {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ // No blacklist, but plugin returns allowed
+ RangerKMSPlugin plugin = Mockito.mock(RangerKMSPlugin.class);
+ RangerAccessResult accessResult =
Mockito.mock(RangerAccessResult.class);
+ Mockito.when(accessResult.getIsAllowed()).thenReturn(true);
+
Mockito.when(plugin.isAccessAllowed((org.apache.ranger.plugin.policyengine.RangerAccessRequest)
Mockito.any())).thenReturn(accessResult);
+ java.lang.reflect.Field pluginField =
RangerKmsAuthorizer.class.getDeclaredField("kmsPlugin");
+ pluginField.setAccessible(true);
+ pluginField.set(null, plugin);
+ UserGroupInformation ugi =
UserGroupInformation.createRemoteUser("bob");
+ boolean result = authorizer.hasAccess(Type.CREATE, ugi, "127.0.0.1");
+ assertTrue(result, "Plugin allows access");
+ }
+
+ /**
+ * @generated by copilot
+ */
+ @Test
+ public void testHasAccess_WithPluginDenies() throws Exception {
+ RangerKmsAuthorizer authorizer = new
RangerKmsAuthorizer((Configuration) null);
+ // No blacklist, but plugin returns denied
+ RangerKMSPlugin plugin = Mockito.mock(RangerKMSPlugin.class);
+ RangerAccessResult accessResult =
Mockito.mock(RangerAccessResult.class);
+ Mockito.when(accessResult.getIsAllowed()).thenReturn(false);
+
Mockito.when(plugin.isAccessAllowed((org.apache.ranger.plugin.policyengine.RangerAccessRequest)
Mockito.any())).thenReturn(accessResult);
+ java.lang.reflect.Field pluginField =
RangerKmsAuthorizer.class.getDeclaredField("kmsPlugin");
+ pluginField.setAccessible(true);
+ pluginField.set(null, plugin);
+ UserGroupInformation ugi =
UserGroupInformation.createRemoteUser("bob");
+ boolean result = authorizer.hasAccess(Type.CREATE, ugi, "127.0.0.1");
+ assertFalse(result, "Plugin denies access");
+ }
+
static {
boolean ok = false;
try {
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/services/kms/RangerServiceKMSTest.java
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/RangerServiceKMSTest.java
new file mode 100644
index 000000000..81e96edc8
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/RangerServiceKMSTest.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.services.kms;
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+* @generated by copilot
+* @description Unit Test cases for RangerServiceKMS
+*/
+@ExtendWith(MockitoExtension.class)
+class RangerServiceKMSTest {
+ static class TestableRangerServiceKMS extends RangerServiceKMS {
+ public void setServiceDef(RangerServiceDef def) {
+ this.serviceDef = def; }
+
+ public void setLookUpUser(String user) {
+ this.lookUpUser = user; }
+
+ @Override
+ public String getLookupUser(String authType, String adminPrincipal,
String adminKeytab) {
+ return this.lookUpUser;
+ }
+ }
+
+ @Spy
+ TestableRangerServiceKMS spyKMS;
+
+ @Mock
+ ResourceLookupContext mockContext;
+ @Mock
+ RangerServiceDef mockServiceDef;
+ @Mock
+ RangerService mockService;
+
+ @BeforeEach
+ void setUp() {
+ spyKMS = Mockito.spy(new TestableRangerServiceKMS());
+ }
+
+ @Test
+ void testValidateConfig_success() throws Exception {
+ Map<String, String> configs = new HashMap<>();
+ spyKMS.setConfigs(configs);
+ doReturn("serviceName").when(spyKMS).getServiceName();
+ try {
+ Map<String, Object> result = spyKMS.validateConfig();
+ assertNotNull(result);
+ } catch (Exception e) {
+ assertTrue(e.getMessage() != null);
+ }
+ }
+
+ @Test
+ void testValidateConfig_exception() throws Exception {
+ Map<String, String> configs = new HashMap<>();
+ spyKMS.setConfigs(configs);
+ doReturn("serviceName").when(spyKMS).getServiceName();
+ assertThrows(Exception.class, () -> spyKMS.validateConfig());
+ }
+
+ @Test
+ void testLookupResource_nullContext() {
+ List<String> result = spyKMS.lookupResource(null);
+ assertNotNull(result);
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ void testInit() {
+ RangerServiceDef serviceDef = new RangerServiceDef();
+ RangerService service = new RangerService();
+
+ spyKMS.init(serviceDef, service);
+
+ verify(spyKMS, times(1)).init(serviceDef, service);
+ }
+
+ @Test
+ void testCreateDefaultPolicyItem_emptyAccessTypes() {
+ TestableRangerServiceKMS service = new TestableRangerServiceKMS();
+ List<RangerAccessTypeDef> accessTypeDefs = new ArrayList<>();
+ List<String> users = Arrays.asList("user1");
+
+ try {
+ Method method =
RangerServiceKMS.class.getDeclaredMethod("createDefaultPolicyItem", List.class,
List.class);
+ method.setAccessible(true);
+ RangerPolicy.RangerPolicyItem policyItem =
+ (RangerPolicy.RangerPolicyItem) method.invoke(service,
accessTypeDefs, users);
+
+ assertNotNull(policyItem);
+ assertEquals(users, policyItem.getUsers());
+ assertTrue(policyItem.getAccesses().isEmpty());
+ assertTrue(policyItem.getDelegateAdmin());
+ } catch (Exception e) {
+ fail("Reflection call failed: " + e.getMessage());
+ }
+ }
+
+ @Test
+ void testLookupResource_exception() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+
+ doThrow(new RuntimeException("Test
exception")).when(spyKMS).getServiceName();
+
+ // Verify that the exception is propagated
+ assertThrows(RuntimeException.class, () -> {
+ spyKMS.lookupResource(context);
+ });
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSClientTest.java
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSClientTest.java
new file mode 100644
index 000000000..bd0064056
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSClientTest.java
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.services.kms.client;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.ProviderUtils;
+import org.apache.ranger.plugin.client.HadoopException;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+* @generated by copilot
+* @description Unit Test cases for KMSClient
+*/
+@ExtendWith(MockitoExtension.class)
+@TestMethodOrder(MethodOrderer.MethodName.class)
+public class KMSClientTest {
+ @Test
+ void createProvider_CreateSingleProvider_whenUriHasSingleHost() throws
Exception {
+ KMSClient kmsClient = new KMSClient("jceks://http@host1:9600/kms",
"user", "pass", "principal", "keytab", "rules", "simple");
+
+ String[] providers = invokeCreateProvider(kmsClient,
"jceks://http@host1:9600/kms");
+
+ assertEquals(1, providers.length);
+ assertEquals("http://host1:9600/kms", providers[0]);
+ }
+
+ @Test
+ public void testCreateProvider_multipleHosts() throws Exception {
+ KMSClient client = new KMSClient("jceks://http@host1:9600/kms",
"user", "pass", "principal", "keytab", "rules", "kerberos");
+
+ // Test a URI with multiple hosts
+ String uri =
"jceks://[email protected];host2.example.com;host3.example.com:9600/kms";
+
+ Method method = KMSClient.class.getDeclaredMethod("createProvider",
String.class);
+ method.setAccessible(true);
+
+ String[] providers = (String[]) method.invoke(client, uri);
+
+ assertNotNull(providers);
+ assertEquals(3, providers.length);
+ assertEquals("http://host1.example.com:9600/kms", providers[0]);
+ assertEquals("http://host2.example.com:9600/kms", providers[1]);
+ assertEquals("http://host3.example.com:9600/kms", providers[2]);
+ }
+
+ @Test
+ public void testCreateProvider_emptyAuthority() throws Exception {
+ KMSClient client = new KMSClient("jceks://http@host1:9600/kms",
"user", "pass", "principal", "keytab", "rules", "kerberos");
+
+ // URI with empty authority
+ String uri = "jceks:///kms";
+
+ Method method = KMSClient.class.getDeclaredMethod("createProvider",
String.class);
+ method.setAccessible(true);
+
+ InvocationTargetException thrown =
assertThrows(InvocationTargetException.class, () -> {
+ method.invoke(client, uri);
+ });
+
+ Throwable cause = thrown.getCause();
+ assertTrue(cause instanceof IOException);
+ }
+
+ @Test
+ public void testCreateProvider_invalidPort() {
+ KMSClient client = new KMSClient("jceks://http@host1:9600/kms",
"user", "pass", "principal", "keytab", "rules", "kerberos");
+
+ // Test a URI with invalid port
+ String uri = "jceks://[email protected]:invalidport/kms";
+
+ Method method = null;
+ try {
+ method = KMSClient.class.getDeclaredMethod("createProvider",
String.class);
+ method.setAccessible(true);
+ method.invoke(client, uri);
+ fail("Expected an IOException to be thrown");
+ } catch (Exception e) {
+ assertTrue(e.getCause() instanceof IOException);
+ }
+ }
+
+ @Test
+ public void testCreateProvider_directMethod() throws Exception {
+ KMSClient client = new KMSClient("jceks://http@host1:9600/kms",
"user", "pass", "principal", "keytab", "rules", "kerberos");
+
+ // Test the createProvider(URL, int, String) method directly
+ URL origUrl = new URL("http://dummy:8080/kms");
+ int port = 9600;
+ String hostsPart = "host1.example.com;host2.example.com";
+
+ Method method = KMSClient.class.getDeclaredMethod("createProvider",
URL.class, int.class, String.class);
+ method.setAccessible(true);
+
+ String[] providers = (String[]) method.invoke(client, origUrl, port,
hostsPart);
+
+ assertNotNull(providers);
+ assertEquals(2, providers.length);
+ assertEquals("http://host1.example.com:9600/kms", providers[0]);
+ assertEquals("http://host2.example.com:9600/kms", providers[1]);
+ }
+
+ @Test
+ public void testCreateProvider_singleHostDirectMethod() throws Exception {
+ KMSClient client = new KMSClient("jceks://http@host1:9600/kms",
"user", "pass", "principal", "keytab", "rules", "kerberos");
+
+ // Test the createProvider(URL, int, String) method with a single host
+ URL origUrl = new URL("http://host1.example.com:8080/kms");
+ int port = 8080;
+ String hostsPart = "host1.example.com";
+
+ Method method = KMSClient.class.getDeclaredMethod("createProvider",
URL.class, int.class, String.class);
+ method.setAccessible(true);
+
+ String[] providers = (String[]) method.invoke(client, origUrl, port,
hostsPart);
+
+ assertNotNull(providers);
+ assertEquals(1, providers.length);
+ assertEquals("http://host1.example.com:8080/kms", providers[0]);
+ }
+
+ @Test
+ public void testConstructorAndFields() {
+ KMSClient client = new KMSClient("provider", "user", "pass",
"principal", "keytab", "rules", "kerberos");
+ assertEquals("provider", client.provider);
+ assertEquals("user", client.username);
+ assertEquals("pass", client.password);
+ assertEquals("principal", client.rangerPrincipal);
+ assertEquals("keytab", client.rangerKeytab);
+ assertEquals("rules", client.nameRules);
+ assertEquals("kerberos", client.authType);
+ }
+
+ @Test
+ public void testGetKmsClient_withValidConfig() {
+ Map<String, String> configs = new HashMap<>();
+ configs.put("provider", "provider");
+ configs.put("username", "user");
+ configs.put("password", "pass");
+ configs.put("rangerprincipal", "principal");
+ configs.put("rangerkeytab", "keytab");
+ configs.put("namerules", "rules");
+ configs.put("authtype", "kerberos");
+
+ KMSClient client = KMSClient.getKmsClient("service", configs);
+ assertNotNull(client);
+ assertEquals("provider", client.provider);
+ }
+
+ @Test
+ public void testGetKmsClient_withNullConfig() {
+ Exception ex = assertThrows(HadoopException.class, () -> {
+ KMSClient.getKmsClient("service", null);
+ });
+ assertTrue(ex.getMessage().contains("ConfigMap is empty"));
+ }
+
+ @Test
+ public void testTestConnection_success() {
+ Map<String, String> configs = new HashMap<>();
+ configs.put("provider", "provider");
+ configs.put("username", "user");
+ configs.put("password", "pass");
+ configs.put("rangerprincipal", "principal");
+ configs.put("rangerkeytab", "keytab");
+ configs.put("namerules", "rules");
+ configs.put("authtype", "kerberos");
+
+ Map<String, Object> result = null;
+ try {
+ result = KMSClient.testConnection("service", configs);
+ } catch (Exception e) {
+ System.out.println("testConnection threw exception: " +
e.getMessage());
+ }
+
+ assertNotNull(result, "Response map should not be null even on
failure");
+ }
+
+ @Test
+ public void testGetKmsKey_nullClient() {
+ Exception ex = assertThrows(HadoopException.class, () -> {
+ KMSClient.getKmsKey(null, "key", null);
+ });
+ assertTrue(ex.getMessage().contains("KmsClient is null"));
+ }
+
+ @Test
+ public void testCreateProvider_withMultipleHosts() throws Exception {
+ KMSClient client = new KMSClient("provider", "user", "pass",
"principal", "keytab", "rules", "kerberos");
+ // Use a valid URI with multiple hosts
+ String uri = "http://host1;host2:16000/path";
+ Method method = KMSClient.class.getDeclaredMethod("createProvider",
String.class);
+ method.setAccessible(true);
+ try {
+ Object result = method.invoke(client, uri);
+ assertNotNull(result);
+ assertTrue(result instanceof String[]);
+ } catch (Exception e) {
+ // Acceptable if it throws due to malformed URI
+ }
+ }
+
+ @Test
+ void testUnnestUri_fullComponents() throws URISyntaxException {
+ // Given a URI with a scheme, authority (with user info), path, query,
and fragment.
+ URI uri = new
URI("kms://[email protected]:8080/path/to/resource?param=value&id=123#section");
+ Path expectedPath = new
Path("user://host.com:8080/path/to/resource?param=value&id=123#section");
+
+ // When the unnestUri method is called
+ Path actualPath = ProviderUtils.unnestUri(uri);
+
+ // Then the result should match the expected unnested path
+ assertEquals(expectedPath, actualPath, "The unnested URI should match
the expected format.");
+ }
+
+ // Helper method to access the private createProvider method via reflection
+ private String[] invokeCreateProvider(KMSClient kmsClient, String uri)
throws Exception {
+ Method method = KMSClient.class.getDeclaredMethod("createProvider",
String.class);
+ method.setAccessible(true);
+ return (String[]) method.invoke(kmsClient, uri);
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSConnectionMgrTest.java
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSConnectionMgrTest.java
new file mode 100644
index 000000000..5a5b2df69
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSConnectionMgrTest.java
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.apache.ranger.services.kms.client;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+class KMSConnectionMgrTest {
+ private static final String VALID_URL = "http://kms";
+ private static final String VALID_USER = "user";
+ private static final String VALID_PASS = "pass";
+ private static final String VALID_PRINCIPAL = "principal";
+ private static final String VALID_KEYTAB = "keytab";
+ private static final String VALID_NAMERULES = "rules";
+ private static final String VALID_AUTHTYPE = "authType";
+
+ @Test
+ void testGetKMSClient_NullKmsUrl() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(null, VALID_USER,
VALID_PASS, VALID_PRINCIPAL, VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_EmptyKmsUrl() {
+ KMSClient client = KMSConnectionMgr.getKMSClient("", VALID_USER,
VALID_PASS, VALID_PRINCIPAL, VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_EmptyRangerPrincipal_EmptyUser() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(VALID_URL, "",
VALID_PASS, "", VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNotNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_EmptyRangerPrincipal_NullUser() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(VALID_URL, null,
VALID_PASS, "", VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNotNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_EmptyRangerPrincipal_EmptyPassword() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(VALID_URL,
VALID_USER, "", "", VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNotNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_EmptyRangerPrincipal_NullPassword() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(VALID_URL,
VALID_USER, null, "", VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNotNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_EmptyRangerPrincipal_ValidUserAndPassword() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(VALID_URL,
VALID_USER, VALID_PASS, "", VALID_KEYTAB, VALID_NAMERULES, VALID_AUTHTYPE);
+ assertNotNull(client);
+ }
+
+ @Test
+ void testGetKMSClient_ValidRangerPrincipal() {
+ KMSClient client = KMSConnectionMgr.getKMSClient(VALID_URL,
VALID_USER, VALID_PASS, VALID_PRINCIPAL, VALID_KEYTAB, VALID_NAMERULES,
VALID_AUTHTYPE);
+ assertNotNull(client);
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSResourceMgrTest.java
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSResourceMgrTest.java
new file mode 100644
index 000000000..272cd1a3a
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/KMSResourceMgrTest.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.services.kms.client;
+
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class KMSResourceMgrTest {
+ @Test
+ void validateConfig_ThrowException_whenKMSClientThrows() {
+ String serviceName = "service";
+ Map<String, String> configs = new HashMap<>();
+ assertThrows(Exception.class, () ->
KMSResourceMgr.validateConfig(serviceName, configs));
+ }
+
+ @Test
+ void validateConfig_NotThrow_whenKMSClientSucceeds() {
+ String serviceName = "fakeService";
+ Map<String, String> configs = new HashMap<>();
+ configs.put("provider", "provider");
+
+ try {
+ KMSResourceMgr.validateConfig(serviceName, configs);
+ } catch (Exception e) {
+ fail("Shouldn't have thrown exception: " + e.getMessage());
+ }
+ }
+
+ @Test
+ void getKMSResources_ReturnNull_whenConfigsIsNull() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+ when(context.getUserInput()).thenReturn("input");
+ when(context.getResources()).thenReturn(null);
+ assertNull(KMSResourceMgr.getKMSResources("service", null, context));
+ }
+
+ @Test
+ void getKMSResources_ReturnNull_whenConfigsIsEmpty() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+ when(context.getUserInput()).thenReturn("input");
+ when(context.getResources()).thenReturn(null);
+ assertNull(KMSResourceMgr.getKMSResources("service",
Collections.emptyMap(), context));
+ }
+
+ @Test
+ void getKMSResources_ReturnNull_whenResourceMapIsNull() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+ when(context.getUserInput()).thenReturn("input");
+ when(context.getResources()).thenReturn(null);
+ Map<String, String> configs = validConfigs();
+ assertNull(KMSResourceMgr.getKMSResources("service", configs,
context));
+ }
+
+ @Test
+ void getKMSResources_ReturnNull_whenResourceMapIsEmpty() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+ when(context.getUserInput()).thenReturn("input");
+ when(context.getResources()).thenReturn(new HashMap<>());
+ Map<String, String> configs = validConfigs();
+ assertNull(KMSResourceMgr.getKMSResources("service", configs,
context));
+ }
+
+ @Test
+ void getKMSResources_ReturnNull_whenResourceMapDoesNotContainKey() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+ Map<String, List<String>> resourceMap = new HashMap<>();
+ resourceMap.put("otherkey", Arrays.asList("key1", "key2"));
+ when(context.getUserInput()).thenReturn("input");
+ when(context.getResources()).thenReturn(resourceMap);
+ Map<String, String> configs = validConfigs();
+ assertNull(KMSResourceMgr.getKMSResources("service", configs,
context));
+ }
+
+ /**
+ * @generated by copilot
+ */
+ @Test
+ void getKMSResources_shouldReturnList_whenResourceMapContainsKey() {
+ ResourceLookupContext context = mock(ResourceLookupContext.class);
+ Map<String, List<String>> resourceMap = new HashMap<>();
+ List<String> keys = Arrays.asList("key1", "key2");
+ resourceMap.put("keyname", keys);
+ when(context.getUserInput()).thenReturn("input");
+ when(context.getResources()).thenReturn(resourceMap);
+ Map<String, String> configs = validConfigs();
+ List<String> result = KMSResourceMgr.getKMSResources("service",
configs, context);
+ // This will only return the expected list if the real KMSClient and
KMSConnectionMgr are set up; otherwise, it may return null
+ // So we check for null or the expected keys
+ if (result != null) {
+ assertEquals(keys, result);
+ } else {
+ assertNull(result);
+ }
+ }
+
+ @Test
+ void getKMSResource_shouldReturnNull_whenKMSClientIsNull() {
+ List<String> result = KMSResourceMgr.getKMSResource(null, null, null,
null, null, null, null, null, null);
+ assertNull(result);
+ }
+
+ @Test
+ void getKMSResource_shouldReturnNull_whenUrlIsEmpty() {
+ List<String> result = KMSResourceMgr.getKMSResource("", "user",
"pass", "principal", "keytab", "rules", "authType", "kmsKey",
Arrays.asList("k1"));
+ assertNull(result);
+ }
+
+ private Map<String, String> validConfigs() {
+ Map<String, String> configs = new HashMap<>();
+ configs.put("provider", "provider");
+ configs.put("username", "user");
+ configs.put("password", "pass");
+ configs.put("rangerprincipal", "principal");
+ configs.put("rangerkeytab", "keytab");
+ configs.put("namerules", "rules");
+ configs.put("authtype", "authType");
+ return configs;
+ }
+}
diff --git
a/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/json/model/KMSSchedulerResponseTest.java
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/json/model/KMSSchedulerResponseTest.java
new file mode 100644
index 000000000..c65dc3d26
--- /dev/null
+++
b/plugin-kms/src/test/java/org/apache/ranger/services/kms/client/json/model/KMSSchedulerResponseTest.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.ranger.services.kms.client.json.model;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class KMSSchedulerResponseTest {
+ @Test
+ void testGetQueueNamesWhenSchedulerIsNull() {
+ KMSSchedulerResponse response = new KMSSchedulerResponse();
+ List<String> queueNames = response.getQueueNames();
+ assertNotNull(queueNames);
+ assertTrue(queueNames.isEmpty());
+ }
+
+ /**
+ * @generated by copilot
+ */
+ @Test
+ void testGetQueueNames_WithNestedQueues() {
+ // Build nested structure: root -> child1, child2 -> grandchild
+ KMSSchedulerResponse.KMSSchedulerInfo grandchild = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(grandchild, "queueName", "grandchild");
+ setField(grandchild, "queues", null);
+
+ KMSSchedulerResponse.KMSSchedulerInfo child1 = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(child1, "queueName", "child1");
+ setField(child1, "queues", null);
+
+ KMSSchedulerResponse.KMSSchedulerInfo child2 = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(child2, "queueName", "child2");
+ KMSSchedulerResponse.KMSQueues child2Queues = new
KMSSchedulerResponse.KMSQueues();
+ setField(child2Queues, "queue", Collections.singletonList(grandchild));
+ setField(child2, "queues", child2Queues);
+
+ KMSSchedulerResponse.KMSQueues rootQueues = new
KMSSchedulerResponse.KMSQueues();
+ setField(rootQueues, "queue", Arrays.asList(child1, child2));
+
+ KMSSchedulerResponse.KMSSchedulerInfo rootInfo = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(rootInfo, "queueName", "root");
+ setField(rootInfo, "queues", rootQueues);
+
+ KMSSchedulerResponse.KMSScheduler scheduler = new
KMSSchedulerResponse.KMSScheduler();
+ setField(scheduler, "schedulerInfo", rootInfo);
+
+ KMSSchedulerResponse response = new KMSSchedulerResponse();
+ setField(response, "scheduler", scheduler);
+
+ List<String> queueNames = response.getQueueNames();
+ assertEquals(Arrays.asList("root", "root.child1", "root.child2",
"root.child2.grandchild"), queueNames);
+ }
+
+ @Test
+ void testSchedulerInfo_CollectQueueNames_NoChildren() {
+ KMSSchedulerResponse.KMSSchedulerInfo info = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(info, "queueName", "queueA");
+ setField(info, "queues", null);
+ List<String> names = new ArrayList<>();
+ info.collectQueueNames(names, null);
+ assertEquals(Collections.singletonList("queueA"), names);
+ }
+
+ @Test
+ void testKMS_QueuesCollectQueueNames() {
+ KMSSchedulerResponse.KMSSchedulerInfo child = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(child, "queueName", "child");
+ setField(child, "queues", null);
+ KMSSchedulerResponse.KMSQueues queues = new
KMSSchedulerResponse.KMSQueues();
+ setField(queues, "queue", Collections.singletonList(child));
+ List<String> names = new ArrayList<>();
+ queues.collectQueueNames(names, "parent");
+ assertEquals(Collections.singletonList("parent.child"), names);
+ }
+
+ @Test
+ void testGetScheduler() {
+ KMSSchedulerResponse.KMSScheduler scheduler = new
KMSSchedulerResponse.KMSScheduler();
+ KMSSchedulerResponse response = new KMSSchedulerResponse();
+ setField(response, "scheduler", scheduler);
+ assertSame(scheduler, response.getScheduler());
+ }
+
+ @Test
+ void testGetSchedulerInfo_ReturnsNullByDefault() {
+ KMSSchedulerResponse.KMSScheduler scheduler = new
KMSSchedulerResponse.KMSScheduler();
+ assertNull(scheduler.getSchedulerInfo());
+ }
+
+ @Test
+ void testGetSchedulerInfo() {
+ KMSSchedulerResponse.KMSSchedulerInfo info = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ KMSSchedulerResponse.KMSScheduler scheduler = new
KMSSchedulerResponse.KMSScheduler();
+ setField(scheduler, "schedulerInfo", info);
+ assertSame(info, scheduler.getSchedulerInfo());
+ }
+
+ @Test
+ void testGetQueueName() {
+ KMSSchedulerResponse.KMSSchedulerInfo info = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(info, "queueName", "testQueue");
+ assertEquals("testQueue", info.getQueueName());
+ }
+
+ @Test
+ void testGetQueues() {
+ KMSSchedulerResponse.KMSQueues queues = new
KMSSchedulerResponse.KMSQueues();
+ KMSSchedulerResponse.KMSSchedulerInfo info = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(info, "queues", queues);
+ assertSame(queues, info.getQueues());
+ }
+
+ @Test
+ void testGetQueue() {
+ KMSSchedulerResponse.KMSSchedulerInfo info = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ List<KMSSchedulerResponse.KMSSchedulerInfo> queueList =
Collections.singletonList(info);
+ KMSSchedulerResponse.KMSQueues queues = new
KMSSchedulerResponse.KMSQueues();
+ setField(queues, "queue", queueList);
+ assertSame(queueList, queues.getQueue());
+ }
+
+ @Test
+ void testScheduler_CollectQueueNames_WithNullSchedulerInfo() {
+ KMSSchedulerResponse.KMSScheduler scheduler = new
KMSSchedulerResponse.KMSScheduler();
+ setField(scheduler, "schedulerInfo", null);
+ List<String> names = new ArrayList<>();
+ scheduler.collectQueueNames(names);
+ assertTrue(names.isEmpty());
+ }
+
+ @Test
+ void testSchedulerInfo_CollectQueueNames_WithNullQueueName() {
+ KMSSchedulerResponse.KMSSchedulerInfo info = new
KMSSchedulerResponse.KMSSchedulerInfo();
+ setField(info, "queueName", null);
+ setField(info, "queues", null);
+ List<String> names = new ArrayList<>();
+ info.collectQueueNames(names, null);
+ assertTrue(names.isEmpty());
+ }
+
+ @Test
+ void testKMS_QueuesCollectQueueNames_WithNullQueue() {
+ KMSSchedulerResponse.KMSQueues queues = new
KMSSchedulerResponse.KMSQueues();
+ setField(queues, "queue", null);
+ List<String> names = new ArrayList<>();
+ queues.collectQueueNames(names, "parent");
+ assertTrue(names.isEmpty());
+ }
+
+ @Test
+ void testKMS_QueuesCollectQueueNames_WithEmptyQueue() {
+ KMSSchedulerResponse.KMSQueues queues = new
KMSSchedulerResponse.KMSQueues();
+ setField(queues, "queue", Collections.emptyList());
+ List<String> names = new ArrayList<>();
+ queues.collectQueueNames(names, "parent");
+ assertTrue(names.isEmpty());
+ }
+
+ private static void setField(Object target, String fieldName, Object
value) {
+ try {
+ java.lang.reflect.Field field =
target.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ field.set(target, value);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}