Copilot commented on code in PR #699:
URL: https://github.com/apache/ranger/pull/699#discussion_r2418207373


##########
authz-api/src/test/java/org/apache/ranger/authz/util/TestRangerResourceNameParser.java:
##########
@@ -0,0 +1,407 @@
+/*
+ * 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.authz.util;
+
+import org.apache.ranger.authz.api.RangerAuthzErrorCode;
+import org.apache.ranger.authz.api.RangerAuthzException;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TYPE_NOT_VALID;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
+
+public class TestRangerResourceNameParser {
+    @Test
+    public void testValidTemplates() throws Exception {
+        Object[][] testData = {
+                { "database", "database", 1, "database" },
+                { "database/table", "table", 2, "database", "table" },
+                { "database/table/column", "column", 3, "database", "table", 
"column" },
+                { "bucket", "bucket", 1, "bucket" },
+                { "bucket/path", "path", 2, "bucket", "path" },
+                { "storageaccount", "storageaccount", 1, "storageaccount" },
+                { "storageaccount/container", "container", 2, 
"storageaccount", "container" },
+                { "storageaccount/container/relativepath", "relativepath", 3, 
"storageaccount", "container", "relativepath" },
+                { "catalog", "catalog", 1, "catalog" },
+                { "catalog/schema", "schema", 2, "catalog", "schema" },
+                { "catalog/schema/table", "table", 3, "catalog", "schema", 
"table" },
+                { "catalog/schema/table/column", "column", 4, "catalog", 
"schema", "table", "column" },
+                { "catalog/schema/procedure", "procedure", 3, "catalog", 
"schema", "procedure" },
+                { "catalog/schema/schemafunction", "schemafunction", 3, 
"catalog", "schema", "schemafunction" },
+                { "catalog/sessionproperty", "sessionproperty", 2, "catalog", 
"sessionproperty" },
+        };
+
+        for (Object[] test : testData) {
+            String               template         = (String) test[0];
+            String               resourceType     = (String) test[1];
+            int                      resourceCount    = (Integer) test[2];
+            RangerResourceNameParser resourceTemplate = new 
RangerResourceNameParser(template);
+
+            assertEquals(resourceType, resourceTemplate.getResourceType(), 
template);
+            assertEquals(resourceCount, resourceTemplate.count(), template);
+            assertEquals(template, resourceTemplate.getTemplate(), template);
+
+            for (int i = 0; i < resourceCount; i++) {
+                assertEquals(test[i + 3], resourceTemplate.resourceAt(i), 
template + " at " + i);
+            }
+        }
+    }
+
+    @Test
+    public void testInvalidTemplates() throws Exception {
+        String[] templates = {
+                null,
+                "",
+                "  ",
+        };
+
+        for (String template : templates) {
+            RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> new 
RangerResourceNameParser(template), template);
+
+            assertEquals(INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE.getCode(), 
excp.getErrorCode().getCode(), template);
+        }
+    }
+
+    @Test
+    public void testParseHiveResources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getHiveTemplates();
+
+        TestData[] tests = {
+                new TestData("database:db1", "database", "db1"),
+                new TestData("database:db1/", "database", "db1/"),
+                new TestData("table:db1/tbl1", "database", "db1", "table", 
"tbl1"),
+                new TestData("table:db\\/1/tbl1", "database", "db/1", "table", 
"tbl1"), // escape '/' in database name "db/1"
+                new TestData("column:db1/tbl1/col1", "database", "db1", 
"table", "tbl1", "column", "col1"),
+                new TestData("column:db1//col1", "database", "db1", "table", 
"", "column", "col1"), // empty table name
+                new TestData("column:db1//", "database", "db1", "table", "", 
"column", ""), // empty table and column names
+                new TestData("column://", "database", "", "table", "", 
"column", ""), // empty database, table and column names
+                new TestData("udf:db1/myUDF", "database", "db1", "udf", 
"myUDF"),
+                new TestData("url:s3a://mybucket/db1/tbl1", "url", 
"s3a://mybucket/db1/tbl1"),
+                new TestData("hiveservice:server1", "hiveservice", "server1"),
+                new TestData("global:*", "global", "*"),
+                // invalid values
+                new TestData("db1/tbl1/col1", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
+                new TestData(":db1/tbl1/col1", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
+                new TestData("invalidResourceType:db1/tbl1/col1", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
+                new TestData("database:", INVALID_RESOURCE_EMPTY_VALUE),
+                new TestData("table:db1_tbl1", INVALID_RESOURCE_VALUE),
+                new TestData("column:db1_tbl1/col1", INVALID_RESOURCE_VALUE),
+                new TestData("udf:db1_myUDF", INVALID_RESOURCE_VALUE),
+        };
+
+        for (TestData test : tests) {
+            if (test.errorCode != null) {
+                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> parseToMap(test.resource, 
templates), test.resource);
+
+                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
+            } else {
+                assertEquals(test.expected, parseToMap(test.resource, 
templates), test.resource);
+            }
+        }
+    }
+
+    @Test
+    public void testParseS3Resources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getS3Templates();
+
+        TestData[] tests = {
+                new TestData("bucket:mybucket", "bucket", "mybucket"),
+                new TestData("path:mybucket/myfolder/myfile.txt", "bucket", 
"mybucket", "path", "myfolder/myfile.txt"),    // no escape needed for '/' in 
the last resource
+                new TestData("path:mybucket/myfolder\\/myfile.txt", "bucket", 
"mybucket", "path", "myfolder/myfile.txt"),  // escape in the last resource 
should be ignored
+                new TestData("path:mybucket/\\/myfolder/myfile.txt", "bucket", 
"mybucket", "path", "/myfolder/myfile.txt"), // escape in the last resource 
should be ignored
+                new TestData("path:mybucket/", "bucket", "mybucket", "path", 
""),
+                // invalid values
+                new TestData("mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
+                new TestData(":mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
+                new 
TestData("invalidResourceType:mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
+                new TestData("bucket:", INVALID_RESOURCE_EMPTY_VALUE),
+                new TestData("path:mybucket_myfolder_myfile.txt", 
INVALID_RESOURCE_VALUE),
+        };
+
+        for (TestData test : tests) {
+            if (test.errorCode != null) {
+                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> parseToMap(test.resource, 
templates), test.resource);
+
+                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
+            } else {
+                assertEquals(test.expected, parseToMap(test.resource, 
templates), test.resource);
+            }
+        }
+    }
+
+    @Test
+    public void testParseAdlsGen2Resources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = 
getAdlsGen2Templates();
+
+        TestData[] tests = {
+                new TestData("container:mycontainer/myaccount", 
"storageaccount", "myaccount", "container", "mycontainer"),
+                new 
TestData("relativepath:mycontainer/myaccount/p1/p2/f1.txt", "storageaccount", 
"myaccount", "container", "mycontainer", "relativepath", "p1/p2/f1.txt"),

Review Comment:
   The test data suggests that the storageaccount and container order in the 
resource name is reversed compared to the template definition. The template is 
'container/storageaccount' but the test expects 'mycontainer/myaccount' to map 
to storageaccount='myaccount' and container='mycontainer'. This inconsistency 
could confuse API consumers.
   ```suggestion
                   new TestData("container:myaccount/mycontainer", 
"storageaccount", "myaccount", "container", "mycontainer"),
                   new 
TestData("relativepath:myaccount/mycontainer/p1/p2/f1.txt", "storageaccount", 
"myaccount", "container", "mycontainer", "relativepath", "p1/p2/f1.txt"),
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to