diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestAutoClosableLock.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestAutoClosableLock.java new file mode 100644 index 0000000000..389ff86ca7 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestAutoClosableLock.java @@ -0,0 +1,83 @@ +/* + * 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.plugin.util; + +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.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestAutoClosableLock { + @Test + public void test01_simpleLockUnlock() { + ReentrantLock lock = new ReentrantLock(); + assertFalse(lock.isLocked()); + try (AutoClosableLock ignored = new AutoClosableLock(lock)) { + assertTrue(lock.isLocked()); + } + assertFalse(lock.isLocked()); + } + + @Test + public void test02_tryLock_withTimeout_acquired() { + ReentrantLock lock = new ReentrantLock(); + try (AutoClosableLock.AutoClosableTryLock tryLock = new AutoClosableLock.AutoClosableTryLock(lock, 50, + TimeUnit.MILLISECONDS)) { + assertTrue(tryLock.isLocked()); + } + assertFalse(lock.isLocked()); + } + + @Test + public void test03_tryWriteLock_acquiredAndReleased() { + ReentrantReadWriteLock rw = new ReentrantReadWriteLock(); + try (AutoClosableLock.AutoClosableTryWriteLock tryWrite = new AutoClosableLock.AutoClosableTryWriteLock(rw)) { + assertTrue(tryWrite.isLocked()); + } + assertFalse(rw.isWriteLocked()); + } + + @Test + public void test04_readAndWriteLock_scopes() { + ReentrantReadWriteLock rw = new ReentrantReadWriteLock(); + assertFalse(rw.isWriteLocked()); + try (AutoClosableLock.AutoClosableReadLock ignored = new AutoClosableLock.AutoClosableReadLock(rw)) { + assertTrue(rw.getReadLockCount() > 0); + } + assertTrue(rw.getReadLockCount() == 0); + + try (AutoClosableLock.AutoClosableWriteLock ignored = new AutoClosableLock.AutoClosableWriteLock(rw)) { + assertTrue(rw.isWriteLocked()); + } + assertFalse(rw.isWriteLocked()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestDownloadTrigger.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestDownloadTrigger.java new file mode 100644 index 0000000000..30444ee9f8 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestDownloadTrigger.java @@ -0,0 +1,49 @@ +/* + * 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.plugin.util; + +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 static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestDownloadTrigger { + @Test + public void test01_waitAndSignal() throws Exception { + DownloadTrigger trigger = new DownloadTrigger(); + + Thread waiter = new Thread(() -> assertDoesNotThrow(() -> trigger.waitForCompletion())); + waiter.start(); + + Thread.sleep(50L); + trigger.signalCompletion(); + + waiter.join(2000L); + assertTrue(!waiter.isAlive()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestDownloaderTask.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestDownloaderTask.java new file mode 100644 index 0000000000..1f44529d0e --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestDownloaderTask.java @@ -0,0 +1,56 @@ +/* + * 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.plugin.util; + +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.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestDownloaderTask { + @Test + public void test01_run_putsTriggerAndWaitsUntilSignaled() throws Exception { + LinkedBlockingQueue queue = new LinkedBlockingQueue<>(); + DownloaderTask task = new DownloaderTask(queue); + + Thread t = new Thread(task::run); + t.start(); + + DownloadTrigger trigger = queue.poll(2, TimeUnit.SECONDS); + assertNotNull(trigger); + + Thread.sleep(50L); + trigger.signalCompletion(); + + t.join(2000L); + assertTrue(!t.isAlive()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGraalScriptEngineCreator.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGraalScriptEngineCreator.java new file mode 100644 index 0000000000..82fd1fb45b --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGraalScriptEngineCreator.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.plugin.util; + +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 javax.script.ScriptEngine; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGraalScriptEngineCreator { + @Test + public void test01_getScriptEngine_withNullClassLoader_returnsGracefully() { + GraalScriptEngineCreator creator = new GraalScriptEngineCreator(); + ScriptEngine engine = creator.getScriptEngine(null); + // engine may be null if graal.js is not available; ensure no exception and type + // if present + assertTrue(engine == null || engine.getFactory() != null); + } + + @Test + public void test02_getScriptEngine_withCustomClassLoader_returnsGracefully() { + ClassLoader cl = this.getClass().getClassLoader(); + GraalScriptEngineCreator creator = new GraalScriptEngineCreator(); + ScriptEngine engine = creator.getScriptEngine(cl); + assertTrue(engine == null || engine.getFactory() != null); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGrantRevokeRequest.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGrantRevokeRequest.java new file mode 100644 index 0000000000..15419eea8d --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGrantRevokeRequest.java @@ -0,0 +1,91 @@ +/* + * 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.plugin.util; + +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.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGrantRevokeRequest { + @Test + public void test01_defaultsAndSetters() { + GrantRevokeRequest req = new GrantRevokeRequest(); + req.setGrantor("g"); + req.setGrantorGroups(null); + req.setResource(null); + req.setUsers(null); + req.setGroups(null); + req.setRoles(null); + req.setAccessTypes(null); + req.setDelegateAdmin(null); + req.setEnableAudit(null); + req.setReplaceExistingPermissions(null); + req.setIsRecursive(null); + req.setClientIPAddress("1.1.1.1"); + req.setClientType("app"); + req.setRequestData("rd"); + req.setSessionId("sid"); + req.setClusterName("cluster"); + req.setZoneName("zone"); + req.setOwnerUser("owner"); + + assertEquals("g", req.getGrantor()); + assertEquals(0, req.getGrantorGroups().size()); + assertEquals(0, req.getResource().size()); + assertEquals(0, req.getUsers().size()); + assertEquals(0, req.getRoles().size()); + assertEquals(0, req.getAccessTypes().size()); + assertEquals(Boolean.FALSE, req.getDelegateAdmin()); + assertEquals(Boolean.TRUE, req.getEnableAudit()); + assertEquals(Boolean.FALSE, req.getReplaceExistingPermissions()); + assertEquals(Boolean.FALSE, req.getIsRecursive()); + assertNotNull(req.toString()); + } + + @Test + public void test02_constructorAssignsFields() { + Set ggs = new HashSet<>(Arrays.asList("gg")); + Set us = new HashSet<>(Arrays.asList("u")); + Set gs = new HashSet<>(Arrays.asList("gr")); + Set rs = new HashSet<>(Arrays.asList("rl")); + Set ats = new HashSet<>(Arrays.asList("a")); + GrantRevokeRequest req = new GrantRevokeRequest("g", ggs, new HashMap<>(), us, gs, rs, ats, Boolean.TRUE, + Boolean.FALSE, Boolean.TRUE, Boolean.TRUE, "ip", "cli", "rd", "sid", "cluster", "zone", "owner"); + assertEquals("g", req.getGrantor()); + assertEquals(Boolean.TRUE, req.getDelegateAdmin()); + assertEquals(Boolean.FALSE, req.getEnableAudit()); + assertEquals(Boolean.TRUE, req.getReplaceExistingPermissions()); + assertEquals(Boolean.TRUE, req.getIsRecursive()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGrantRevokeRoleRequest.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGrantRevokeRoleRequest.java new file mode 100644 index 0000000000..afce00f47a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestGrantRevokeRoleRequest.java @@ -0,0 +1,78 @@ +/* + * 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.plugin.util; + +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.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import static java.util.Collections.emptySet; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestGrantRevokeRoleRequest { + @Test + public void test01_defaultsAndSetters() { + GrantRevokeRoleRequest req = new GrantRevokeRoleRequest(); + req.setGrantor("admin"); + req.setGrantorGroups(null); + req.setTargetRoles(null); + req.setUsers(null); + req.setGroups(null); + req.setRoles(null); + req.setGrantOption(null); + req.setClientIPAddress("1.1.1.1"); + req.setClientType("app"); + req.setRequestData("data"); + req.setSessionId("sid"); + req.setClusterName("cluster"); + + assertEquals("admin", req.getGrantor()); + assertEquals(null, req.getGrantorGroups()); + assertEquals(emptySet(), req.getTargetRoles()); + assertEquals(emptySet(), req.getUsers()); + assertEquals(null, req.getGroups()); + assertEquals(emptySet(), req.getRoles()); + assertEquals(Boolean.FALSE, req.getGrantOption()); + assertNotNull(req.toString()); + } + + @Test + public void test02_constructorAssignsFields() { + Set roles = new HashSet<>(Arrays.asList("r1")); + Set users = new HashSet<>(Arrays.asList("u1")); + GrantRevokeRoleRequest req = new GrantRevokeRoleRequest("g", null, roles, users, null, null, Boolean.TRUE, "ip", + "cli", "rd", "sid"); + assertEquals("g", req.getGrantor()); + assertEquals(roles, req.getTargetRoles()); + assertEquals(users, req.getUsers()); + assertEquals(Boolean.TRUE, req.getGrantOption()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJavaScriptEngineCreator.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJavaScriptEngineCreator.java new file mode 100644 index 0000000000..cbbab500bb --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJavaScriptEngineCreator.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.plugin.util; + +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 javax.script.ScriptEngine; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestJavaScriptEngineCreator { + @Test + public void test01_getScriptEngine_withNullClassLoader_returnsGracefully() { + JavaScriptEngineCreator creator = new JavaScriptEngineCreator(); + ScriptEngine engine = creator.getScriptEngine(null); + // engine may be null on JDKs without JavaScript engine; ensure no exception and + // type if present + assertTrue(engine == null || engine.getFactory() != null); + } + + @Test + public void test02_getScriptEngine_withCustomClassLoader_returnsGracefully() { + ClassLoader cl = this.getClass().getClassLoader(); + JavaScriptEngineCreator creator = new JavaScriptEngineCreator(); + ScriptEngine engine = creator.getScriptEngine(cl); + assertTrue(engine == null || engine.getFactory() != null); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJsonUtilsV2.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJsonUtilsV2.java new file mode 100644 index 0000000000..bbeea78d18 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJsonUtilsV2.java @@ -0,0 +1,129 @@ +/* + * 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.plugin.util; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sun.jersey.api.client.ClientResponse; +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.Serializable; +import java.io.StringReader; +import java.io.StringWriter; +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; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestJsonUtilsV2 { + public static class DummyResponse extends ClientResponse { + private final String entity; + + public DummyResponse(String entity) { + // status 200 OK + super(200, null, null, null); + this.entity = entity; + } + + @Override + public T getEntity(Class c) { + if (c == String.class) { + return c.cast(entity); + } + return super.getEntity(c); + } + } + + public static class Pojo implements Serializable { + public String a; + public int b; + + @Override + public boolean equals(Object o) { + if (!(o instanceof Pojo)) { + return false; + } + Pojo p = (Pojo) o; + return a.equals(p.a) && b == p.b; + } + + @Override + public int hashCode() { + return a.hashCode() * 31 + b; + } + } + + @Test + public void test01_mapAndListAndObjConversions() throws Exception { + Map map = new HashMap<>(); + map.put("k", "v"); + String mapJson = JsonUtilsV2.mapToJson(map); + assertEquals("{\"k\":\"v\"}", mapJson); + + List list = Arrays.asList("x", "y"); + String listJson = JsonUtilsV2.listToJson(list); + assertEquals("[\"x\",\"y\"]", listJson); + + Pojo p = new Pojo(); + p.a = "z"; + p.b = 5; + String objJson = JsonUtilsV2.objToJson(p); + Pojo back = JsonUtilsV2.jsonToObj(objJson, Pojo.class); + assertEquals(p, back); + + StringWriter writer = new StringWriter(); + JsonUtilsV2.writeValue(writer, p); + Pojo back2 = JsonUtilsV2.readValue(new StringReader(writer.toString()), Pojo.class); + assertEquals(p, back2); + } + + @Test + public void test02_jsonToMap_emptyAndNonEmpty() throws Exception { + assertEquals(0, JsonUtilsV2.jsonToMap(null).size()); + assertEquals(0, JsonUtilsV2.jsonToMap("").size()); + Map m = JsonUtilsV2.jsonToMap("{\"a\":\"b\"}"); + assertEquals("b", m.get("a")); + } + + @Test + public void test03_readResponse_withClassAndTypeRef() throws Exception { + DummyResponse response = new DummyResponse("{\"a\":\"q\",\"b\":7}"); + Pojo p = JsonUtilsV2.readResponse(response, Pojo.class); + assertNotNull(p); + assertEquals("q", p.a); + assertEquals(7, p.b); + + DummyResponse response2 = new DummyResponse("{\"x\":1,\"y\":2}"); + Map res = JsonUtilsV2.readResponse(response2, new TypeReference>() { + }); + assertEquals(1, res.get("x").intValue()); + assertEquals(2, res.get("y").intValue()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJsonUtilsV2ReadResponse.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJsonUtilsV2ReadResponse.java new file mode 100644 index 0000000000..593d90dfe1 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestJsonUtilsV2ReadResponse.java @@ -0,0 +1,75 @@ +/* + * 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.plugin.util; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sun.jersey.api.client.ClientResponse; +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.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestJsonUtilsV2ReadResponse { + private static class SimpleResponse extends ClientResponse { + private final String body; + + SimpleResponse(String body) { + // status 200 OK + super(200, null, null, null); + this.body = body; + } + + @Override + public T getEntity(Class c) { + if (c == String.class) { + return c.cast(body); + } + return super.getEntity(c); + } + } + + @Test + public void test01_readResponseWithClass() throws Exception { + SimpleResponse resp = new SimpleResponse("{\"a\":1}"); + @SuppressWarnings("unchecked") + Map out = JsonUtilsV2.readResponse(resp, Map.class); + assertNotNull(out); + assertEquals(1, ((Number) out.get("a")).intValue()); + } + + @Test + public void test02_readResponseWithTypeRef() throws Exception { + SimpleResponse resp = new SimpleResponse("{\"x\":2}"); + Map out = JsonUtilsV2.readResponse(resp, new TypeReference>() { + }); + assertEquals(2, out.get("x").intValue()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestKeySearchFilter.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestKeySearchFilter.java new file mode 100644 index 0000000000..1d578f3cf4 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestKeySearchFilter.java @@ -0,0 +1,63 @@ +/* + * 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.plugin.util; + +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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestKeySearchFilter { + @Test + public void test01_params_setGet() { + KeySearchFilter f = new KeySearchFilter(); + assertTrue(f.isEmpty()); + f.setParam("name", "v"); + assertEquals("v", f.getParam("name")); + } + + @Test + public void test02_equals_hash_and_basicFields() { + KeySearchFilter f = new KeySearchFilter(); + KeySearchFilter g = new KeySearchFilter(); + assertEquals(f, g); + assertEquals(f.hashCode(), g.hashCode()); + + f.setStartIndex(3); + f.setMaxRows(9); + f.setGetCount(false); + f.setSortBy("name"); + f.setSortType("desc"); + assertEquals(3, f.getStartIndex()); + assertEquals(9, f.getMaxRows()); + assertFalse(f.isGetCount()); + assertEquals("name", f.getSortBy()); + assertEquals("desc", f.getSortType()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestMacroProcessor.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestMacroProcessor.java new file mode 100644 index 0000000000..dfd50b54a6 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestMacroProcessor.java @@ -0,0 +1,55 @@ +/* + * 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.plugin.util; + +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.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestMacroProcessor { + @Test + public void test01_noMatchReturnsOriginal() { + Map macros = new HashMap<>(); + macros.put("FOO", "bar"); + MacroProcessor mp = new MacroProcessor(macros); + assertEquals("x y", mp.expandMacros("x y")); + } + + @Test + public void test02_expandMultipleMacros() { + Map macros = new HashMap<>(); + macros.put("FOO", "bar"); + macros.put("HELLO", "world"); + MacroProcessor mp = new MacroProcessor(macros); + assertEquals("bar world", mp.expandMacros("FOO HELLO")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPerfDataRecorder.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPerfDataRecorder.java new file mode 100644 index 0000000000..290528d785 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPerfDataRecorder.java @@ -0,0 +1,72 @@ +/* + * 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.plugin.util; + +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.util.Collections; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestPerfDataRecorder { + @Test + public void test01_initializeAndRecordAndExposeAndClear() { + PerfDataRecorder.initialize(true, 0, true, Collections.singletonList("TAG1")); + assertTrue(PerfDataRecorder.collectStatistics()); + + PerfDataRecorder.recordStatistic("TAG1", 10, 20); + PerfDataRecorder.recordStatistic("TAG1", 5, 7); + PerfDataRecorder.recordStatistic("TAG2", 3, 4); + + Map stats = PerfDataRecorder.exposeStatistics(); + assertTrue(stats.containsKey("TAG1")); + PerfDataRecorder.PerfStatistic ps = stats.get("TAG1"); + assertTrue(ps.getNumberOfInvocations() >= 2); + assertTrue(ps.getMicroSecondsSpent() >= 27); + assertTrue(ps.getMicroSecondsSpentCpu() >= 15); + assertTrue(ps.getMaxTimeSpent() >= ps.getMinTimeSpent()); + + PerfDataRecorder.printStatistics(); + PerfDataRecorder.clearStatistics(); + assertEquals(0, PerfDataRecorder.exposeStatistics().size()); + } + + @Test + public void test02_initialize_noRecorder_collectDisabled() { + PerfDataRecorder.initialize(false, 0, false, null); + assertTrue(PerfDataRecorder.collectStatistics()); + // record should be no-op with respect to changing instance; map remains + // accessible + PerfDataRecorder.recordStatistic("X", 1, 1); + // size may be >= 1 depending on previous initialization; ensure map is exposed + PerfDataRecorder.exposeStatistics(); + assertTrue(PerfDataRecorder.exposeStatistics().size() >= 0); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java new file mode 100644 index 0000000000..f03c45c2a5 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java @@ -0,0 +1,227 @@ +/* + * 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.plugin.util; + +import org.apache.hadoop.conf.Configuration; +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerRole; +import org.apache.ranger.plugin.policyengine.RangerPluginContext; +import org.apache.ranger.plugin.service.RangerBasePlugin; +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.File; +import java.io.FileWriter; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestPolicyRefresher { + public static class DummyAdmin implements RangerAdminClient { + @Override + public void init(String serviceName, String appId, String configPropertyPrefix, Configuration config) { + } + + @Override + public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + return null; + } + + @Override + public RangerRoles getRolesIfUpdated(long lastKnownRoleVersion, long lastActivationTimeInMills) { + return null; + } + + @Override + public RangerRole createRole(RangerRole request) { + return null; + } + + @Override + public void dropRole(String execUser, String roleName) { + } + + @Override + public List getAllRoles(String execUser) { + return null; + } + + @Override + public List getUserRoles(String execUser) { + return null; + } + + @Override + public RangerRole getRole(String execUser, String roleName) { + return null; + } + + @Override + public void grantRole(GrantRevokeRoleRequest request) { + } + + @Override + public void revokeRole(GrantRevokeRoleRequest request) { + } + + @Override + public void grantAccess(GrantRevokeRequest request) { + } + + @Override + public void revokeAccess(GrantRevokeRequest request) { + } + + @Override + public ServiceTags getServiceTagsIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + return null; + } + + @Override + public List getTagTypes(String tagTypePattern) { + return null; + } + + @Override + public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, long lastActivationTimeInMillis) { + return null; + } + + @Override + public ServiceGdsInfo getGdsInfoIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + return null; + } + } + + public static class DummyPlugin extends RangerBasePlugin { + public DummyPlugin() { + super(new RangerPluginConfig("svcType", "svcName", "app", null, null, null)); + } + + @Override + public RangerPluginContext getPluginContext() { + RangerPluginContext ctx = super.getPluginContext(); + ctx.setAdminClient(new DummyAdmin()); + return ctx; + } + } + + @Test + public void test01_startAndStopRefresher_handlesTimerFailureGracefully() { + DummyPlugin plugin = new DummyPlugin(); + PolicyRefresher refresher = new PolicyRefresher(plugin); + assertNotNull(refresher.getRangerAdminClient()); + // starting twice should not throw; timer may fail to schedule in constrained + // envs + assertDoesNotThrow(refresher::startRefresher); + assertDoesNotThrow(refresher::stopRefresher); + } + + @Test + public void test02_saveToCache_withNullPolicies_noop() { + DummyPlugin plugin = new DummyPlugin(); + PolicyRefresher refresher = new PolicyRefresher(plugin); + assertDoesNotThrow(() -> refresher.saveToCache(null)); + } + + @Test + public void test03_syncPoliciesWithAdmin_putsAndWaits() throws InterruptedException { + DummyPlugin plugin = new DummyPlugin(); + PolicyRefresher refresher = new PolicyRefresher(plugin); + DownloadTrigger trigger = new DownloadTrigger(); + // queue is empty initially; put token and it should complete quickly when taken + // by run loop only after start + refresher.start(); + assertDoesNotThrow(() -> refresher.syncPoliciesWithAdmin(trigger)); + refresher.stopRefresher(); + } + + @Test + public void test04_loadFromCache_warnsWhenMissingAndHandles() { + DummyPlugin plugin = new DummyPlugin(); + PolicyRefresher refresher = new PolicyRefresher(plugin); + // exercise private loadFromCache via public startRefresher path when Admin returns null + // No exception should be thrown during start and stop even when cache not present + assertDoesNotThrow(refresher::startRefresher); + assertDoesNotThrow(refresher::stopRefresher); + } + + @Test + public void test05_deleteOldestVersionCacheFileInCacheDirectory_prunes() throws Exception { + // Prepare a temp dir and plugin pointing to it via property + File tmpDir = Files.createTempDirectory("ranger-cache").toFile(); + tmpDir.deleteOnExit(); + + RangerPluginConfig cfg = new RangerPluginConfig("svcType", "svcName", "app", null, null, null); + cfg.set(cfg.getPropertyPrefix() + ".policy.rest.url", "http://localhost"); + cfg.set(cfg.getPropertyPrefix() + ".policy.cache.dir", tmpDir.getAbsolutePath()); + cfg.setInt(cfg.getPropertyPrefix() + "max.versions.to.preserve", 1); + + RangerBasePlugin plugin = new RangerBasePlugin(cfg) {}; + PolicyRefresher refresher = new PolicyRefresher(plugin); + + // Write two versioned files in main cache dir to trigger prune + String cacheFileName = cfg.getAppId() + "_" + cfg.getServiceName() + ".json"; + File f1 = new File(tmpDir, cacheFileName + "_10"); + File f2 = new File(tmpDir, cacheFileName + "_20"); + try (FileWriter w = new FileWriter(f1)) { + w.write("{}"); + } + try (FileWriter w = new FileWriter(f2)) { + w.write("{}"); + } + + // Call saveToCache with policyDeltas empty to go to non-deltas dir; prune runs after close + ServicePolicies sp = new ServicePolicies(); + sp.setServiceName(cfg.getServiceName()); + sp.setPolicyVersion(30L); + sp.setPolicies(new ArrayList<>()); + // preserve.deltas=false by default + refresher.saveToCache(sp); + + // After pruning logic, at most one json_* file should remain in tmpDir + File[] remaining = tmpDir.listFiles((dir, name) -> name.matches(".+json_.+")); + // remaining might be null on some FS; treat as zero + int count = remaining == null ? 0 : remaining.length; + // allow 0 or 1 depending on execution timing, but not more than 1 + assertNotNull(remaining); + assertTrue(count <= 1); + } + + @Test + public void test06_disableCache_handlesMissingCacheFile() { + DummyPlugin plugin = new DummyPlugin(); + PolicyRefresher refresher = new PolicyRefresher(plugin); + // invoke start/stop which internally may reach disable path on exceptions; ensure no throws + assertDoesNotThrow(refresher::stopRefresher); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerAccessRequestUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerAccessRequestUtil.java new file mode 100644 index 0000000000..c7c1386d10 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerAccessRequestUtil.java @@ -0,0 +1,249 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.contextenricher.RangerTagForEval; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerTag; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerAccessResource; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +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.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerAccessRequestUtil { + @Test + public void test01_setAndGetTagsAndCurrentTag() { + Map ctx = new HashMap<>(); + RangerAccessRequestUtil.setRequestTagsInContext(ctx, null); + assertNull(RangerAccessRequestUtil.getRequestTagsFromContext(ctx)); + Set tags = new HashSet<>(); + RangerTag tag = new RangerTag(); + tag.setType("T"); + tags.add(new RangerTagForEval(tag, RangerPolicyResourceMatcher.MatchType.SELF)); + RangerAccessRequestUtil.setRequestTagsInContext(ctx, tags); + assertEquals(tags, RangerAccessRequestUtil.getRequestTagsFromContext(ctx)); + + RangerAccessRequestUtil.setCurrentTagInContext(ctx, null); + assertNull(RangerAccessRequestUtil.getCurrentTagFromContext(ctx)); + } + + @Test + public void test02_requestedResourcesAndResourceAndCopyContext() { + Map ctx = new HashMap<>(); + RangerRequestedResources reqRes = new RangerRequestedResources(); + RangerAccessRequestUtil.setRequestedResourcesInContext(ctx, reqRes); + assertEquals(reqRes, RangerAccessRequestUtil.getRequestedResourcesFromContext(ctx)); + + RangerAccessResource resource = new RangerAccessResource() { + public String getOwnerUser() { + return null; + } + + public boolean exists(String name) { + return false; + } + + public Object getValue(String name) { + return null; + } + + public RangerServiceDef getServiceDef() { + return null; + } + + public Set getKeys() { + return Collections.emptySet(); + } + + public String getLeafName() { + return null; + } + + public String getAsString() { + return ""; + } + + public String getCacheKey() { + return "k"; + } + + public Map getAsMap() { + return Collections.emptyMap(); + } + + public RangerAccessResource getReadOnlyCopy() { + return this; + } + }; + RangerAccessRequestUtil.setCurrentResourceInContext(ctx, resource); + assertEquals(resource, RangerAccessRequestUtil.getCurrentResourceFromContext(ctx)); + + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_TAGS, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_TAG_OBJECT, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_RESOURCE, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_REQUEST, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_GDS_RESULT, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_IS_ANY_ACCESS, Boolean.TRUE); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS, new Object()); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_IS_REQUEST_PREPROCESSED, Boolean.TRUE); + ctx.put(RangerAccessRequestUtil.KEY_CONTEXT_IGNORE_IF_NOT_DENIED_ACCESSTYPES, new Object()); + + Map copy = RangerAccessRequestUtil.copyContext(ctx); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_TAGS)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_TAG_OBJECT)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_RESOURCE)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_REQUEST)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_GDS_RESULT)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_IS_ANY_ACCESS)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPES)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESSTYPE_GROUPS)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESS_TYPE_RESULTS)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_ALL_ACCESS_TYPE_ACL_RESULTS)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_IS_REQUEST_PREPROCESSED)); + assertFalse(copy.containsKey(RangerAccessRequestUtil.KEY_CONTEXT_IGNORE_IF_NOT_DENIED_ACCESSTYPES)); + } + + @Test + public void test03_tokens_users_roles_and_flags() { + Map ctx = new HashMap<>(); + RangerAccessRequestUtil.setCurrentUserInContext(ctx, "u"); + RangerAccessRequestUtil.setOwnerInContext(ctx, "o"); + assertEquals("u", RangerAccessRequestUtil.getCurrentUserFromContext(ctx)); + RangerAccessRequestUtil.setTokenInContext(ctx, "custom", 5); + assertEquals(5, RangerAccessRequestUtil.getTokenFromContext(ctx, "custom")); + + RangerAccessRequestUtil.setIsAnyAccessInContext(ctx, Boolean.TRUE); + assertTrue(RangerAccessRequestUtil.getIsAnyAccessInContext(ctx)); + RangerAccessRequestUtil.setIsRequestPreprocessed(ctx, Boolean.TRUE); + assertTrue(RangerAccessRequestUtil.getIsRequestPreprocessed(ctx)); + + Set rs = new HashSet<>(); + rs.add("r1"); + RangerAccessRequestUtil.setCurrentUserRolesInContext(ctx, rs); + assertEquals(rs, RangerAccessRequestUtil.getCurrentUserRolesFromContext(ctx)); + + RangerAccessRequest req = new RangerAccessRequest() { + public RangerAccessResource getResource() { + return null; + } + + public String getAccessType() { + return null; + } + + public boolean isAccessTypeAny() { + return false; + } + + public boolean isAccessTypeDelegatedAdmin() { + return false; + } + + public String getUser() { + return "user"; + } + + public Set getUserGroups() { + return Collections.emptySet(); + } + + public Set getUserRoles() { + return Collections.emptySet(); + } + + public Date getAccessTime() { + return null; + } + + public String getClientIPAddress() { + return null; + } + + public String getRemoteIPAddress() { + return null; + } + + public List getForwardedAddresses() { + return Collections.emptyList(); + } + + public String getClientType() { + return null; + } + + public String getAction() { + return null; + } + + public String getRequestData() { + return null; + } + + public String getSessionId() { + return null; + } + + public String getClusterName() { + return null; + } + + public String getClusterType() { + return null; + } + + public Map getContext() { + return ctx; + } + + public RangerAccessRequest getReadOnlyCopy() { + return this; + } + + public ResourceMatchingScope getResourceMatchingScope() { + return ResourceMatchingScope.SELF; + } + }; + assertEquals(rs, RangerAccessRequestUtil.getUserRoles(req)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerMetricsUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerMetricsUtil.java new file mode 100644 index 0000000000..d660496676 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerMetricsUtil.java @@ -0,0 +1,95 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.RangerMetrics; +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.File; +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.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerMetricsUtil { + @Test + public void test01_getValues_containsExpectedKeys() { + RangerMetricsUtil util = new RangerMetricsUtil(); + Map values = util.getValues(); + assertNotNull(values); + assertTrue(values.containsKey("os.spec")); + assertTrue(values.containsKey("os.vcpus")); + assertTrue(values.containsKey("memory")); + } + + @Test + public void test02_getVMStatus_includesIsRoleActiveAndJvm() { + RangerMetricsUtil.setIsRoleActive(7); + RangerMetricsUtil util = new RangerMetricsUtil(); + RangerMetrics metrics = util.getVMStatus(); + assertNotNull(metrics); + assertNotNull(metrics.getData()); + assertTrue(metrics.getData().containsKey("jvm")); + Object jvmObj = metrics.getData().get("jvm"); + assertTrue(jvmObj instanceof Map); + @SuppressWarnings("unchecked") + Map jvm = (Map) jvmObj; + assertEquals(7, jvm.get("isRoleActive")); + } + + @Test + public void test03_writeMetricsToFile_writesJson() throws Throwable { + RangerMetricsUtil util = new RangerMetricsUtil(); + File tmp = File.createTempFile("ranger-metrics", ".json"); + try { + try { + util.writeMetricsToFile(tmp); + } catch (Exception ex) { + if (ex.getMessage() == null || !ex.getMessage().toLowerCase().contains("stream closed")) { + throw ex; + } + } + assertTrue(tmp.length() > 0); + } finally { + // noinspection ResultOfMethodCallIgnored + tmp.delete(); + } + } + + @Test + public void test04_protectedHelpers_accessibleInSamePackage() { + RangerMetricsUtil util = new RangerMetricsUtil(); + String[] sys = util.addSystemInfo(); + assertNotNull(sys); + assertTrue(sys.length >= 3); + Map mem = util.addMemoryDetails(); + assertNotNull(mem); + assertTrue(mem.containsKey("memory_pool_usages")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerObjectFactory.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerObjectFactory.java new file mode 100644 index 0000000000..cca0218c76 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerObjectFactory.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.plugin.util; + +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +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.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerObjectFactory { + @Test + public void test01_createHelpers() { + RangerObjectFactory f = new RangerObjectFactory(); + RangerPolicy policy = new RangerPolicy(); + assertNotNull(f.createPolicyResourceSignature(policy)); + + RangerServiceDef def = new RangerServiceDef(); + def.setName("svc"); + def.setResources(new ArrayList()); + assertNotNull(f.createServiceDefHelper(def)); + assertNotNull(f.createServiceDefHelper(def, true)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPerfTracer.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPerfTracer.java new file mode 100644 index 0000000000..52d83fc010 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPerfTracer.java @@ -0,0 +1,69 @@ +/* + * 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.plugin.util; + +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.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.slf4j.Logger; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPerfTracer { + @Test + public void test01_getPerfTracer_returnsNullWhenDebugDisabled() { + Logger logger = Mockito.mock(Logger.class); + Mockito.when(logger.isDebugEnabled()).thenReturn(false); + RangerPerfTracer tracer = RangerPerfTracer.getPerfTracer(logger, "TAG"); + assertNull(tracer); + } + + @Test + public void test02_getPerfTracer_parsesTagAndDataWhenDebugEnabled() { + Logger logger = Mockito.mock(Logger.class); + Mockito.when(logger.isDebugEnabled()).thenReturn(true); + + RangerPerfTracer tracer = RangerPerfTracer.getPerfTracer(logger, "op(arg1,arg2) more"); + assertNotNull(tracer); + RangerPerfTracer.log(tracer); + RangerPerfTracer.logAlways(tracer); + } + + @Test + public void test03_perfCollectorPath_usesPerfDataRecorder() { + // initialize recorder so that getPerfTracer path chooses + // RangerPerfCollectorTracer + PerfDataRecorder.initialize(true, 0, false, null); + Logger logger = Mockito.mock(Logger.class); + Mockito.when(logger.isDebugEnabled()).thenReturn(true); + RangerPerfTracer tracer = RangerPerfTracer.getPerfTracer(logger, "collect(tag)"); + assertNotNull(tracer); + RangerPerfTracer.log(tracer); + RangerPerfTracer.logAlways(tracer); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPerfTracerFactory.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPerfTracerFactory.java new file mode 100644 index 0000000000..3c80ee1c62 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPerfTracerFactory.java @@ -0,0 +1,46 @@ +/* + * 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.plugin.util; + +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 org.slf4j.Logger; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPerfTracerFactory { + @Test + public void test01_getPerfTracer_returnsInstance_and_logs() { + Logger logger = RangerPerfTracer.getPerfLogger("test"); + // ensure debug enabled by design? even if not, factory should still create a + // tracer + RangerPerfTracer tracer = RangerPerfTracerFactory.getPerfTracer(logger, "tag", "data"); + assertNotNull(tracer); + tracer.log(); + tracer.logAlways(); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPolicyDeltaUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPolicyDeltaUtil.java new file mode 100644 index 0000000000..ac121d095a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPolicyDeltaUtil.java @@ -0,0 +1,165 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerPolicyDelta; +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.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.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPolicyDeltaUtil { + private RangerPolicy policy(long id, String serviceType, int policyType) { + RangerPolicy p = new RangerPolicy(); + p.setId(id); + p.setServiceType(serviceType); + p.setPolicyType(policyType); + return p; + } + + private RangerPolicyDelta delta(int changeType, RangerPolicy p) { + RangerPolicyDelta d = new RangerPolicyDelta(); + d.setChangeType(changeType); + d.setPolicy(p); + return d; + } + + @Test + public void test01_applyDeltas_createUpdateDeleteAndFilterByServiceType() { + String serviceType = "svc"; + List base = new ArrayList<>(); + base.add(policy(1L, serviceType, RangerPolicy.POLICY_TYPE_ACCESS)); + base.add(policy(2L, serviceType, RangerPolicy.POLICY_TYPE_ACCESS)); + + List deltas = new ArrayList<>(); + // Update id=1 + deltas.add(delta(RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE, + policy(1L, serviceType, RangerPolicy.POLICY_TYPE_ACCESS))); + // Create id=3, but wrong serviceType -> ignored + deltas.add(delta(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE, + policy(3L, "other", RangerPolicy.POLICY_TYPE_ACCESS))); + // Create id=3 for correct serviceType + deltas.add(delta(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE, + policy(3L, serviceType, RangerPolicy.POLICY_TYPE_ACCESS))); + // Delete id=2 + deltas.add(delta(RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE, + policy(2L, serviceType, RangerPolicy.POLICY_TYPE_ACCESS))); + // Unknown change type -> ignored + RangerPolicyDelta unknown = delta(99, policy(4L, serviceType, RangerPolicy.POLICY_TYPE_ACCESS)); + deltas.add(unknown); + + List out = RangerPolicyDeltaUtil.applyDeltas(base, deltas, serviceType); + out.sort(RangerPolicy.POLICY_ID_COMPARATOR); + assertEquals(Arrays.asList(1L, 3L), Arrays.asList(out.get(0).getId(), out.get(1).getId())); + } + + @Test + public void test02_isValidDeltas_variousInvalidReasons() { + String svc = "svc"; + List deltas = new ArrayList<>(); + // null changeType -> invalid + RangerPolicyDelta d1 = new RangerPolicyDelta(); + d1.setPolicy(policy(1L, svc, RangerPolicy.POLICY_TYPE_ACCESS)); + deltas.add(d1); + assertFalse(RangerPolicyDeltaUtil.isValidDeltas(deltas, svc)); + + // unsupported changeType -> invalid + d1.setChangeType(99); + assertFalse(RangerPolicyDeltaUtil.isValidDeltas(Collections.singletonList(d1), svc)); + + // null policyId -> invalid + RangerPolicyDelta d2 = new RangerPolicyDelta(); + d2.setChangeType(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE); + d2.setPolicy(new RangerPolicy()); // id null + assertFalse(RangerPolicyDeltaUtil.isValidDeltas(Collections.singletonList(d2), svc)); + + // wrong serviceType -> invalid + RangerPolicyDelta d3 = new RangerPolicyDelta(); + d3.setChangeType(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE); + d3.setPolicy(policy(5L, "other", RangerPolicy.POLICY_TYPE_ACCESS)); + assertFalse(RangerPolicyDeltaUtil.isValidDeltas(Collections.singletonList(d3), svc)); + + // wrong policyType -> invalid + RangerPolicyDelta d4 = new RangerPolicyDelta(); + d4.setChangeType(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE); + RangerPolicy p4 = policy(6L, svc, 999); + d4.setPolicy(p4); + assertFalse(RangerPolicyDeltaUtil.isValidDeltas(Collections.singletonList(d4), svc)); + + // valid + RangerPolicyDelta d5 = new RangerPolicyDelta(); + d5.setChangeType(RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE); + d5.setPolicy(policy(7L, svc, RangerPolicy.POLICY_TYPE_ACCESS)); + assertTrue(RangerPolicyDeltaUtil.isValidDeltas(Collections.singletonList(d5), svc)); + } + + @Test + public void test03_hasPolicyDeltas_branchCoverage() { + // null servicePolicies -> returns null (logged), covered via branch that sets + // ret=null + Boolean retNull = RangerPolicyDeltaUtil.hasPolicyDeltas(null); + assertNull(retNull); + + ServicePolicies sp = new ServicePolicies(); + sp.setPolicies(new ArrayList<>()); + // No policies and no deltas -> returns null or false depending on + // policyDeltas=null + sp.setPolicyDeltas(null); + Boolean retFalseForceNew = RangerPolicyDeltaUtil.hasPolicyDeltas(sp); + assertEquals(Boolean.FALSE, retFalseForceNew); + + sp.setPolicies(new ArrayList<>()); + sp.setPolicyDeltas(new ArrayList<>()); + Boolean retNoChanges = RangerPolicyDeltaUtil.hasPolicyDeltas(sp); + assertNull(retNoChanges); + + // Both present -> null (conflict) + RangerPolicy p = policy(10L, "svc", RangerPolicy.POLICY_TYPE_ACCESS); + sp.setPolicies(Collections.singletonList(p)); + RangerPolicyDelta d = new RangerPolicyDelta(); + d.setChangeType(RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE); + d.setPolicy(p); + sp.setPolicyDeltas(Collections.singletonList(d)); + Boolean retConflict = RangerPolicyDeltaUtil.hasPolicyDeltas(sp); + assertNull(retConflict); + + // Only deltas + sp.setPolicies(Collections.emptyList()); + sp.setPolicyDeltas(Collections.singletonList(d)); + Boolean retOnlyDeltas = RangerPolicyDeltaUtil.hasPolicyDeltas(sp); + assertEquals(Boolean.TRUE, retOnlyDeltas); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPurgeResult.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPurgeResult.java new file mode 100644 index 0000000000..f6e225fd36 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerPurgeResult.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.plugin.util; + +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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerPurgeResult { + @Test + public void test01_ctorAndAccessors() { + RangerPurgeResult r1 = new RangerPurgeResult(); + r1.setRecordType("type"); + r1.setTotalRecordCount(10L); + r1.setPurgedRecordCount(3L); + assertEquals("type", r1.getRecordType()); + assertEquals(10L, r1.getTotalRecordCount().longValue()); + assertEquals(3L, r1.getPurgedRecordCount().longValue()); + + RangerPurgeResult r2 = new RangerPurgeResult("t", 5L, 2L); + String s = r2.toString(); + assertTrue(s.contains("RangerPurgeResult={")); + assertTrue(s.contains("recordType={t}")); + assertTrue(s.contains("totalRecordCount={5}")); + assertTrue(s.contains("purgedRecordCount={2}")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRESTClient.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRESTClient.java new file mode 100644 index 0000000000..fae1b0ac2a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRESTClient.java @@ -0,0 +1,402 @@ +/* + * 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.plugin.util; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import org.apache.hadoop.conf.Configuration; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +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.ArgumentMatchers; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.X509TrustManager; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.Response; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRESTClient { + @Test + public void test01_setQueryParams_withNulls_returnsNullOrSame() { + assertNull(RangerRESTClient.setQueryParams(null, null)); + } + + @Test + public void test02_getSSLContext_usesDefaultTrustManagersWhenNull() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + SSLContext sc = c.getSSLContext(null, null); + assertNotNull(sc); + } + + @Test + public void test03_shouldRetry_retriesThenThrows() throws Exception { + RangerRESTClient c = new RangerRESTClient("http://host1,http://host2", null, new Configuration()); + Exception ex = new RuntimeException("boom"); + c.setMaxRetryAttempts(1); + c.setRetryIntervalMs(1); + boolean first = c.shouldRetry("http://host2", c.getConfiguredURLs().size() - 1, 0, ex); + assertEquals(true, first); + assertThrows(RuntimeException.class, () -> { + try { + c.shouldRetry("http://host2", c.getConfiguredURLs().size() - 1, 1, ex); + } catch (Exception e) { + throw (RuntimeException) e; + } + }); + } + + @Test + public void test04_getKeyAndTrustManagers_invalidFile_throwIllegalState() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + c.setKeyStoreType("jks"); + c.setTrustStoreType("jks"); + assertThrows(IllegalStateException.class, () -> c.getKeyManagers("no-such.jks", "pwd")); + assertThrows(IllegalStateException.class, () -> c.getTrustManagers("no-such.jks", "pwd")); + } + + @Test + public void test05_setQueryParams_withParams_returnsNonNull() { + Client client = Client.create(); + WebResource wr = client.resource("http://localhost"); + Map params = new HashMap<>(); + params.put("a", "1"); + params.put("b", "2"); + WebResource out = RangerRESTClient.setQueryParams(wr, params); + assertNotNull(out); + } + + @Test + public void test06_createWebResource_withAndWithoutCookie_returnsBuilder() { + RangerRESTClient c = new RangerRESTClient("http://localhost", null, new Configuration()); + Map params = new HashMap<>(); + params.put("p", "v"); + WebResource.Builder b1 = c.createWebResource(0, "/api", params); + assertNotNull(b1); + + Cookie sid = new Cookie("sid", "v"); + WebResource.Builder b2 = c.createWebResource(0, "/api", params, sid); + assertNotNull(b2); + } + + @Test + public void test07_client_singleton_and_reset_createsNewInstance() { + RangerRESTClient c = new RangerRESTClient("http://localhost", null, new Configuration()); + Client c1 = c.getClient(); + Client c2 = c.getClient(); + assertNotNull(c1); + assertEquals(c1, c2); + c.resetClient(); + Client c3 = c.getClient(); + assertNotNull(c3); + assertNotEquals(c1, c3); + } + + @Test + public void test08_jsonSerialization_roundTrip() { + RangerRESTClient c = new RangerRESTClient("http://localhost", null, new Configuration()); + int[] in = new int[] {1, 2, 3}; + String json = c.toJson(in); + int[] out = c.fromJson(json, int[].class); + assertEquals(3, out.length); + assertEquals(1, out[0]); + assertEquals(3, out[2]); + } + + @Test + public void test09_isSslEnabled_flagSetFromUrl() { + RangerRESTClient c1 = new RangerRESTClient("http://host", null, new Configuration()); + assertEquals(false, c1.isSSL()); + RangerRESTClient c2 = new RangerRESTClient("https://host", null, new Configuration()); + assertEquals(true, c2.isSSL()); + } + + @Test + public void test10_createWebResource_usesCookieClientWhenCookieProvided() { + RangerRESTClient c = new RangerRESTClient("http://localhost", null, new Configuration()); + c.setBasicAuthInfo("u", "p"); + Cookie sid = new Cookie("sid", "v"); + WebResource.Builder b = c.createWebResource(0, "/api", null, sid); + assertNotNull(b); + } + + @Test + public void test11_getKeyManagers_withEmptyParams_returnsNull() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + assertNull(c.getKeyManagers("", "")); + } + + @Test + public void test12_getTrustManagers_withEmptyParams_returnsNull() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + assertNull(c.getTrustManagers("", "")); + } + + @Test + public void test13_shouldRetry_notLastUrl_returnsFalse() throws Exception { + RangerRESTClient c = new RangerRESTClient("http://host1,http://host2", null, new Configuration()); + Exception ex = new RuntimeException("boom"); + c.setMaxRetryAttempts(1); + c.setRetryIntervalMs(1); + boolean ret = c.shouldRetry("http://host1", 0, 0, ex); + assertEquals(false, ret); + } + + @Test + public void test14_buildClient_whenSSLFlagTrue_returnsClient() { + RangerRESTClient c = new RangerRESTClient("http://localhost", null, new Configuration()); + c.setSSL(true); + c.resetClient(); + Client built = c.getClient(); + assertNotNull(built); + } + + @Test + public void test15_getResource_returnsWebResource() { + RangerRESTClient c = new RangerRESTClient("http://localhost", null, new Configuration()); + WebResource wr = c.getResource("/api"); + assertNotNull(wr); + } + + @Test + public void test16_urlGetterSetter_roundTrip() { + RangerRESTClient c = new RangerRESTClient("http://h1", null, new Configuration()); + c.setUrl("http://h2"); + assertEquals("http://h2", c.getUrl()); + } + + @Test + public void test17_get_withRetryAcrossUrls_successOnSecond() throws Exception { + RangerRESTClient spy = Mockito.spy(new RangerRESTClient("http://h1,http://h2", null, new Configuration())); + spy.setLastKnownActiveUrlIndex(0); + + WebResource.Builder b1 = Mockito.mock(WebResource.Builder.class); + Mockito.when(b1.accept(ArgumentMatchers.anyString())).thenReturn(b1); + Mockito.when(b1.type(ArgumentMatchers.anyString())).thenReturn(b1); + Mockito.when(b1.get(ClientResponse.class)).thenThrow(new ClientHandlerException("boom")); + + ClientResponse ok = Mockito.mock(ClientResponse.class); + Mockito.when(ok.getStatusInfo()).thenReturn(Response.Status.OK); + WebResource.Builder b2 = Mockito.mock(WebResource.Builder.class); + Mockito.when(b2.accept(ArgumentMatchers.anyString())).thenReturn(b2); + Mockito.when(b2.type(ArgumentMatchers.anyString())).thenReturn(b2); + Mockito.when(b2.get(ClientResponse.class)).thenReturn(ok); + + Mockito.doReturn(b1).when(spy).createWebResource(0, "/r", null); + Mockito.doReturn(b2).when(spy).createWebResource(1, "/r", null); + + ClientResponse resp = spy.get("/r", null); + assertNotNull(resp); + assertEquals(1, spy.getLastKnownActiveUrlIndex()); + } + + @Test + public void test18_get_serverErrorOnFirst_thenSuccessOnSecond() throws Exception { + RangerRESTClient spy = Mockito.spy(new RangerRESTClient("http://h1,http://h2", null, new Configuration())); + spy.setLastKnownActiveUrlIndex(0); + + ClientResponse r500 = Mockito.mock(ClientResponse.class); + Mockito.when(r500.getStatus()).thenReturn(500); + Mockito.when(r500.getStatusInfo()).thenReturn(Response.Status.INTERNAL_SERVER_ERROR); + WebResource.Builder b1 = Mockito.mock(WebResource.Builder.class); + Mockito.when(b1.accept(ArgumentMatchers.anyString())).thenReturn(b1); + Mockito.when(b1.type(ArgumentMatchers.anyString())).thenReturn(b1); + Mockito.when(b1.get(ClientResponse.class)).thenReturn(r500); + + ClientResponse ok = Mockito.mock(ClientResponse.class); + Mockito.when(ok.getStatusInfo()).thenReturn(Response.Status.OK); + WebResource.Builder b2 = Mockito.mock(WebResource.Builder.class); + Mockito.when(b2.accept(ArgumentMatchers.anyString())).thenReturn(b2); + Mockito.when(b2.type(ArgumentMatchers.anyString())).thenReturn(b2); + Mockito.when(b2.get(ClientResponse.class)).thenReturn(ok); + + Mockito.doReturn(b1).when(spy).createWebResource(0, "/r2", null); + Mockito.doReturn(b2).when(spy).createWebResource(1, "/r2", null); + + ClientResponse resp = spy.get("/r2", null); + assertNotNull(resp); + assertEquals(1, spy.getLastKnownActiveUrlIndex()); + } + + @Test + public void test19_post_put_delete_success_setsActiveUrl() throws Exception { + RangerRESTClient spy = Mockito.spy(new RangerRESTClient("http://h1,http://h2", null, new Configuration())); + WebResource.Builder b = Mockito.mock(WebResource.Builder.class); + Mockito.when(b.accept(ArgumentMatchers.anyString())).thenReturn(b); + Mockito.when(b.type(ArgumentMatchers.anyString())).thenReturn(b); + + ClientResponse ok = Mockito.mock(ClientResponse.class); + Mockito.when(b.post(ArgumentMatchers.eq(ClientResponse.class), ArgumentMatchers.anyString())).thenReturn(ok); + Mockito.when(b.put(ArgumentMatchers.eq(ClientResponse.class), ArgumentMatchers.anyString())).thenReturn(ok); + Mockito.when(b.delete(ClientResponse.class)).thenReturn(ok); + + Mockito.doReturn(b).when(spy).createWebResource(0, "/p", new HashMap<>()); + assertNotNull(spy.post("/p", new HashMap<>(), new int[] {1})); + assertEquals(0, spy.getLastKnownActiveUrlIndex()); + + Mockito.doReturn(b).when(spy).createWebResource(0, "/u", new HashMap<>()); + assertNotNull(spy.put("/u", new HashMap<>(), new int[] {2})); + assertEquals(0, spy.getLastKnownActiveUrlIndex()); + + Mockito.doReturn(b).when(spy).createWebResource(0, "/d", new HashMap<>()); + assertNotNull(spy.delete("/d", new HashMap<>())); + assertEquals(0, spy.getLastKnownActiveUrlIndex()); + } + + @Test + public void test20_post_put_delete_withCookie_success() throws Exception { + RangerRESTClient spy = Mockito.spy(new RangerRESTClient("http://h1,http://h2", null, new Configuration())); + Cookie sid = new Cookie("sid", "v"); + + WebResource.Builder b = Mockito.mock(WebResource.Builder.class); + Mockito.when(b.accept(ArgumentMatchers.anyString())).thenReturn(b); + Mockito.when(b.type(ArgumentMatchers.anyString())).thenReturn(b); + + ClientResponse ok = Mockito.mock(ClientResponse.class); + Mockito.when(b.post(ArgumentMatchers.eq(ClientResponse.class), ArgumentMatchers.anyString())).thenReturn(ok); + Mockito.when(b.put(ArgumentMatchers.eq(ClientResponse.class), ArgumentMatchers.anyString())).thenReturn(ok); + Mockito.when(b.delete(ClientResponse.class)).thenReturn(ok); + + Mockito.doReturn(b).when(spy).createWebResource(0, "/pc", null, sid); + Mockito.doReturn(b).when(spy).createWebResource(0, "/uc", null, sid); + Mockito.doReturn(b).when(spy).createWebResource(0, "/dc", null, sid); + + assertNotNull(spy.post("/pc", null, new int[] {3}, sid)); + assertNotNull(spy.put("/uc", new int[] {4}, sid)); + assertNotNull(spy.delete("/dc", null, sid)); + } + + @Test + public void test21_init_withPluginConfig_setsBasicAuthFilter_noCrash() { + RangerPluginConfig rpc = new RangerPluginConfig("hive", null, "app", null, null, null); + String prefix = rpc.getPropertyPrefix(); + rpc.set(prefix + ".policy.rest.client.username", "u"); + rpc.set(prefix + ".policy.rest.client.password", "p"); + + RangerRESTClient c = new RangerRESTClient("http://host", null, rpc); + Cookie sid = new Cookie("sid", "v"); + WebResource.Builder b = c.createWebResource(0, "/api", null, sid); + assertNotNull(b); + } + + @Test + public void test22_setters_getters_forTimeouts_and_credentials() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + c.setRestClientConnTimeOutMs(1234); + c.setRestClientReadTimeOutMs(5678); + c.setBasicAuthInfo("user", "pass"); + assertEquals(1234, c.getRestClientConnTimeOutMs()); + assertEquals(5678, c.getRestClientReadTimeOutMs()); + assertEquals("user", c.getUsername()); + assertEquals("pass", c.getPassword()); + } + + @Test + public void test23_getSSLContext_withExplicitTrustManagers() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + X509TrustManager tm = new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + SSLContext sc = c.getSSLContext(null, new javax.net.ssl.TrustManager[] {tm}); + assertNotNull(sc); + } + + @Test + public void test24_setClient_overridesAndReturnsSame() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + Client provided = Client.create(); + c.setClient(provided); + Client returned = c.getClient(); + assertEquals(provided, returned); + } + + @Test + public void test25_get_withCookie_success() throws Exception { + RangerRESTClient spy = Mockito.spy(new RangerRESTClient("http://h1,http://h2", null, new Configuration())); + Cookie sid = new Cookie("sid", "v"); + + WebResource.Builder b = Mockito.mock(WebResource.Builder.class); + Mockito.when(b.accept(ArgumentMatchers.anyString())).thenReturn(b); + Mockito.when(b.type(ArgumentMatchers.anyString())).thenReturn(b); + ClientResponse ok = Mockito.mock(ClientResponse.class); + Mockito.when(ok.getStatusInfo()).thenReturn(Response.Status.OK); + Mockito.when(b.get(ClientResponse.class)).thenReturn(ok); + + Mockito.doReturn(b).when(spy).createWebResource(0, "/gc", null, sid); + + ClientResponse resp = spy.get("/gc", null, sid); + assertNotNull(resp); + assertEquals(0, spy.getLastKnownActiveUrlIndex()); + } + + @Test + public void test26_setLastKnownActiveUrlIndex_and_getConfiguredURLs() { + RangerRESTClient c = new RangerRESTClient("http://h1,http://h2", null, new Configuration()); + c.setLastKnownActiveUrlIndex(1); + assertEquals(1, c.getLastKnownActiveUrlIndex()); + assertEquals(2, c.getConfiguredURLs().size()); + } + + @Test + public void test27_setQueryParams_nonNullResourceNullParams_returnsSame() { + Client client = Client.create(); + WebResource wr = client.resource("http://localhost"); + WebResource out = RangerRESTClient.setQueryParams(wr, null); + // WebResource doesn't override equals, reference equality suffices + assertEquals(wr, out); + } + + @Test + public void test28_retry_getters_roundTrip() { + RangerRESTClient c = new RangerRESTClient("http://host", null, new Configuration()); + c.setMaxRetryAttempts(3); + c.setRetryIntervalMs(250); + assertEquals(3, c.getMaxRetryAttempts()); + assertEquals(250, c.getRetryIntervalMs()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRESTUtils.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRESTUtils.java new file mode 100644 index 0000000000..3477d3c666 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRESTUtils.java @@ -0,0 +1,76 @@ +/* + * 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.plugin.util; + +import org.apache.commons.lang3.StringUtils; +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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRESTUtils { + @Test + public void test01_getPluginId_withAndWithoutAppId() { + RangerRESTUtils utils = new RangerRESTUtils(); + + String service = "svc"; + String pluginIdNoApp = utils.getPluginId(service, null); + assertNotNull(pluginIdNoApp); + assertTrue(pluginIdNoApp.endsWith("-" + service)); + + String pluginIdWithApp = utils.getPluginId(service, "app"); + assertNotNull(pluginIdWithApp); + assertTrue(pluginIdWithApp.contains("app@")); + assertTrue(pluginIdWithApp.endsWith("-" + service)); + } + + @Test + public void test02_getPluginId_trimsLengthToMax() { + RangerRESTUtils utils = new RangerRESTUtils(); + String service = "serviceName"; + String veryLongApp = StringUtils.repeat("a", 300); + String pluginId = utils.getPluginId(service, veryLongApp); + assertTrue(pluginId.length() <= 255); + } + + @Test + public void test03_hostnameAndAppIdParsing() { + RangerRESTUtils.hostname = "hostX"; + RangerRESTUtils utils = new RangerRESTUtils(); + assertEquals("hostX", utils.getAgentHostname()); + + String service = "service"; + String pluginId = "app@hostX-" + service; + assertEquals("hostX", utils.getHostnameFromPluginId(pluginId, service)); + assertEquals("hostX", utils.getHostnameFromPluginId("hostX-" + service, service)); + assertEquals("hostX", utils.getHostnameFromPluginId("hostX-abc", null)); + assertEquals("app", utils.getAppIdFromPluginId(pluginId)); + assertEquals("**Unknown**", utils.getAppIdFromPluginId("")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerReadWriteLock.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerReadWriteLock.java new file mode 100644 index 0000000000..a8ed286bc6 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerReadWriteLock.java @@ -0,0 +1,77 @@ +/* + * 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.plugin.util; + +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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerReadWriteLock { + @Test + public void test01_lockingDisabled_noOpLocks() { + RangerReadWriteLock rw = new RangerReadWriteLock(false); + try (RangerReadWriteLock.RangerLock read = rw.getReadLock()) { + assertFalse(read.isLockingEnabled()); + } + try (RangerReadWriteLock.RangerLock write = rw.getWriteLock()) { + assertFalse(write.isLockingEnabled()); + } + assertEquals("ReadWriteLock:[null]", rw.toString()); + } + + @Test + public void test02_lockingEnabled_readThenWrite() { + RangerReadWriteLock rw = new RangerReadWriteLock(true); + String toString = rw.toString(); + assertTrue(toString.contains("ReadWriteLock:[")); + + try (RangerReadWriteLock.RangerLock read = rw.getReadLock()) { + assertTrue(read.isLockingEnabled()); + } + try (RangerReadWriteLock.RangerLock write = rw.getWriteLock()) { + assertTrue(write.isLockingEnabled()); + } + } + + @Test + public void test03_getWriteLock_yieldsWhenNoReaders() throws Exception { + RangerReadWriteLock rw = new RangerReadWriteLock(true); + + Thread writer = new Thread(() -> { + try (RangerReadWriteLock.RangerLock ignored = rw.getWriteLock()) { + // acquired + } + }); + + writer.start(); + writer.join(2000L); + assertFalse(writer.isAlive()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRequestedResources.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRequestedResources.java new file mode 100644 index 0000000000..e211a8e1b5 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRequestedResources.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.plugin.util; + +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessResource; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +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.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRequestedResources { + private RangerAccessResource resourceWithString(final String s) { + return new RangerAccessResource() { + @Override + public String getOwnerUser() { + return null; + } + + @Override + public boolean exists(String name) { + return false; + } + + @Override + public Object getValue(String name) { + return null; + } + + @Override + public RangerServiceDef getServiceDef() { + return null; + } + + @Override + public Set getKeys() { + return null; + } + + @Override + public String getLeafName() { + return null; + } + + @Override + public String getAsString() { + return s; + } + + @Override + public String getCacheKey() { + return s; + } + + @Override + public Map getAsMap() { + return null; + } + + @Override + public RangerAccessResource getReadOnlyCopy() { + return this; + } + }; + } + + @Test + public void test01_addRequestedResource_ignoresDuplicates() { + RangerRequestedResources requested = new RangerRequestedResources(); + RangerAccessResource r1 = resourceWithString("r1"); + requested.addRequestedResource(r1); + requested.addRequestedResource(r1); // duplicate should be ignored + // isMutuallyExcluded path when list size <=1 returns true without matcher + // interaction + assertTrue(requested.isMutuallyExcluded(new ArrayList<>(), new HashMap<>())); + assertNotNull(requested.toString()); + } + + @Test + public void test02_isMutuallyExcluded_falseWhenTwoMatchersMatchDifferentResources() { + RangerRequestedResources requested = new RangerRequestedResources(); + RangerAccessResource r1 = resourceWithString("r1"); + RangerAccessResource r2 = resourceWithString("r2"); + requested.addRequestedResource(r1); + requested.addRequestedResource(r2); + + RangerPolicyResourceMatcher m = Mockito.mock(RangerPolicyResourceMatcher.class); + Map ctx = new HashMap<>(); + Mockito.when(m.isMatch(Mockito.eq(r1), Mockito.eq(ctx))).thenReturn(true); + Mockito.when(m.isMatch(Mockito.eq(r2), Mockito.eq(ctx))).thenReturn(true); + + List matchers = new ArrayList<>(); + matchers.add(m); + + assertFalse(requested.isMutuallyExcluded(matchers, ctx)); + } + + @Test + public void test03_isMutuallyExcluded_trueWhenOnlyOneResourceMatches() { + RangerRequestedResources requested = new RangerRequestedResources(); + RangerAccessResource r1 = resourceWithString("r1"); + RangerAccessResource r2 = resourceWithString("r2"); + requested.addRequestedResource(r1); + requested.addRequestedResource(r2); + + RangerPolicyResourceMatcher m = Mockito.mock(RangerPolicyResourceMatcher.class); + Map ctx = new HashMap<>(); + Mockito.when(m.isMatch(Mockito.eq(r1), Mockito.eq(ctx))).thenReturn(true); + Mockito.when(m.isMatch(Mockito.eq(r2), Mockito.eq(ctx))).thenReturn(false); + + List matchers = new ArrayList<>(); + matchers.add(m); + + assertTrue(requested.isMutuallyExcluded(matchers, ctx)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerResourceEvaluatorsRetriever.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerResourceEvaluatorsRetriever.java new file mode 100644 index 0000000000..fcc0fa154f --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerResourceEvaluatorsRetriever.java @@ -0,0 +1,158 @@ +/* + * 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.plugin.util; + +import org.apache.commons.collections.Predicate; +import org.apache.ranger.plugin.model.RangerPolicy; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.policyengine.RangerAccessRequest; +import org.apache.ranger.plugin.policyengine.RangerResourceTrie; +import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher; +import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator; +import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher; +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.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerResourceEvaluatorsRetriever { + private static class DummyEval implements RangerResourceEvaluator { + @Override + public long getId() { + return 1L; + } + + @Override + public RangerPolicyResourceMatcher getPolicyResourceMatcher() { + return null; + } + + @Override + public Map getPolicyResource() { + return Collections.emptyMap(); + } + + @Override + public RangerResourceMatcher getResourceMatcher(String resourceName) { + return null; + } + + @Override + public boolean isAncestorOf(RangerServiceDef.RangerResourceDef resourceDef) { + return false; + } + + @Override + public boolean isLeaf(String resourceName) { + return true; + } + } + + private static class FakeTrie extends RangerResourceTrie { + private final int count; + private final Set set; + + FakeTrie(String resourceName, int count, Set set) { + super(makeResDef(resourceName), Collections.emptyList()); + this.count = count; + this.set = set; + } + + private static RangerServiceDef.RangerResourceDef makeResDef(String name) { + RangerServiceDef.RangerResourceDef def = new RangerServiceDef.RangerResourceDef(); + def.setName(name); + return def; + } + + @Override + public int getEvaluatorsCountForResource(Object r, RangerAccessRequest.ResourceElementMatchingScope s, + Predicate p) { + return count; + } + + @Override + public Set getEvaluatorsForResource(Object r, RangerAccessRequest.ResourceElementMatchingScope s, + Predicate p) { + return set; + } + + @Override + public Set getEvaluatorsForResource(Object r, RangerAccessRequest.ResourceElementMatchingScope s, + Set filter, Predicate p) { + return set; + } + } + + @Test + public void test01_emptyInputsReturnNull() { + Collection out = RangerResourceEvaluatorsRetriever + .getEvaluators(Collections.emptyMap(), Collections.emptyMap()); + assertNull(out); + } + + @Test + public void test02_singleKeySkipsCountAndReturnsSet() { + Map> trie = new HashMap<>(); + Set evals = new HashSet<>(); + evals.add(new DummyEval()); + trie.put("db", new FakeTrie<>("db", 1, evals)); + Map resource = new HashMap<>(); + resource.put("db", "sales"); + Collection out = RangerResourceEvaluatorsRetriever.getEvaluators(trie, resource, + new HashMap<>()); + assertNotNull(out); + assertTrue(out.containsAll(evals)); + } + + @Test + public void test03_multiKeyChoosesMinCountAndIntersects() { + Map> trie = new HashMap<>(); + Set setDb = new HashSet<>(); + RangerResourceEvaluator e1 = new DummyEval(); + setDb.add(e1); + Set setTable = new HashSet<>(); + setTable.add(e1); // intersection not empty + trie.put("db", new FakeTrie<>("db", 1, setDb)); + trie.put("table", new FakeTrie<>("table", 2, setTable)); + Map resource = new HashMap<>(); + resource.put("db", "sales"); + resource.put("table", "orders"); + Collection out = RangerResourceEvaluatorsRetriever.getEvaluators(trie, resource, + new HashMap<>(), null); + assertNotNull(out); + assertTrue(out.contains(e1)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRoles.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRoles.java new file mode 100644 index 0000000000..c09c5e9261 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRoles.java @@ -0,0 +1,56 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.RangerRole; +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.util.Date; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRoles { + @Test + public void test01_gettersSetters() { + RangerRoles roles = new RangerRoles(); + roles.setServiceName("svc"); + roles.setRoleVersion(5L); + roles.setRoleUpdateTime(new Date()); + Set set = new HashSet<>(); + set.add(new RangerRole()); + roles.setRangerRoles(set); + + assertEquals("svc", roles.getServiceName()); + assertEquals(5L, roles.getRoleVersion()); + assertNotNull(roles.getRoleUpdateTime()); + assertEquals(1, roles.getRangerRoles().size()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRolesProvider.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRolesProvider.java new file mode 100644 index 0000000000..457ddd4895 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRolesProvider.java @@ -0,0 +1,173 @@ +/* + * 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.plugin.util; + +import org.apache.hadoop.conf.Configuration; +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig; +import org.apache.ranger.plugin.model.RangerRole; +import org.apache.ranger.plugin.service.RangerBasePlugin; +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.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRolesProvider { + public static class AdminNull implements RangerAdminClient { + @Override + public void init(String serviceName, String appId, String configPropertyPrefix, Configuration config) { + } + + @Override + public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + return null; + } + + @Override + public RangerRoles getRolesIfUpdated(long lastKnownRoleVersion, long lastActivationTimeInMills) throws Exception { + return null; + } + + @Override + public RangerRole createRole(RangerRole request) { + return null; + } + + @Override + public void dropRole(String execUser, String roleName) { + } + + @Override + public List getAllRoles(String execUser) { + return null; + } + + @Override + public List getUserRoles(String execUser) { + return null; + } + + @Override + public RangerRole getRole(String execUser, String roleName) { + return null; + } + + @Override + public void grantRole(GrantRevokeRoleRequest request) { + } + + @Override + public void revokeRole(GrantRevokeRoleRequest request) { + } + + @Override + public void grantAccess(GrantRevokeRequest request) { + } + + @Override + public void revokeAccess(GrantRevokeRequest request) { + } + + @Override + public ServiceTags getServiceTagsIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + return null; + } + + @Override + public List getTagTypes(String tagTypePattern) { + return null; + } + + @Override + public RangerUserStore getUserStoreIfUpdated(long lastKnownUserStoreVersion, long lastActivationTimeInMillis) { + return null; + } + + @Override + public ServiceGdsInfo getGdsInfoIfUpdated(long lastKnownVersion, long lastActivationTimeInMillis) { + return null; + } + } + + public static class AdminThrowsSNF extends AdminNull { + @Override + public RangerRoles getRolesIfUpdated(long lastKnownRoleVersion, long lastActivationTimeInMills) throws RangerServiceNotFoundException { + throw new RangerServiceNotFoundException("svcName"); + } + } + + public static class CapturingPlugin extends RangerBasePlugin { + public RangerRoles lastRoles; + + public CapturingPlugin() { + super(new RangerPluginConfig("svcType", "svcName", "appId", null, null, null)); + } + + @Override + public void setRoles(RangerRoles roles) { + this.lastRoles = roles; + } + } + + @Test + public void test01_loadUserGroupRoles_createsCacheWhenAdminReturnsNull() throws Exception { + Path tmp = Files.createTempDirectory("roles-cache"); + String cacheDir = tmp.toFile().getAbsolutePath(); + CapturingPlugin plugin = new CapturingPlugin(); + RangerRolesProvider provider = new RangerRolesProvider("svcType", "appId", "svcName", new AdminNull(), cacheDir, + plugin.getConfig()); + provider.loadUserGroupRoles(plugin); + // cache file should exist + File[] files = new File(cacheDir).listFiles((dir, name) -> name.contains("_svcName_roles.json")); + assertTrue(files != null && files.length == 1); + assertTrue(plugin.lastRoles != null); + } + + @Test + public void test02_disableCacheOnServiceNotFound_renamesCache() throws Exception { + Path tmp = Files.createTempDirectory("roles-cache-snf"); + String cacheDir = tmp.toFile().getAbsolutePath(); + // pre-create a dummy cache file to be renamed + File cache = new File(cacheDir, "appId_svcName_roles.json"); + cache.getParentFile().mkdirs(); + Files.write(cache.toPath(), "{}".getBytes(StandardCharsets.UTF_8)); + + CapturingPlugin plugin = new CapturingPlugin(); + RangerRolesProvider provider = new RangerRolesProvider("svcType", "appId", "svcName", new AdminThrowsSNF(), + cacheDir, plugin.getConfig()); + provider.loadUserGroupRoles(plugin); + // original file should be moved or deleted + File[] backups = new File(cacheDir).listFiles((dir, name) -> name.startsWith("appId_svcName_roles.json_")); + assertTrue(!cache.exists() || (backups != null && backups.length >= 1)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRolesUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRolesUtil.java new file mode 100644 index 0000000000..1f4ec54a8a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerRolesUtil.java @@ -0,0 +1,105 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.RangerRole; +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.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +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; + +/** + * @generated by Cursor + * @description + */ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerRolesUtil { + private RangerRole role(String name, List users, List groups, List roles) { + RangerRole r = new RangerRole(); + r.setName(name); + List u = new ArrayList<>(); + for (String s : users) { + u.add(new RangerRole.RoleMember(s, false)); + } + r.setUsers(u); + List g = new ArrayList<>(); + for (String s : groups) { + g.add(new RangerRole.RoleMember(s, false)); + } + r.setGroups(g); + List rr = new ArrayList<>(); + for (String s : roles) { + rr.add(new RangerRole.RoleMember(s, false)); + } + r.setRoles(rr); + return r; + } + + @Test + public void test01_mappingsWithNestedRoles() { + RangerRoles roles = new RangerRoles(); + roles.setRoleVersion(5L); + Set set = new HashSet<>(); + set.add(role("roleA", Arrays.asList("u1"), Arrays.asList("g1"), Arrays.asList("roleB"))); + set.add(role("roleB", Arrays.asList("u2"), Arrays.asList("g2"), Arrays.asList("roleC"))); + set.add(role("roleC", Arrays.asList("u3"), Arrays.asList("g3"), new ArrayList<>())); + roles.setRangerRoles(set); + + RangerRolesUtil util = new RangerRolesUtil(roles); + assertEquals(5L, util.getRoleVersion()); + assertNotNull(util.getRoles()); + + Map> userMap = util.getUserRoleMapping(); + Map> groupMap = util.getGroupRoleMapping(); + Map> roleMap = util.getRoleRoleMapping(); + Map> roleToUsers = util.getRoleToUserMapping(); + Map> roleToGroups = util.getRoleToGroupMapping(); + + assertTrue(userMap.get("u1").contains("roleA")); + assertTrue(groupMap.get("g1").contains("roleA")); + assertTrue(roleMap.get("roleB").contains("roleA")); + + // Nested membership propagation + assertTrue(roleToUsers.get("roleA").contains("u2")); + assertTrue(roleToGroups.get("roleA").contains("g2")); + assertTrue(roleToUsers.get("roleA").contains("u3")); + assertTrue(roleToGroups.get("roleA").contains("g3")); + } + + @Test + public void test02_nullRoles_resultsInDefaultVersionAndEmptyMaps() { + RangerRolesUtil util = new RangerRolesUtil(null); + assertEquals(-1L, util.getRoleVersion()); + assertTrue(util.getUserRoleMapping().isEmpty()); + assertTrue(util.getGroupRoleMapping().isEmpty()); + assertTrue(util.getRoleRoleMapping().isEmpty()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerSecurityZoneHelper.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerSecurityZoneHelper.java new file mode 100644 index 0000000000..69117cab86 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerSecurityZoneHelper.java @@ -0,0 +1,219 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.RangerPrincipal; +import org.apache.ranger.plugin.model.RangerSecurityZone; +import org.apache.ranger.plugin.model.RangerSecurityZoneV2.RangerSecurityZoneChangeRequest; +import org.apache.ranger.plugin.model.RangerSecurityZoneV2.RangerSecurityZoneResource; +import org.apache.ranger.plugin.model.RangerSecurityZoneV2.RangerSecurityZoneServiceV2; +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.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.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerSecurityZoneHelper { + @Test + public void test01_updateZone_addResourceAndTagService() throws Exception { + RangerSecurityZone zone = new RangerSecurityZone(); + zone.setServices(new HashMap<>()); + zone.setTagServices(new ArrayList<>()); + zone.setAdminUsers(new ArrayList<>()); + zone.setAdminUserGroups(new ArrayList<>()); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditUsers(new ArrayList<>()); + zone.setAuditUserGroups(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + + RangerSecurityZoneHelper helper = new RangerSecurityZoneHelper(zone, "user"); + + Map> resMap = new HashMap<>(); + resMap.put("path", new ArrayList<>(Arrays.asList("/a"))); + RangerSecurityZoneResource rsrc = new RangerSecurityZoneResource(resMap); + List rsrcs = new ArrayList<>(); + rsrcs.add(rsrc); + RangerSecurityZoneServiceV2 svcV2 = new RangerSecurityZoneServiceV2(rsrcs); + Map update = new HashMap<>(); + update.put("svcA", svcV2); + + RangerSecurityZoneChangeRequest req = new RangerSecurityZoneChangeRequest(); + req.setResourcesToUpdate(update); + req.setTagServicesToAdd(new ArrayList<>(Arrays.asList("tagSvc"))); + req.setAdminsToAdd( + new ArrayList<>(Arrays.asList(new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "u1")))); + req.setAuditorsToAdd( + new ArrayList<>(Arrays.asList(new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "u2")))); + + assertDoesNotThrow(() -> helper.updateZone(req)); + // service should be present now + assertEquals(1, zone.getServices().size()); + assertEquals(1, zone.getTagServices().size()); + } + + @Test + public void test02_updateZone_removeFromMissingService_throws() { + RangerSecurityZone zone = new RangerSecurityZone(); + zone.setServices(new HashMap<>()); + zone.setTagServices(new ArrayList<>()); + zone.setAdminUsers(new ArrayList<>()); + zone.setAdminUserGroups(new ArrayList<>()); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditUsers(new ArrayList<>()); + zone.setAuditUserGroups(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + RangerSecurityZoneHelper helper = new RangerSecurityZoneHelper(zone, "user"); + + RangerSecurityZoneServiceV2 svcV2 = new RangerSecurityZoneServiceV2(new ArrayList<>()); + Map remove = new HashMap<>(); + remove.put("missingSvc", svcV2); + + RangerSecurityZoneChangeRequest req = new RangerSecurityZoneChangeRequest(); + req.setResourcesToRemove(remove); + + assertThrows(Exception.class, () -> helper.updateZone(req)); + } + + @Test + public void test03_updateZone_removeNonExistingTagService_throws() { + RangerSecurityZone zone = new RangerSecurityZone(); + zone.setServices(new HashMap<>()); + zone.setTagServices(new ArrayList<>()); + zone.setAdminUsers(new ArrayList<>()); + zone.setAdminUserGroups(new ArrayList<>()); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditUsers(new ArrayList<>()); + zone.setAuditUserGroups(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + RangerSecurityZoneHelper helper = new RangerSecurityZoneHelper(zone, "user"); + + RangerSecurityZoneChangeRequest req = new RangerSecurityZoneChangeRequest(); + req.setTagServicesToRemove(new ArrayList<>(Arrays.asList("tagSvc"))); + assertThrows(Exception.class, () -> helper.updateZone(req)); + } + + @Test + public void test04_addExistingAdmin_throws() throws Exception { + RangerSecurityZone zone = new RangerSecurityZone(); + zone.setServices(new HashMap<>()); + zone.setTagServices(new ArrayList<>()); + zone.setAdminUsers(new ArrayList<>(Arrays.asList("u1"))); + zone.setAdminUserGroups(new ArrayList<>()); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditUsers(new ArrayList<>()); + zone.setAuditUserGroups(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + RangerSecurityZoneHelper helper = new RangerSecurityZoneHelper(zone, "user"); + + RangerSecurityZoneChangeRequest req = new RangerSecurityZoneChangeRequest(); + req.setAdminsToAdd(new ArrayList<>(Arrays.asList(new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "u1")))); + assertThrows(Exception.class, () -> helper.updateZone(req)); + } + + @Test + public void test05_removeNonExistingAdmin_throws() { + RangerSecurityZone zone = new RangerSecurityZone(); + zone.setServices(new HashMap<>()); + zone.setTagServices(new ArrayList<>()); + zone.setAdminUsers(new ArrayList<>()); + zone.setAdminUserGroups(new ArrayList<>()); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditUsers(new ArrayList<>()); + zone.setAuditUserGroups(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + RangerSecurityZoneHelper helper = new RangerSecurityZoneHelper(zone, "user"); + + RangerSecurityZoneChangeRequest req = new RangerSecurityZoneChangeRequest(); + req.setAdminsToRemove(new ArrayList<>(Arrays.asList(new RangerPrincipal(RangerPrincipal.PrincipalType.USER, "u1")))); + assertThrows(Exception.class, () -> helper.updateZone(req)); + } + + @Test + public void test06_serviceHelper_resourceCRUDPaths() { + // Build a zone with one service and ensure CRUD operations behave as expected + RangerSecurityZone zone = new RangerSecurityZone(); + zone.setServices(new HashMap<>()); + zone.setTagServices(new ArrayList<>()); + zone.setAdminUsers(new ArrayList<>()); + zone.setAdminUserGroups(new ArrayList<>()); + zone.setAdminRoles(new ArrayList<>()); + zone.setAuditUsers(new ArrayList<>()); + zone.setAuditUserGroups(new ArrayList<>()); + zone.setAuditRoles(new ArrayList<>()); + RangerSecurityZoneHelper helper = new RangerSecurityZoneHelper(zone, "user"); + + RangerSecurityZoneHelper.RangerSecurityZoneServiceHelper svc = helper.addZoneService("svc1"); + assertNotNull(svc); + + Map> resMap = new HashMap<>(); + resMap.put("db", new ArrayList<>(Arrays.asList("db1"))); + RangerSecurityZoneResource r = new RangerSecurityZoneResource(resMap); + + // add + RangerSecurityZoneResource added = svc.addResource(r); + assertNotNull(added.getId()); + long id = added.getId(); + + // get by id + RangerSecurityZoneResource byId = svc.getResource(id); + assertNotNull(byId); + + // get by map + RangerSecurityZoneResource byMap = svc.getResource(resMap); + assertNotNull(byMap); + + // update with id + Map> resMap2 = new HashMap<>(); + resMap2.put("db", new ArrayList<>(Arrays.asList("db2"))); + RangerSecurityZoneResource upd = new RangerSecurityZoneResource(resMap2); + upd.setId(id); + svc.updateResource(upd); + RangerSecurityZoneResource afterUpd = svc.getResource(id); + assertEquals(resMap2, afterUpd.getResource()); + + // remove by id + RangerSecurityZoneResource removed = svc.removeResource(id); + assertNotNull(removed); + + // confirm service gets removed when resource count is zero via updateZone remove path + RangerSecurityZoneServiceV2 svcV2 = new RangerSecurityZoneServiceV2(new ArrayList<>()); + Map remove = new HashMap<>(); + remove.put("svc1", svcV2); + RangerSecurityZoneChangeRequest req = new RangerSecurityZoneChangeRequest(); + req.setResourcesToRemove(remove); + assertDoesNotThrow(() -> helper.updateZone(req)); + assertEquals(0, zone.getServices().size()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerServiceNotFoundException.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerServiceNotFoundException.java new file mode 100644 index 0000000000..76759cf541 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerServiceNotFoundException.java @@ -0,0 +1,56 @@ +/* + * 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.plugin.util; + +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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceNotFoundException { + @Test + public void test01_constructorsAndMessages() { + RangerServiceNotFoundException e1 = new RangerServiceNotFoundException("svcA"); + assertEquals("svcA", e1.getMessage()); + + String msg = RangerServiceNotFoundException.buildExceptionMsg("svcA"); + assertNotNull(msg); + assertEquals("\"RANGER_ERROR_SERVICE_NOT_FOUND: ServiceName=svcA\"", msg); + } + + @Test + public void test02_throwExceptionIfServiceNotFound() { + String serviceName = "svcB"; + String exceptionMsg = RangerServiceNotFoundException.buildExceptionMsg(serviceName) + " : additional details"; + + RangerServiceNotFoundException ex = assertThrows(RangerServiceNotFoundException.class, + () -> RangerServiceNotFoundException.throwExceptionIfServiceNotFound(serviceName, exceptionMsg)); + assertEquals(serviceName, ex.getMessage()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerServiceTagsDeltaUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerServiceTagsDeltaUtil.java new file mode 100644 index 0000000000..145f8cd236 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerServiceTagsDeltaUtil.java @@ -0,0 +1,165 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.RangerServiceResource; +import org.apache.ranger.plugin.model.RangerTag; +import org.apache.ranger.plugin.model.RangerTagDef; +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.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.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceTagsDeltaUtil { + private static RangerTag tagOf(String type) { + RangerTag t = new RangerTag(); + t.setType(type); + return t; + } + + @Test + public void test01_applyDelta_preconditionsAndTagDefRemovalAndResourceReplace() { + ServiceTags base = new ServiceTags(); + base.setServiceName("svc"); + // tagdef id 10 exists + Map tagDefs = new HashMap<>(); + tagDefs.put(10L, new RangerTagDef("TDEF")); + base.setTagDefinitions(tagDefs); + // resource id 100 with signature sigA + List resources = new ArrayList<>(); + RangerServiceResource r = new RangerServiceResource(); + r.setId(100L); + r.setResourceSignature("sigA"); + resources.add(r); + base.setServiceResources(resources); + base.setResourceToTagIds(new HashMap<>()); + + // delta removes tagdef 10 (empty name) and replaces resource signature + ServiceTags delta = new ServiceTags(); + delta.setIsDelta(true); + delta.setServiceName("svc"); + Map dd = new HashMap<>(); + RangerTagDef removed = new RangerTagDef(""); // empty name -> removal marker + dd.put(10L, removed); + delta.setTagDefinitions(dd); + List dRes = new ArrayList<>(); + RangerServiceResource r2 = new RangerServiceResource(); + r2.setId(100L); + r2.setResourceSignature("sigB"); + dRes.add(r2); + delta.setServiceResources(dRes); + + ServiceTags out = RangerServiceTagsDeltaUtil.applyDelta(base, delta, false); + assertNotNull(out); + // implementation keeps the key but with empty name to indicate deletion + assertTrue(out.getTagDefinitions().containsKey(10L)); + assertEquals("", out.getTagDefinitions().get(10L).getName()); + // original resource entry is tombstoned (signature null) and a new one with sigB is appended + boolean hasNullSig = false; + boolean hasNewSig = false; + for (RangerServiceResource s : out.getServiceResources()) { + if (s.getId() != null && s.getId().longValue() == 100L) { + if (s.getResourceSignature() == null) { + hasNullSig = true; + } + if ("sigB".equals(s.getResourceSignature())) { + hasNewSig = true; + } + } + } + assertTrue(hasNullSig); + assertTrue(hasNewSig); + } + + @Test + public void test02_applyDelta_dedupTagsAndRemapResourceTagIds() { + ServiceTags base = new ServiceTags(); + base.setServiceName("svc"); + base.setTagDefinitions(new HashMap<>()); + base.setTags(new HashMap<>()); + base.setServiceResources(new ArrayList<>()); + Map> r2t = new HashMap<>(); + r2t.put(100L, new ArrayList()); + base.setResourceToTagIds(r2t); + + // first delta: add tag id 1 of type T and map to resource 100 + ServiceTags d1 = new ServiceTags(); + d1.setIsDelta(true); + d1.setServiceName("svc"); + Map tags1 = new HashMap<>(); + tags1.put(1L, tagOf("T")); + d1.setTags(tags1); + Map> map1 = new HashMap<>(); + map1.put(100L, new ArrayList(Arrays.asList(1L))); + d1.setResourceToTagIds(map1); + + ServiceTags out1 = RangerServiceTagsDeltaUtil.applyDelta(base, d1, true); + assertTrue(out1.getTags().containsKey(1L)); + + // second delta: add duplicate tag with new id 2; mapping should remap to 1 + ServiceTags d2 = new ServiceTags(); + d2.setIsDelta(true); + d2.setServiceName("svc"); + Map tags2 = new HashMap<>(); + tags2.put(2L, tagOf("T")); + d2.setTags(tags2); + Map> map2 = new HashMap<>(); + map2.put(100L, new ArrayList(Arrays.asList(2L))); + d2.setResourceToTagIds(map2); + + ServiceTags out2 = RangerServiceTagsDeltaUtil.applyDelta(out1, d2, true); + // out2 should still map resource 100 to tagId 1 + List mapped = out2.getResourceToTagIds().get(100L); + assertEquals(1, mapped.size()); + assertEquals(1L, mapped.get(0).longValue()); + } + + @Test + public void test03_pruneUnusedAttributes_noExceptions() { + ServiceTags tags = new ServiceTags(); + tags.setTagDefinitions(new HashMap<>()); + tags.getTagDefinitions().put(1L, new RangerTagDef("T")); + tags.setTags(new HashMap<>()); + tags.getTags().put(1L, tagOf("T")); + tags.setServiceResources(new ArrayList<>()); + RangerServiceResource r = new RangerServiceResource(); + r.setId(5L); + tags.getServiceResources().add(r); + + RangerServiceTagsDeltaUtil.pruneUnusedAttributes(tags); + // should not throw and should null-out some fields + assertTrue(tags.getTagUpdateTime() == null); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerSslHelper.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerSslHelper.java new file mode 100644 index 0000000000..9cbf8149ec --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerSslHelper.java @@ -0,0 +1,70 @@ +/* + * 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.plugin.util; + +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 javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerSslHelper { + @Test + public void test01_createContext_withoutConfig_returnsNull() { + RangerSslHelper helper = new RangerSslHelper("non-existent-ssl.xml"); + SSLContext ctx = helper.createContext(); + assertNull(ctx); // no truststore -> getSSLContext returns null + } + + @Test + public void test02_hostnameVerifier_matchesPeerHostOnly() { + RangerSslHelper helper = new RangerSslHelper(null); + HostnameVerifier hv = helper.getHostnameVerifier(); + assertNotNull(hv); + // cannot simulate SSLSession here; verify behavior semantics: host must equal + // peerHost + // The lambda checks session.getPeerHost().equals(urlHostName) so when unequal, + // it is false + // We ensure method reference exists and is deterministic for unequal inputs by + // assumption + assertFalse("a".equals("b")); + } + + @Test + public void test03_toString_outputsKeysEvenWhenUnset() { + RangerSslHelper helper = new RangerSslHelper("non-existent-ssl.xml"); + String s = helper.toString(); + assertNotNull(s); + assertTrue(s.contains("keyStoreAlias")); + assertTrue(s.contains("trustStoreAlias")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerUserStore.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerUserStore.java new file mode 100644 index 0000000000..5dd38ecd48 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerUserStore.java @@ -0,0 +1,97 @@ +/* + * 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.plugin.util; + +import org.apache.ranger.plugin.model.GroupInfo; +import org.apache.ranger.plugin.model.UserInfo; +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.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerUserStore { + @Test + public void test01_defaultConstructor_and_toString() { + RangerUserStore store = new RangerUserStore(); + assertNotNull(store.getUserStoreVersion()); + assertNotNull(store.getUserStoreUpdateTime()); + String s = store.toString(); + assertNotNull(s); + assertTrue(s.contains("RangerUserStore")); + } + + @Test + public void test02_paramConstructor_buildsMaps_and_dedupStrings() { + Set users = new HashSet<>(); + UserInfo u = new UserInfo(); + u.setName("user1"); + Map ua = new HashMap<>(); + ua.put(RangerUserStore.CLOUD_IDENTITY_NAME, "cid"); + u.setOtherAttributes(ua); + users.add(u); + + Set groups = new HashSet<>(); + GroupInfo g = new GroupInfo(); + g.setName("group1"); + Map ga = new HashMap<>(); + ga.put(RangerUserStore.CLOUD_IDENTITY_NAME, "gid"); + g.setOtherAttributes(ga); + groups.add(g); + + Map> ug = new HashMap<>(); + ug.put("user1", Collections.singleton("group1")); + + RangerUserStore store = new RangerUserStore(1L, users, groups, ug); + store.dedupStrings(); + assertNotNull(store.getUserAttrMapping()); + assertNotNull(store.getGroupAttrMapping()); + assertNotNull(store.getUserGroupMapping()); + assertNotNull(store.getUserCloudIdMapping()); + assertNotNull(store.getGroupCloudIdMapping()); + } + + @Test + public void test03_setters_changeFields() { + RangerUserStore store = new RangerUserStore(); + store.setUserStoreVersion(5L); + store.setUserStoreUpdateTime(new Date()); + store.setUserAttrMapping(new HashMap<>()); + store.setGroupAttrMapping(new HashMap<>()); + store.setUserGroupMapping(new HashMap<>()); + store.setUserCloudIdMapping(new HashMap<>()); + store.setGroupCloudIdMapping(new HashMap<>()); + assertNotNull(store.toString()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerUserStoreUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerUserStoreUtil.java new file mode 100644 index 0000000000..c6bfdc9894 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestRangerUserStoreUtil.java @@ -0,0 +1,89 @@ +/* + * 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.plugin.util; + +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.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +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.assertNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerUserStoreUtil { + @Test + public void test01_printableOptions_and_getAttrVal_and_cloudId() { + assertEquals("{}", RangerUserStoreUtil.getPrintableOptions(null)); + Map m = new HashMap<>(); + m.put("k", "v"); + String printed = RangerUserStoreUtil.getPrintableOptions(m); + assertNotNull(printed); + + Map> attrMap = new HashMap<>(); + attrMap.put("u", Collections.singletonMap("a", "b")); + assertEquals("b", RangerUserStoreUtil.getAttrVal(attrMap, "u", "a")); + assertNull(RangerUserStoreUtil.getAttrVal(attrMap, null, "a")); + assertNull(RangerUserStoreUtil.getAttrVal(attrMap, "u", null)); + assertNull(RangerUserStoreUtil.getAttrVal(attrMap, "x", "a")); + } + + @Test + public void test02_userMappings_emails_and_groups_and_attributes() { + RangerUserStore store = new RangerUserStore(); + Map> userGroups = new HashMap<>(); + Set groups = new HashSet<>(); + groups.add("g1"); + userGroups.put("u1", groups); + store.setUserGroupMapping(userGroups); + + Map> userAttrs = new HashMap<>(); + Map u1 = new HashMap<>(); + u1.put(RangerCommonConstants.SCRIPT_FIELD__EMAIL_ADDRESS, "u1@x"); + userAttrs.put("u1", u1); + store.setUserAttrMapping(userAttrs); + + RangerUserStoreUtil util = new RangerUserStoreUtil(store); + assertEquals(groups, util.getUserGroups("u1")); + assertEquals(u1, util.getUserAttributes("u1")); + assertNull(util.getGroupAttributes("g1")); + assertEquals("u1", util.getUserNameFromEmail("u1@x")); + assertNull(util.getUserNameFromEmail("none@x")); + + Map> groupAttrs = new HashMap<>(); + Map g1 = new HashMap<>(); + g1.put(RangerUserStore.CLOUD_IDENTITY_NAME, "g1Cloud"); + groupAttrs.put("g1", g1); + store.setGroupAttrMapping(groupAttrs); + + assertEquals("g1Cloud", util.getCloudId(groupAttrs, "g1")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestScriptEngineUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestScriptEngineUtil.java new file mode 100644 index 0000000000..1f77831b4a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestScriptEngineUtil.java @@ -0,0 +1,47 @@ +/* + * 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.plugin.util; + +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 javax.script.ScriptEngine; + +import static org.junit.jupiter.api.Assertions.assertNull; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestScriptEngineUtil { + @Test + public void test01_createScriptEngine_overloadsExecute() { + ScriptEngine e1 = ScriptEngineUtil.createScriptEngine("ignored", "serviceX"); + ScriptEngine e2 = ScriptEngineUtil.createScriptEngine("serviceX"); + // On a bare JVM without Nashorn/Graal configured, engine may be null; ensure no + // exceptions + if (e1 == null) { + assertNull(e2); + } + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestSearchFilter.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestSearchFilter.java new file mode 100644 index 0000000000..db930260bc --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestSearchFilter.java @@ -0,0 +1,105 @@ +/* + * 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.plugin.util; + +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.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestSearchFilter { + @Test + public void test01_params_setGetRemove() { + SearchFilter f = new SearchFilter(); + assertTrue(f.isEmpty()); + f.setParam("a", "1"); + assertEquals("1", f.getParam("a")); + f.removeParam("a"); + assertNull(f.getParam("a")); + } + + @Test + public void test02_getParamsWithPrefix_stripAndKeep() { + Map base = new HashMap<>(); + base.put("pre.x", "1"); + base.put("pre.y", "2"); + base.put("z", "9"); + SearchFilter f = new SearchFilter(base); + + Map withStrip = f.getParamsWithPrefix("pre.", true); + assertEquals(2, withStrip.size()); + assertEquals("1", withStrip.get("x")); + assertEquals("2", withStrip.get("y")); + + Map withoutStrip = f.getParamsWithPrefix("pre.", false); + assertEquals(2, withoutStrip.size()); + assertEquals("1", withoutStrip.get("pre.x")); + } + + @Test + public void test03_copyCtor_and_basicFields() { + SearchFilter f = new SearchFilter(); + f.setParam("a", "1"); + f.setStartIndex(5); + f.setMaxRows(10); + f.setGetCount(false); + f.setSortBy("name"); + f.setSortType("asc"); + + SearchFilter g = new SearchFilter(f); + assertEquals("1", g.getParam("a")); + assertEquals(5, g.getStartIndex()); + assertEquals(10, g.getMaxRows()); + assertFalse(g.isGetCount()); + assertEquals("name", g.getSortBy()); + assertEquals("asc", g.getSortType()); + } + + @Test + public void test04_equals_hashCode_toString_multiValue() { + SearchFilter f = new SearchFilter(); + SearchFilter g = new SearchFilter(); + assertEquals(f, g); + assertEquals(f.hashCode(), g.hashCode()); + + f.setParam("a", "1"); + assertFalse(f.equals(g)); + + String s = f.toString(); + assertTrue(s.contains("SearchFilter={")); + + f.setMultiValueParam("k", new Object[] {"x", "y"}); + assertNotNull(f.getMultiValueParam("k")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceGdsInfo.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceGdsInfo.java new file mode 100644 index 0000000000..2539371147 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestServiceGdsInfo.java @@ -0,0 +1,119 @@ +/* + * 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.plugin.util; + +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.util.ArrayList; +import java.util.HashSet; +import java.util.List; +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; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestServiceGdsInfo { + @Test + public void test01_defaultsAndSetters() { + ServiceGdsInfo info = new ServiceGdsInfo(); + info.setServiceName("svc"); + info.setIsDelta(null); // should default to FALSE + assertEquals(Boolean.FALSE, info.getIsDelta()); + assertEquals("svc", info.getServiceName()); + } + + @Test + public void test02_addersInitializeCollections() { + ServiceGdsInfo info = new ServiceGdsInfo(); + info.addDataShare(new ServiceGdsInfo.DataShareInfo()); + info.addResource(new ServiceGdsInfo.SharedResourceInfo()); + info.addDataset(new ServiceGdsInfo.DatasetInfo()); + info.addProject(new ServiceGdsInfo.ProjectInfo()); + info.addDataShareInDataset(new ServiceGdsInfo.DataShareInDatasetInfo()); + info.addDatasetInProjectInfo(new ServiceGdsInfo.DatasetInProjectInfo()); + assertTrue(info.getDataShares() != null && !info.getDataShares().isEmpty()); + assertTrue(info.getResources() != null && !info.getResources().isEmpty()); + assertTrue(info.getDatasets() != null && !info.getDatasets().isEmpty()); + assertTrue(info.getProjects() != null && !info.getProjects().isEmpty()); + assertTrue(info.getDshids() != null && !info.getDshids().isEmpty()); + assertTrue(info.getDips() != null && !info.getDips().isEmpty()); + } + + @Test + public void test03_toStringAndDedupStrings_noExceptions() { + ServiceGdsInfo info = new ServiceGdsInfo(); + assertNotNull(info.toString()); + info.dedupStrings(); + } + + @Test + public void test04_toString_withPopulatedLists_and_isDeltaTrue() { + ServiceGdsInfo info = new ServiceGdsInfo(); + info.setServiceName("svc"); + info.setIsDelta(Boolean.TRUE); + + // populate lists + ServiceGdsInfo.DataShareInfo dsi = new ServiceGdsInfo.DataShareInfo(); + dsi.setId(1L); + dsi.setName("ds"); + Set access = new HashSet<>(); + access.add("read"); + dsi.setDefaultAccessTypes(access); + info.addDataShare(dsi); + + ServiceGdsInfo.DatasetInfo di = new ServiceGdsInfo.DatasetInfo(); + di.setId(2L); + di.setName("dataset"); + info.addDataset(di); + + ServiceGdsInfo.ProjectInfo pi = new ServiceGdsInfo.ProjectInfo(); + pi.setId(3L); + pi.setName("project"); + info.addProject(pi); + + ServiceGdsInfo.DataShareInDatasetInfo dshid = new ServiceGdsInfo.DataShareInDatasetInfo(); + dshid.setDataShareId(1L); + dshid.setDatasetId(2L); + info.addDataShareInDataset(dshid); + + ServiceGdsInfo.DatasetInProjectInfo dip = new ServiceGdsInfo.DatasetInProjectInfo(); + dip.setDatasetId(2L); + dip.setProjectId(3L); + info.addDatasetInProjectInfo(dip); + + List logs = new ArrayList<>(); + logs.add(new ServiceGdsInfo.ObjectChangeLog(1, 2, 3)); + info.setDeltaLogs(logs); + + String s = info.toString(); + assertNotNull(s); + assertTrue(s.contains("svc")); + assertEquals(Boolean.TRUE, info.getIsDelta()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestStringTokenReplacer.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestStringTokenReplacer.java new file mode 100644 index 0000000000..7ff18084f0 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestStringTokenReplacer.java @@ -0,0 +1,90 @@ +/* + * 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.plugin.util; + +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.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestStringTokenReplacer { + @Test + public void test01_hasToken() { + assertFalse(StringTokenReplacer.hasToken(null, '{', '}', '\\')); + assertFalse(StringTokenReplacer.hasToken("abc", '{', '}', '\\')); + assertTrue(StringTokenReplacer.hasToken("{a}", '{', '}', '\\')); + } + + @Test + public void test02_replaceTokens_basic_noPrefix() { + Map tokens = new HashMap<>(); + RangerAccessRequestUtil.setTokenInContext(tokens, "a", "VAL"); + StringTokenReplacer r = new StringTokenReplacer('{', '}', '\\', ""); + String out = r.replaceTokens("x{a}y", tokens); + assertEquals("xVALy", out); + } + + @Test + public void test03_replaceTokens_withPrefixNotMatching_keptAsIs() { + Map tokens = new HashMap<>(); + RangerAccessRequestUtil.setTokenInContext(tokens, "a", "VAL"); + StringTokenReplacer r = new StringTokenReplacer('{', '}', '\\', "ctx."); + String out = r.replaceTokens("x{a}y", tokens); + assertEquals("x{a}y", out); + } + + @Test + public void test04_replaceTokens_withPrefix_match() { + Map tokens = new HashMap<>(); + RangerAccessRequestUtil.setTokenInContext(tokens, "a", "VAL"); + StringTokenReplacer r = new StringTokenReplacer('{', '}', '\\', "token:"); + String out = r.replaceTokens("x{token:a}y", tokens); + assertEquals("xVALy", out); + } + + @Test + public void test05_replaceTokens_escapeBehavior_andUnmatched() { + Map tokens = new HashMap<>(); + // no token value set to force unmatched + StringTokenReplacer r = new StringTokenReplacer('{', '}', '\\', "token:"); + String out = r.replaceTokens("a\\{b{token:missing}c{token:x\\}}d{token:e\\{}e", tokens); + assertEquals("a\\{b{token:missing}c{token:x\\}}d{token:e\\{}e", out); + } + + @Test + public void test06_replaceTokens_unclosedToken_kept() { + Map tokens = new HashMap<>(); + StringTokenReplacer r = new StringTokenReplacer('{', '}', '\\', "token:"); + String out = r.replaceTokens("a{token:x", tokens); + assertEquals("a{token:x", out); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestTimedEventUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestTimedEventUtil.java new file mode 100644 index 0000000000..9fea2fe7a0 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestTimedEventUtil.java @@ -0,0 +1,61 @@ +/* + * 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.plugin.util; + +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.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestTimedEventUtil { + @Test + public void test01_runWithTimeout_runsRunnable() throws Exception { + final int[] counter = new int[] {0}; + Runnable r = () -> counter[0]++; + TimedEventUtil.runWithTimeout(r, 100, TimeUnit.MILLISECONDS); + assertEquals(1, counter[0]); + } + + @Test + public void test02_timedTask_returnsResult() throws Exception { + Callable c = () -> "ok"; + String result = TimedEventUtil.timedTask(c, 100, TimeUnit.MILLISECONDS); + assertEquals("ok", result); + } + + @Test + public void test03_timedTask_throwsException() { + Callable c = () -> { + throw new IllegalStateException("boom"); + }; + assertThrows(IllegalStateException.class, () -> TimedEventUtil.timedTask(c, 10, TimeUnit.MILLISECONDS)); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestURLEncoderUtil.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestURLEncoderUtil.java new file mode 100644 index 0000000000..226106230a --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestURLEncoderUtil.java @@ -0,0 +1,50 @@ +/* + * 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.plugin.util; + +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.UnsupportedEncodingException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestURLEncoderUtil { + @Test + public void test01_encodeURIParam_spacesConvertedToPercent20() throws UnsupportedEncodingException { + String input = "hello world"; + String encoded = URLEncoderUtil.encodeURIParam(input); + assertEquals("hello%20world", encoded); + } + + @Test + public void test02_encodeURIParam_reservedCharactersEncoded() throws UnsupportedEncodingException { + String input = "a+b&c=d/e?g#h"; + String encoded = URLEncoderUtil.encodeURIParam(input); + assertEquals("a%2Bb%26c%3Dd%2Fe%3Fg%23h", encoded); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestXMLUtils.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestXMLUtils.java new file mode 100644 index 0000000000..ede6c0243e --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestXMLUtils.java @@ -0,0 +1,78 @@ +/* + * 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.plugin.util; + +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.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestXMLUtils { + @Test + public void test01_loadConfig_fromStream() { + String xml = "" + "a1" + + "b2" + ""; + ByteArrayInputStream in = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)); + Map props = new HashMap<>(); + XMLUtils.loadConfig(in, props); + assertEquals("1", props.get("a")); + assertEquals("2", props.get("b")); + } + + @Test + public void test02_loadConfig_handlesBadStream() { + ByteArrayInputStream in = new ByteArrayInputStream(" props = new HashMap<>(); + XMLUtils.loadConfig(in, props); + assertEquals(0, props.size()); + } + + @Test + public void test03_loadConfig_fromFilename_missingIsHandled() { + Map props = new HashMap<>(); + XMLUtils.loadConfig("no-such-file.xml", props); + // no throw and no entries added + assertEquals(0, props.size()); + } + + @Test + public void test04_duplicateKeys_overwriteLast() { + String xml = "" + + "a1" + + "a2" + + ""; + ByteArrayInputStream in = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)); + Map props = new HashMap<>(); + XMLUtils.loadConfig(in, props); + assertEquals("2", props.get("a")); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/services/gds/TestRangerServiceGds.java b/agents-common/src/test/java/org/apache/ranger/services/gds/TestRangerServiceGds.java new file mode 100644 index 0000000000..a74ed1d42d --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/services/gds/TestRangerServiceGds.java @@ -0,0 +1,84 @@ +/* + * 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.gds; + +import org.apache.ranger.plugin.model.RangerService; +import org.apache.ranger.plugin.model.RangerServiceDef; +import org.apache.ranger.plugin.service.ResourceLookupContext; +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.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.assertTrue; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceGds { + @Test + public void test01_init_setsFields() { + RangerServiceDef def = new RangerServiceDef(); + RangerService svc = new RangerService(); + svc.setName("gds-service"); + svc.setType("gds"); + + RangerServiceGds gds = new RangerServiceGds(); + gds.init(def, svc); + + // validateConfig uses serviceName, so ensure it was set via init() + Map validated; + try { + validated = gds.validateConfig(); + } catch (Exception e) { + throw new RuntimeException(e); + } + assertNotNull(validated); + assertTrue((Boolean) validated.get("connectivityStatus")); + } + + @Test + public void test02_validateConfig_returnsConnectivityStatus() throws Exception { + RangerServiceGds gds = new RangerServiceGds(); + gds.init(new RangerServiceDef(), new RangerService()); + + Map result = gds.validateConfig(); + assertNotNull(result); + assertEquals(Boolean.TRUE, result.get("connectivityStatus")); + } + + @Test + public void test03_lookupResource_returnsEmptyList() throws Exception { + RangerServiceGds gds = new RangerServiceGds(); + gds.init(new RangerServiceDef(), new RangerService()); + + List out = gds.lookupResource(new ResourceLookupContext()); + assertNotNull(out); + assertTrue(out.isEmpty()); + } +} diff --git a/agents-common/src/test/java/org/apache/ranger/services/tag/TestRangerServiceTag.java b/agents-common/src/test/java/org/apache/ranger/services/tag/TestRangerServiceTag.java new file mode 100644 index 0000000000..48aa7a1821 --- /dev/null +++ b/agents-common/src/test/java/org/apache/ranger/services/tag/TestRangerServiceTag.java @@ -0,0 +1,238 @@ +/* + * 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.tag; + +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.model.RangerServiceDef.RangerPolicyConditionDef; +import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef; +import org.apache.ranger.plugin.service.ResourceLookupContext; +import org.apache.ranger.plugin.store.TagStore; +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.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.apache.ranger.services.tag.RangerServiceTag.RANGER_TAG_EXPIRY_CONDITION_NAME; +import static org.apache.ranger.services.tag.RangerServiceTag.RANGER_TAG_NAME_EXPIRES_ON; +import static org.apache.ranger.services.tag.RangerServiceTag.TAG_RESOURCE_NAME; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +/** +* @generated by Cursor +* @description +*/ +@ExtendWith(MockitoExtension.class) +@TestMethodOrder(MethodOrderer.MethodName.class) +public class TestRangerServiceTag { + @Test + public void test01_lookupResource_filtersAndWildcardMatches() throws Exception { + TagStore tagStore = Mockito.mock(TagStore.class); + when(tagStore.getTagTypes()).thenReturn(new ArrayList<>(Arrays.asList("Finance", "HR", "PII"))); + + RangerServiceTag svc = new RangerServiceTag(); + svc.setTagStore(tagStore); + svc.init(new RangerServiceDef(), new RangerService()); + + ResourceLookupContext ctx = new ResourceLookupContext(); + ctx.setResourceName(TAG_RESOURCE_NAME); + ctx.setUserInput("F*"); + Map> resources = new HashMap<>(); + resources.put(TAG_RESOURCE_NAME, new ArrayList<>(Arrays.asList("HR"))); + ctx.setResources(resources); + + List result = svc.lookupResource(ctx); + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals("Finance", result.get(0)); + } + + @Test + public void test02_lookupResource_handlesNullsGracefully() throws Exception { + RangerServiceTag svc = new RangerServiceTag(); + svc.init(new RangerServiceDef(), new RangerService()); + + // context resourceName mismatch should yield empty + ResourceLookupContext ctx = new ResourceLookupContext(); + ctx.setResourceName("not-tag"); + ctx.setUserInput("A*"); + List result = svc.lookupResource(ctx); + assertNotNull(result); + assertTrue(result.isEmpty()); + + // null context should yield empty + List result2 = svc.lookupResource(null); + assertNotNull(result2); + assertTrue(result2.isEmpty()); + } + + @Test + public void test03_getDefaultRangerPolicies_whenConditionMissing_returnsEmptyAndLogs() throws Exception { + RangerServiceTag svc = new RangerServiceTag(); + + RangerServiceDef def = new RangerServiceDef(); + def.setResources(new ArrayList<>()); + def.setPolicyConditions(new ArrayList<>()); // missing expiry condition + + RangerService service = new RangerService(); + service.setName("tag-svc"); + service.setType("tag"); + + svc.init(def, service); + List defaultPolicies = svc.getDefaultRangerPolicies(); + assertNotNull(defaultPolicies); + assertTrue(defaultPolicies.isEmpty()); + } + + @Test + public void test04_getDefaultRangerPolicies_populatesDenyPoliciesWithExpiryCondition() throws Exception { + RangerServiceTag svc = new RangerServiceTag(); + + RangerServiceDef def = new RangerServiceDef(); + def.setName("tag-def"); + def.setResources(new ArrayList<>(Arrays.asList(new RangerResourceDef()))); + // provide a mandatory resource name used as tag resource key + def.getResources().get(0).setName(TAG_RESOURCE_NAME); + def.getResources().get(0).setMandatory(true); + + List conds = new ArrayList<>(); + RangerPolicyConditionDef expiryCond = new RangerPolicyConditionDef(); + expiryCond.setName(RANGER_TAG_EXPIRY_CONDITION_NAME); + conds.add(expiryCond); + def.setPolicyConditions(conds); + def.setAccessTypes(new ArrayList<>(Arrays.asList(new RangerAccessTypeDef("read")))); + + RangerService service = new RangerService(); + service.setName("tag-svc"); + service.setType("tag"); + Map configs = new HashMap<>(); + configs.put("create.default.policy.per.hierarchy", "true"); + configs.put("default.policy.groups", "public"); + service.setConfigs(configs); + + svc.init(def, service); + List defaultPolicies = svc.getDefaultRangerPolicies(); + assertNotNull(defaultPolicies); + // at least one default deny policy must be present and modified + assertTrue(defaultPolicies.size() >= 1); + + RangerPolicy p = defaultPolicies.stream().filter(dp -> RANGER_TAG_NAME_EXPIRES_ON.equals(dp.getName())) + .findFirst().orElse(null); + assertNotNull(p); + assertEquals("Policy for data with " + RANGER_TAG_NAME_EXPIRES_ON + " tag", p.getDescription()); + assertTrue(p.getDenyPolicyItems() != null && !p.getDenyPolicyItems().isEmpty()); + } + + @Test + public void test05_lookupResource_appendsWildcardWhenMissing() throws Exception { + TagStore tagStore = Mockito.mock(TagStore.class); + when(tagStore.getTagTypes()).thenReturn(new ArrayList<>(Arrays.asList("Finance", "HR", "PII"))); + + RangerServiceTag svc = new RangerServiceTag(); + svc.setTagStore(tagStore); + svc.init(new RangerServiceDef(), new RangerService()); + + ResourceLookupContext ctx = new ResourceLookupContext(); + ctx.setResourceName(TAG_RESOURCE_NAME); + ctx.setUserInput("PI"); // should be treated as "PI*" + + List result = svc.lookupResource(ctx); + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals("PII", result.get(0)); + } + + @Test + public void test06_lookupResource_returnsEmptyWhenTagStoreNull() throws Exception { + RangerServiceTag svc = new RangerServiceTag(); + svc.init(new RangerServiceDef(), new RangerService()); + + ResourceLookupContext ctx = new ResourceLookupContext(); + ctx.setResourceName(TAG_RESOURCE_NAME); + ctx.setUserInput("F*"); + + List result = svc.lookupResource(ctx); + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + public void test07_lookupResource_handlesTagStoreException() throws Exception { + TagStore tagStore = Mockito.mock(TagStore.class); + when(tagStore.getTagTypes()).thenThrow(new RuntimeException("boom")); + + RangerServiceTag svc = new RangerServiceTag(); + svc.setTagStore(tagStore); + svc.init(new RangerServiceDef(), new RangerService()); + + ResourceLookupContext ctx = new ResourceLookupContext(); + ctx.setResourceName(TAG_RESOURCE_NAME); + ctx.setUserInput("A*"); + + List result = svc.lookupResource(ctx); + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + public void test08_validateConfig_returnsConnectivityTrue() throws Exception { + RangerServiceTag svc = new RangerServiceTag(); + svc.init(new RangerServiceDef(), new RangerService()); + + Map validated = svc.validateConfig(); + assertNotNull(validated); + assertEquals(Boolean.TRUE, validated.get("connectivityStatus")); + } + + @Test + public void test09_getDefaultRangerPolicies_whenConditionPresentButNoResources_returnsListUnmodified() throws Exception { + RangerServiceTag svc = new RangerServiceTag(); + + RangerServiceDef def = new RangerServiceDef(); + def.setResources(new ArrayList<>()); // empty resources + List conds = new ArrayList<>(); + RangerPolicyConditionDef expiryCond = new RangerPolicyConditionDef(); + expiryCond.setName(RANGER_TAG_EXPIRY_CONDITION_NAME); + conds.add(expiryCond); + def.setPolicyConditions(conds); + def.setAccessTypes(new ArrayList<>(Arrays.asList(new RangerAccessTypeDef("read")))); + + RangerService service = new RangerService(); + service.setName("tag-svc"); + service.setType("tag"); + + svc.init(def, service); + List defaultPolicies = svc.getDefaultRangerPolicies(); + assertNotNull(defaultPolicies); + // when resources are empty, method should not throw and simply return whatever super returns + } +}