You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by es...@apache.org on 2017/02/03 09:00:43 UTC

[41/50] [abbrv] incubator-hawq git commit: HAWQ-1281. Refactored RPS integration tests

HAWQ-1281. Refactored RPS integration tests

(closes #1100)


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/8a5e65bf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/8a5e65bf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/8a5e65bf

Branch: refs/heads/2.1.0.0-incubating
Commit: 8a5e65bffc52f6c36c0813ecd1825631fac3acba
Parents: eb2ea90
Author: Alexander Denissov <ad...@pivotal.io>
Authored: Fri Jan 20 11:19:40 2017 -0800
Committer: Alexander Denissov <ad...@pivotal.io>
Committed: Wed Jan 25 09:56:05 2017 -0800

----------------------------------------------------------------------
 .../integration/service/tests/DatabaseTest.java |  66 ++++----
 .../integration/service/tests/FunctionTest.java | 111 +++++++------
 .../integration/service/tests/LanguageTest.java |  96 +++++------
 .../integration/service/tests/ProtocolTest.java |  61 +++----
 .../integration/service/tests/RPSRequest.java   |  60 -------
 .../integration/service/tests/RPSResponse.java  |  42 -----
 .../integration/service/tests/SchemaTest.java   |  95 +++++++++++
 .../integration/service/tests/SequenceTest.java |  97 +++++++++++
 .../service/tests/ServiceBaseTest.java          | 116 -------------
 .../service/tests/SpecialPrivilegesTest.java    |  95 +++++++++++
 .../integration/service/tests/TableTest.java    |  96 +++++++++++
 .../service/tests/TablespaceTest.java           |  61 +++----
 .../ranger/integration/service/tests/Utils.java |  76 ---------
 .../tests/common/ComplexResourceTestBase.java   |  40 +++++
 .../service/tests/common/Policy.java            | 107 ++++++++++++
 .../service/tests/common/RESTClient.java        | 114 +++++++++++++
 .../service/tests/common/ServiceTestBase.java   | 162 +++++++++++++++++++
 .../tests/common/SimpleResourceTestBase.java    | 114 +++++++++++++
 .../src/test/resources/test-database.json       |  46 ------
 .../src/test/resources/test-function-2.json     |  40 -----
 .../src/test/resources/test-function.json       |  40 -----
 .../src/test/resources/test-language-2.json     |  35 ----
 .../src/test/resources/test-language.json       |  35 ----
 .../src/test/resources/test-protocol.json       |  33 ----
 .../src/test/resources/test-tablespace.json     |  30 ----
 25 files changed, 1107 insertions(+), 761 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
index 451a289..1e6557f 100644
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/DatabaseTest.java
@@ -19,49 +19,43 @@
 
 package org.apache.hawq.ranger.integration.service.tests;
 
-import org.junit.Test;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.apache.hawq.ranger.integration.service.tests.common.SimpleResourceTestBase;
+import org.junit.Before;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.*;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+public class DatabaseTest extends SimpleResourceTestBase {
 
-public class DatabaseTest extends ServiceBaseTest {
+    // create-schema will be requested by HAWQ with only database in context, so it looks like a privilege for database resource
+    private static final String[] SPECIAL_PRIVILEGES = new String[] {"connect", "temp", "create-schema"};
 
-    private static final List<String> PRIVILEGES = Arrays.asList("connect", "temp");
-
-    public void beforeTest()
-            throws IOException {
-        createPolicy("test-database.json");
-        resources.put("database", "sirotan");
-    }
-
-    @Test
-    public void testDatabases_UserMaria_SirotanDb_Allowed()
-            throws IOException {
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Before
+    public void beforeTest() {
+        specificResource.put(database, TEST_DB);
+        unknownResource.put(database, UNKNOWN);
+        privileges = new String[] {"connect", "temp", "create"};
     }
 
-    @Test
-    public void testDatabases_UserMaria_DoesNotExistDb_Denied()
-            throws IOException {
-        resources.put("database", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, STAR)
+                .resource(table, STAR)
+                .userAccess(TEST_USER, SPECIAL_PRIVILEGES)
+                .build();
+        return policy;
     }
 
-    @Test
-    public void testDatabases_UserBob_SirotanDb_Denied()
-            throws IOException {
-        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, STAR)
+                .resource(table, STAR)
+                .groupAccess(PUBLIC_GROUP, SPECIAL_PRIVILEGES)
+                .build();
+        return policy;
     }
-
-    @Test
-    public void testDatabases_UserMaria_SirotanDb_Denied()
-            throws IOException {
-        deletePolicy();
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
index 1253c38..ecdb67b 100644
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/FunctionTest.java
@@ -19,73 +19,78 @@
 
 package org.apache.hawq.ranger.integration.service.tests;
 
-import org.junit.Test;
+import org.apache.hawq.ranger.integration.service.tests.common.ComplexResourceTestBase;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.junit.Before;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.*;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+public class FunctionTest extends ComplexResourceTestBase {
 
-public class FunctionTest extends ServiceBaseTest {
+    @Before
+    public void beforeTest() {
+        specificResource.put(database, TEST_DB);
+        specificResource.put(schema, TEST_SCHEMA);
+        specificResource.put(function, TEST_FUNCTION);
 
-    private static final List<String> PRIVILEGES = Arrays.asList("execute");
+        parentUnknownResource.put(database, TEST_DB);
+        parentUnknownResource.put(schema, UNKNOWN);
+        parentUnknownResource.put(function, TEST_FUNCTION);
 
-    public void beforeTest()
-            throws IOException {
-        createPolicy("test-function.json");
-        resources.put("database", "sirotan");
-        resources.put("schema", "siroschema");
-        resources.put("function", "atan");
-    }
+        childUnknownResource.put(database, TEST_DB);
+        childUnknownResource.put(schema, TEST_SCHEMA);
+        childUnknownResource.put(function, UNKNOWN);
 
-    @Test
-    public void testFunctions_UserMaria_SirotanDb_AtanFunction_Allowed()
-            throws IOException {
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
-    }
+        unknownResource.put(database, UNKNOWN);
+        unknownResource.put(schema, UNKNOWN);
+        unknownResource.put(function, UNKNOWN);
 
-    @Test
-    public void testFunctions_UserMaria_OtherDb_AtanFunction_Denied()
-            throws IOException {
-        resources.put("database", "other");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+        privileges = new String[] {"execute"};
     }
 
-    @Test
-    public void testFunctions_UserMaria_SirotanDb_DoesNotExistFunction_Denied()
-            throws IOException {
-        resources.put("function", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(function, TEST_FUNCTION)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        return policy;
     }
 
-    @Test
-    public void testFunctions_UserBob_SirotanDb_AtanFunction_Denied()
-            throws IOException {
-        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceParentStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, STAR)
+                .resource(function, TEST_FUNCTION)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isParentStar = true;
+        return policy;
     }
 
-    @Test
-    public void testFunctions_UserMaria_SirotanDb_AtanFunction_Denied()
-            throws IOException {
-        deletePolicy();
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceChildStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(function, STAR)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isChildStar = true;
+        return policy;
     }
 
-    @Test
-    public void testFunctions_UserMaria_DoesNotExistDb_AtanFunction_Denied()
-            throws IOException {
-        resources.put("database", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(function, TEST_FUNCTION)
+                .groupAccess(PUBLIC_GROUP, privileges)
+                .build();
+        return policy;
     }
-
-    @Test
-    public void testFunctions_UserMaria_SirotanDb_AtanFunction_Policy2_Allowed()
-            throws IOException {
-        deletePolicy();
-        createPolicy("test-function-2.json");
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java
index 6eedb08..d39a595 100644
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/LanguageTest.java
@@ -19,65 +19,71 @@
 
 package org.apache.hawq.ranger.integration.service.tests;
 
-import org.junit.Test;
+import org.apache.hawq.ranger.integration.service.tests.common.ComplexResourceTestBase;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.junit.Before;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.database;
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.language;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+public class LanguageTest extends ComplexResourceTestBase {
 
-public class LanguageTest extends ServiceBaseTest {
+    @Before
+    public void beforeTest() {
+        specificResource.put(database, TEST_DB);
+        specificResource.put(language, TEST_LANGUAGE);
 
-    private static final List<String> PRIVILEGES = Arrays.asList("usage");
+        parentUnknownResource.put(database, UNKNOWN);
+        parentUnknownResource.put(language, TEST_LANGUAGE);
 
-    public void beforeTest()
-            throws IOException {
-        createPolicy("test-language.json");
-        resources.put("database", "sirotan");
-        resources.put("language", "sql");
-    }
+        childUnknownResource.put(database, TEST_DB);
+        childUnknownResource.put(language, UNKNOWN);
 
-    @Test
-    public void testLanguages_UserMaria_SirotanDb_SqlLanguage_Allowed()
-            throws IOException {
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
-    }
+        unknownResource.put(database, UNKNOWN);
+        unknownResource.put(language, UNKNOWN);
 
-    @Test
-    public void testLanguages_UserMaria_SirotanDb_DoesNotExistLanguage_Denied()
-            throws IOException {
-        resources.put("language", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+        privileges = new String[] {"usage"};
     }
 
-    @Test
-    public void testLanguages_UserBob_SirotanDb_SqlLanguage_Denied()
-            throws IOException {
-        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(language, TEST_LANGUAGE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        return policy;
     }
 
-    @Test
-    public void testLanguages_UserMaria_SirotanDb_SqlLanguage_Denied()
-            throws IOException {
-        deletePolicy();
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceParentStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, STAR)
+                .resource(language, TEST_LANGUAGE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isParentStar = true;
+        return policy;
     }
 
-    @Test
-    public void testLanguages_UserMaria_DoesNotExistDb_SqlLanguage_Denied()
-            throws IOException {
-        resources.put("database", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceChildStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(language, STAR)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isChildStar = true;
+        return policy;
     }
 
-    @Test
-    public void testLanguages_UserMaria_SirotanDb_SqlLanguage_Policy2_Allowed()
-            throws IOException {
-        deletePolicy();
-        createPolicy("test-language-2.json");
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(language, TEST_LANGUAGE)
+                .groupAccess(PUBLIC_GROUP, privileges)
+                .build();
+        return policy;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
index f0e5c99..e67a0d3 100644
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ProtocolTest.java
@@ -19,49 +19,36 @@
 
 package org.apache.hawq.ranger.integration.service.tests;
 
-import org.junit.Test;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.apache.hawq.ranger.integration.service.tests.common.SimpleResourceTestBase;
+import org.junit.Before;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.protocol;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+public class ProtocolTest extends SimpleResourceTestBase {
 
-public class ProtocolTest extends ServiceBaseTest {
-
-    private static final List<String> PRIVILEGES = Arrays.asList("select", "insert");
-
-    public void beforeTest()
-            throws IOException {
-        createPolicy("test-protocol.json");
-        resources.put("protocol", "pxf");
-    }
-
-    @Test
-    public void testProtocols_UserMaria_PxfProtocol_Allowed()
-            throws IOException {
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Before
+    public void beforeTest() {
+        specificResource.put(protocol, TEST_PROTOCOL);
+        unknownResource.put(protocol, UNKNOWN);
+        privileges = new String[] {"select", "insert"};
     }
 
-    @Test
-    public void testProtocols_UserMaria_DoesNotExistProtocol_Denied()
-            throws IOException {
-        resources.put("protocol", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(protocol, TEST_PROTOCOL)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        return policy;
     }
 
-    @Test
-    public void testProtocols_UserBob_PxfProtocol_Denied()
-            throws IOException {
-        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(protocol, TEST_PROTOCOL)
+                .groupAccess(PUBLIC_GROUP, privileges)
+                .build();
+        return policy;
     }
-
-    @Test
-    public void testProtocols_UserMaria_PxfProtocol_Denied()
-            throws IOException {
-        deletePolicy();
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java
deleted file mode 100644
index 7e7787a..0000000
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSRequest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.hawq.ranger.integration.service.tests;
-
-import org.codehaus.jackson.map.ObjectMapper;
-
-import java.io.IOException;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class RPSRequest {
-
-    String user;
-    Map<String, String> resources;
-    List<String> privileges;
-
-    public RPSRequest(String user,
-                      Map<String, String> resources,
-                      List<String> privileges) {
-        this.user = user;
-        this.resources = resources;
-        this.privileges = privileges;
-    }
-
-    public String getJsonString()
-            throws IOException {
-
-        Map<String, Object> request = new HashMap<>();
-        request.put("requestId", 9);
-        request.put("user", user);
-        request.put("clientIp", "123.0.0.21");
-        request.put("context", "CREATE DATABASE sirotan;");
-        Map<String, Object> accessHash = new HashMap<>();
-        accessHash.put("resource", resources);
-        accessHash.put("privileges", privileges);
-        request.put("access", Arrays.asList(accessHash));
-        return new ObjectMapper().writeValueAsString(request);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java
deleted file mode 100644
index 2ed1046..0000000
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/RPSResponse.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.hawq.ranger.integration.service.tests;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-
-import java.util.List;
-import java.util.Map;
-
-public class RPSResponse {
-
-    @JsonProperty
-    public int requestId;
-
-    @JsonProperty
-    public List<Map<String, Object>> access;
-
-    public List<Map<String, Object>> getAccess() {
-        return access;
-    }
-
-    public boolean hasAccess() {
-        return (boolean) access.get(0).get("allowed");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SchemaTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SchemaTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SchemaTest.java
new file mode 100644
index 0000000..b3dff37
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SchemaTest.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.hawq.ranger.integration.service.tests;
+
+import org.apache.hawq.ranger.integration.service.tests.common.ComplexResourceTestBase;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.junit.Before;
+
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.*;
+
+public class SchemaTest extends ComplexResourceTestBase {
+
+    // for schema only, privileges in policy must have -schema suffix added, create-schema is covered as part of DatabaseTest
+    private static final String[] SPECIAL_PRIVILEGES = new String[] {"usage-schema"};
+
+    @Before
+    public void beforeTest() {
+        specificResource.put(database, TEST_DB);
+        specificResource.put(schema, TEST_SCHEMA);
+
+        parentUnknownResource.put(database, UNKNOWN);
+        parentUnknownResource.put(schema, TEST_SCHEMA);
+
+        childUnknownResource.put(database, TEST_DB);
+        childUnknownResource.put(schema, UNKNOWN);
+
+        unknownResource.put(database, UNKNOWN);
+        unknownResource.put(schema, UNKNOWN);
+
+        privileges = new String[] {"usage"};
+    }
+
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(table, STAR)
+                .userAccess(TEST_USER, SPECIAL_PRIVILEGES)
+                .build();
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceParentStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, STAR)
+                .resource(schema, TEST_SCHEMA)
+                .resource(table, STAR)
+                .userAccess(TEST_USER, SPECIAL_PRIVILEGES)
+                .build();
+        policy.isParentStar = true;
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceChildStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, STAR)
+                .resource(table, STAR)
+                .userAccess(TEST_USER, SPECIAL_PRIVILEGES)
+                .build();
+        policy.isChildStar = true;
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(table, STAR)
+                .groupAccess(PUBLIC_GROUP, SPECIAL_PRIVILEGES)
+                .build();
+        return policy;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SequenceTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SequenceTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SequenceTest.java
new file mode 100644
index 0000000..5add94c
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SequenceTest.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.hawq.ranger.integration.service.tests;
+
+import org.apache.hawq.ranger.integration.service.tests.common.ComplexResourceTestBase;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.junit.Before;
+
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.*;
+
+public class SequenceTest extends ComplexResourceTestBase {
+
+    @Before
+    public void beforeTest() {
+        specificResource.put(database, TEST_DB);
+        specificResource.put(schema, TEST_SCHEMA);
+        specificResource.put(sequence, TEST_SEQUENCE);
+
+        parentUnknownResource.put(database, TEST_DB);
+        parentUnknownResource.put(schema, UNKNOWN);
+        parentUnknownResource.put(sequence, TEST_SEQUENCE);
+
+        childUnknownResource.put(database, TEST_DB);
+        childUnknownResource.put(schema, TEST_SCHEMA);
+        childUnknownResource.put(sequence, UNKNOWN);
+
+        unknownResource.put(database, UNKNOWN);
+        unknownResource.put(schema, UNKNOWN);
+        unknownResource.put(sequence, UNKNOWN);
+
+        privileges = new String[] {"select", "update", "usage"};
+    }
+
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(sequence, TEST_SEQUENCE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        return policy;
+    }
+
+    @Override
+
+    protected Policy getResourceParentStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, STAR)
+                .resource(sequence, TEST_SEQUENCE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isParentStar = true;
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceChildStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(sequence, STAR)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isChildStar = true;
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(sequence, TEST_SEQUENCE)
+                .groupAccess(PUBLIC_GROUP, privileges)
+                .build();
+        return policy;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java
deleted file mode 100644
index 8608584..0000000
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/ServiceBaseTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.hawq.ranger.integration.service.tests;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.rules.TestName;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public abstract class ServiceBaseTest {
-
-    protected final Log log = LogFactory.getLog(this.getClass());
-
-    @Rule
-    public final TestName testName = new TestName();
-    protected final String policyName = getClass().getSimpleName();
-    protected Map<String, String> resources = new HashMap<>();
-
-    public static String RANGER_PLUGIN_SERVICE_HOST = "localhost";
-    public static String RANGER_PLUGIN_SERVICE_PORT = "8432";
-    public static String RANGER_PLUGIN_SERVICE_URL =
-        "http://" + RANGER_PLUGIN_SERVICE_HOST + ":" + RANGER_PLUGIN_SERVICE_PORT + "/rps";
-    public static String RANGER_ADMIN_HOST = "localhost";
-    public static String RANGER_ADMIN_PORT = "6080";
-    public static String RANGER_URL =
-        "http://" + RANGER_ADMIN_HOST + ":" + RANGER_ADMIN_PORT + "/service/public/v2/api";
-    public static String RANGER_TEST_USER = "maria_dev";
-    public static int    POLICY_REFRESH_INTERVAL = 6000;
-
-    @Before
-    public void setUp()
-            throws IOException {
-        log.info("======================================================================================");
-        log.info("Running test " + testName.getMethodName());
-        log.info("======================================================================================");
-        beforeTest();
-    }
-
-    @After
-    public void tearDown()
-            throws IOException {
-        deletePolicy();
-    }
-
-    protected void createPolicy(String jsonFile)
-            throws IOException {
-
-        log.info("Creating policy " + policyName);
-        HttpPost httpPost = new HttpPost(RANGER_URL + "/policy");
-        httpPost.setEntity(new StringEntity(Utils.getPayload(jsonFile)));
-        Utils.processHttpRequest(httpPost);
-        waitForPolicyRefresh();
-    }
-
-    protected void deletePolicy()
-            throws IOException {
-
-        log.info("Deleting policy " + policyName);
-        String requestUrl = RANGER_URL + "/policy?servicename=hawq&policyname=" + policyName;
-        Utils.processHttpRequest(new HttpDelete(requestUrl));
-        waitForPolicyRefresh();
-    }
-
-    protected boolean hasAccess(String user,
-                                Map<String, String> resources,
-                                List<String> privileges)
-            throws IOException {
-
-        log.info("Checking access for user " + user);
-        RPSRequest request = new RPSRequest(user, resources, privileges);
-        HttpPost httpPost = new HttpPost(RANGER_PLUGIN_SERVICE_URL);
-        httpPost.setEntity(new StringEntity(request.getJsonString()));
-        String result = Utils.processHttpRequest(httpPost);
-        RPSResponse rpsResponse = Utils.getResponse(result);
-        return rpsResponse.hasAccess();
-    }
-
-    private void waitForPolicyRefresh() {
-
-        try {
-            Thread.sleep(POLICY_REFRESH_INTERVAL);
-        }
-        catch (InterruptedException e) {
-            log.error(e);
-        }
-    }
-
-    public abstract void beforeTest() throws IOException;
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SpecialPrivilegesTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SpecialPrivilegesTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SpecialPrivilegesTest.java
new file mode 100644
index 0000000..ac1727f
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/SpecialPrivilegesTest.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.hawq.ranger.integration.service.tests;
+
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.apache.hawq.ranger.integration.service.tests.common.ServiceTestBase;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.*;
+
+public class SpecialPrivilegesTest extends ServiceTestBase {
+
+    private final String[] privilegeUsageSchema = new String[] {"usage-schema"};
+    private final String[] privilegeUsage = new String[] {"usage"};
+
+
+    private Map<Policy.ResourceType, String> schemaResource;
+    private Map<Policy.ResourceType, String> sequenceResource;
+
+    @Before
+    public void beforeTest() {
+        // resource used for lookup from RPS
+        schemaResource = new HashMap<>();
+        schemaResource.put(database, TEST_DB);
+        schemaResource.put(schema, TEST_SCHEMA);
+
+        sequenceResource = new HashMap<>();
+        sequenceResource.put(database, TEST_DB);
+        sequenceResource.put(schema, TEST_SCHEMA);
+        sequenceResource.put(sequence, TEST_SEQUENCE);
+    }
+
+
+    @Test
+    public void testUsageSchemaPrivilege() throws IOException {
+        // define policy for "usage-schema" on db:schema:*
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(sequence, STAR)
+                .userAccess(TEST_USER, privilegeUsageSchema)
+                .build();
+        createPolicy(policy);
+        try {
+            // user should have access to usage on schema
+            checkUserHasResourceAccess(TEST_USER, schemaResource, privilegeUsage);
+            // user should have NO access to usage on sequence
+            checkUserDeniedResourceAccess(TEST_USER, sequenceResource, privilegeUsage);
+        } finally {
+            deletePolicy(policy);
+        }
+    }
+
+    @Test
+    public void testUsagePrivilege() throws IOException {
+        // define policy for "usage" on db:schema:*
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(sequence, STAR)
+                .userAccess(TEST_USER, privilegeUsage)
+                .build();
+        createPolicy(policy);
+        try {
+            // user should have NO access to usage on schema
+            checkUserDeniedResourceAccess(TEST_USER, schemaResource, privilegeUsage);
+            // user should have access to usage on sequence
+            checkUserHasResourceAccess(TEST_USER, sequenceResource, privilegeUsage);
+        } finally {
+            deletePolicy(policy);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TableTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TableTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TableTest.java
new file mode 100644
index 0000000..742b91c
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TableTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.hawq.ranger.integration.service.tests;
+
+import org.apache.hawq.ranger.integration.service.tests.common.ComplexResourceTestBase;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.junit.Before;
+
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.*;
+
+public class TableTest extends ComplexResourceTestBase {
+
+    @Before
+    public void beforeTest() {
+        specificResource.put(database, TEST_DB);
+        specificResource.put(schema, TEST_SCHEMA);
+        specificResource.put(table, TEST_TABLE);
+
+        parentUnknownResource.put(database, TEST_DB);
+        parentUnknownResource.put(schema, UNKNOWN);
+        parentUnknownResource.put(table, TEST_TABLE);
+
+        childUnknownResource.put(database, TEST_DB);
+        childUnknownResource.put(schema, TEST_SCHEMA);
+        childUnknownResource.put(table, UNKNOWN);
+
+        unknownResource.put(database, UNKNOWN);
+        unknownResource.put(schema, UNKNOWN);
+        unknownResource.put(table, UNKNOWN);
+
+        privileges = new String[] {"select", "insert", "update", "delete", "references"};
+    }
+
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(table, TEST_TABLE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceParentStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, STAR)
+                .resource(table, TEST_TABLE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isParentStar = true;
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceChildStarUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(table, STAR)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        policy.isChildStar = true;
+        return policy;
+    }
+
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(database, TEST_DB)
+                .resource(schema, TEST_SCHEMA)
+                .resource(table, TEST_TABLE)
+                .groupAccess(PUBLIC_GROUP, privileges)
+                .build();
+        return policy;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
index cfc41cb..f8834b5 100644
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/TablespaceTest.java
@@ -19,49 +19,36 @@
 
 package org.apache.hawq.ranger.integration.service.tests;
 
-import org.junit.Test;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy;
+import org.apache.hawq.ranger.integration.service.tests.common.SimpleResourceTestBase;
+import org.junit.Before;
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
+import static org.apache.hawq.ranger.integration.service.tests.common.Policy.ResourceType.tablespace;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+public class TablespaceTest extends SimpleResourceTestBase {
 
-public class TablespaceTest extends ServiceBaseTest {
-
-    private static final List<String> PRIVILEGES = Arrays.asList("create");
-
-    public void beforeTest()
-            throws IOException {
-        createPolicy("test-tablespace.json");
-        resources.put("tablespace", "pg_global");
-    }
-
-    @Test
-    public void testTablespaces_UserMaria_PgGlobalTablespace_Allowed()
-            throws IOException {
-        assertTrue(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Before
+    public void beforeTest() {
+        specificResource.put(tablespace, TEST_TABLESPACE);
+        unknownResource.put(tablespace, UNKNOWN);
+        privileges = new String[] {"create"};
     }
 
-    @Test
-    public void testTablespaces_UserMaria_DoesNotExistTablespace_Denied()
-            throws IOException {
-        resources.put("tablespace", "doesnotexist");
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceUserPolicy() {
+        Policy policy = policyBuilder
+                .resource(tablespace, TEST_TABLESPACE)
+                .userAccess(TEST_USER, privileges)
+                .build();
+        return policy;
     }
 
-    @Test
-    public void testTablespaces_UserBob_PgGlobalTablespace_Denied()
-            throws IOException {
-        assertFalse(hasAccess("bob", resources, PRIVILEGES));
+    @Override
+    protected Policy getResourceGroupPolicy() {
+        Policy policy = policyBuilder
+                .resource(tablespace, TEST_TABLESPACE)
+                .groupAccess(PUBLIC_GROUP, privileges)
+                .build();
+        return policy;
     }
-
-    @Test
-    public void testTablespaces_UserMaria_PgGlobalTablespace_Denied()
-            throws IOException {
-        deletePolicy();
-        assertFalse(hasAccess(RANGER_TEST_USER, resources, PRIVILEGES));
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java
deleted file mode 100644
index 971e513..0000000
--- a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/Utils.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.hawq.ranger.integration.service.tests;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.codehaus.jackson.map.ObjectMapper;
-
-import java.io.IOException;
-
-public class Utils {
-
-    protected static final Log log = LogFactory.getLog(Utils.class);
-
-    public static String getPayload(String jsonFile)
-            throws IOException {
-        return IOUtils.toString(Utils.class.getClassLoader().getResourceAsStream(jsonFile));
-    }
-
-    public static String getEncoding() {
-        return Base64.encodeBase64String("admin:admin".getBytes());
-    }
-
-    public static String processHttpRequest(HttpRequestBase request)
-            throws IOException {
-
-        if (log.isDebugEnabled()) {
-            log.debug("Request URI = " + request.getURI().toString());
-        }
-        request.setHeader("Authorization", "Basic " + getEncoding());
-        request.setHeader("Content-Type", "application/json");
-        HttpClient httpClient = HttpClientBuilder.create().build();
-        HttpResponse response = httpClient.execute(request);
-        int responseCode = response.getStatusLine().getStatusCode();
-        log.info("Response Code = " + responseCode);
-        HttpEntity entity = response.getEntity();
-        if (entity != null) {
-            String result = IOUtils.toString(entity.getContent());
-            if (log.isDebugEnabled()) {
-                log.debug(result);
-            }
-            return result;
-        }
-        return null;
-    }
-
-    public static RPSResponse getResponse(String result)
-            throws IOException {
-        return new ObjectMapper().readValue(result, RPSResponse.class);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ComplexResourceTestBase.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ComplexResourceTestBase.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ComplexResourceTestBase.java
new file mode 100644
index 0000000..f49c18b
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ComplexResourceTestBase.java
@@ -0,0 +1,40 @@
+/*
+ * 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.hawq.ranger.integration.service.tests.common;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+public abstract class ComplexResourceTestBase extends SimpleResourceTestBase {
+
+    @Test
+    public void testParentStarResourceUserPolicy() throws IOException {
+        checkResourceUserPolicy(getResourceParentStarUserPolicy());
+    }
+
+    @Test
+    public void testChildStarResourceUserPolicy() throws IOException {
+        checkResourceUserPolicy(getResourceChildStarUserPolicy());
+    }
+
+    abstract protected Policy getResourceParentStarUserPolicy();
+    abstract protected Policy getResourceChildStarUserPolicy();
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/Policy.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/Policy.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/Policy.java
new file mode 100644
index 0000000..7d8f4b5
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/Policy.java
@@ -0,0 +1,107 @@
+/*
+ * 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.hawq.ranger.integration.service.tests.common;
+
+import java.util.*;
+
+public class Policy {
+
+    public enum ResourceType {
+        database, schema, table, function, sequence, tablespace, language, protocol;
+    }
+
+    public static class ResourceValue {
+        public Set<String> values = new HashSet<>();
+        public Boolean isExcludes = false;
+        public Boolean isRecursive = false;
+
+        public ResourceValue(String... values) {
+            this.values.addAll(Arrays.asList(values));
+        }
+    }
+
+    public static class Access {
+        public String type;
+        public Boolean isAllowed = true;
+        public Access(String type) {
+            this.type = type;
+        }
+    }
+
+    public static class PolicyItem {
+        public Set<Access> accesses = new HashSet<>();
+        public Set<String> users = new HashSet<>();
+        public Set<String> groups = new HashSet<>();
+        public Set<String> conditions = new HashSet<>();
+        public Boolean delegateAdmin = true;
+        public PolicyItem(String[] privileges) {
+            for (String privilege : privileges) {
+                this.accesses.add(new Access(privilege));
+            }
+        }
+    }
+
+    public Boolean isEnabled = true;
+    public String service = "hawq";
+    public String name;
+    public Integer policyType = 0;
+    public String description = "Test policy";
+    public Boolean isAuditEnabled = true;
+    public Map<ResourceType, ResourceValue> resources = new HashMap<>();
+    public Set<PolicyItem> policyItems = new HashSet<>();
+    public Set<Object> denyPolicyItems = new HashSet<>();
+    public Set<Object> allowExceptions = new HashSet<>();
+    public Set<Object> denyExceptions = new HashSet<>();
+    public Set<Object> dataMaskPolicyItems = new HashSet<>();
+    public Set<Object> rowFilterPolicyItems = new HashSet<>();
+
+    // do not serialize into JSON
+    public transient boolean isParentStar = false;
+    public transient boolean isChildStar = false;
+
+    public static class PolicyBuilder {
+        private Policy policy = new Policy();
+
+        public PolicyBuilder name(String name) {
+            policy.name = name;
+            policy.description = "Test Policy for " + name;
+            return this;
+        }
+        public PolicyBuilder resource(ResourceType type, String value) {
+            policy.resources.put(type, new ResourceValue(value));
+            return this;
+        }
+        public PolicyBuilder userAccess(String user, String... privileges) {
+            PolicyItem policyItem = new PolicyItem(privileges);
+            policyItem.users.add(user);
+            policy.policyItems.add(policyItem);
+            return this;
+        }
+        public PolicyBuilder groupAccess(String group, String... privileges) {
+            PolicyItem policyItem = new PolicyItem(privileges);
+            policyItem.groups.add(group);
+            policy.policyItems.add(policyItem);
+            return this;
+        }
+        public Policy build() {
+            return policy;
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/RESTClient.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/RESTClient.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/RESTClient.java
new file mode 100644
index 0000000..ee7cb6e
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/RESTClient.java
@@ -0,0 +1,114 @@
+/*
+ * 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.hawq.ranger.integration.service.tests.common;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.*;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import java.io.IOException;
+
+
+public class RESTClient {
+
+    private static final Log LOG = LogFactory.getLog(RESTClient.class);
+    private static final String AUTH_HEADER = getAuthorizationHeader();
+
+    private CloseableHttpClient httpClient;
+
+    private static String getAuthorizationHeader() {
+        return "Basic " + Base64.encodeBase64String("admin:admin".getBytes());
+    }
+
+    public RESTClient() {
+        httpClient = HttpClients.createDefault();
+    }
+
+    public String executeRequest(Method method, String url) throws IOException {
+        return executeRequest(method, url, null);
+    }
+
+    public String executeRequest(Method method, String url, String payload) throws IOException {
+        HttpUriRequest request = null;
+        switch (method) {
+            case GET:
+                request = new HttpGet(url);
+                break;
+            case POST:
+                request = new HttpPost(url);
+                ((HttpPost) request).setEntity(new StringEntity(payload));
+                break;
+            case DELETE:
+                request = new HttpDelete(url);
+                break;
+            default:
+                throw new IllegalArgumentException("Method " + method + " is not supported");
+        }
+        return executeRequest(request);
+    }
+
+    private String executeRequest(HttpUriRequest request) throws IOException {
+
+        LOG.debug("--> request URI = " + request.getURI());
+
+        request.setHeader("Authorization", AUTH_HEADER);
+        request.setHeader("Content-Type", ContentType.APPLICATION_JSON.toString());
+
+        CloseableHttpResponse response = httpClient.execute(request);
+        String payload = null;
+        try {
+            int responseCode = response.getStatusLine().getStatusCode();
+            LOG.debug("<-- response code = " + responseCode);
+
+            HttpEntity entity = response.getEntity();
+            if (entity != null) {
+                payload = EntityUtils.toString(response.getEntity());
+            }
+            LOG.debug("<-- response payload = " + payload);
+
+            if (responseCode == HttpStatus.SC_NOT_FOUND) {
+                throw new ResourceNotFoundException();
+            } else if (responseCode >= 300) {
+                throw new ClientProtocolException("Unexpected HTTP response code = " + responseCode);
+            }
+        } finally {
+            response.close();
+        }
+
+        return payload;
+    }
+
+    public static class ResourceNotFoundException extends IOException {
+
+    }
+
+    public enum Method {
+        GET, POST, PUT, DELETE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ServiceTestBase.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ServiceTestBase.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ServiceTestBase.java
new file mode 100644
index 0000000..0b3be56
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/ServiceTestBase.java
@@ -0,0 +1,162 @@
+/*
+ * 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.hawq.ranger.integration.service.tests.common;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hawq.ranger.integration.service.tests.common.Policy.PolicyBuilder;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestName;
+
+import java.io.IOException;
+import java.util.*;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public abstract class ServiceTestBase {
+
+    protected Log LOG = LogFactory.getLog(this.getClass());
+
+    @Rule
+    public final TestName testName = new TestName();
+
+    protected static final String PUBLIC_GROUP = "public";
+    protected static final String GPADMIN_USER = "gpadmin";
+    protected static final String TEST_USER = "maria_dev";
+    protected static final String UNKNOWN = "unknown";
+    protected static final String STAR = "*";
+
+    protected static final String TEST_DB = "test-db";
+    protected static final String TEST_SCHEMA = "test-schema";
+    protected static final String TEST_TABLE = "test-table";
+    protected static final String TEST_FUNCTION = "test-function";
+    protected static final String TEST_SEQUENCE = "test-sequence";
+    protected static final String TEST_LANGUAGE = "test-language";
+    protected static final String TEST_PROTOCOL = "test-protocol";
+    protected static final String TEST_TABLESPACE = "test-tablespace";
+
+    protected PolicyBuilder policyBuilder;
+
+    private static final String RPS_HOST = "localhost";
+    private static final String RPS_PORT = "8432";
+    private static final String RPS_URL = String.format("http://%s:%s/rps", RPS_HOST, RPS_PORT);
+
+    private static final String RANGER_HOST = "localhost";
+    private static final String RANGER_PORT = "6080";
+    private static final String RANGER_URL = String.format("http://%s:%s/service/public/v2/api", RANGER_HOST, RANGER_PORT);
+    private static final String RANGER_POLICY_URL = RANGER_URL + "/policy";
+
+    private static final int POLICY_REFRESH_INTERVAL = 6000;
+    private static final TypeReference<HashMap<String,Object>> typeMSO = new TypeReference<HashMap<String,Object>>() {};
+
+    private RESTClient rest = new RESTClient();
+    private ObjectMapper mapper = new ObjectMapper();
+
+    @Before
+    public void setUp() throws IOException {
+        LOG.info("======================================================================================");
+        LOG.info("Running test " + testName.getMethodName());
+        LOG.info("======================================================================================");
+
+        policyBuilder = (new PolicyBuilder()).name(getClass().getSimpleName());
+    }
+
+    protected void checkUserHasResourceAccess(String user, Map<Policy.ResourceType, String> resource, String[] privileges) throws IOException {
+        // user IN the policy --> has all possible privileges to the specific resource
+        LOG.debug(String.format("Asserting user %s HAS access %s privileges %s", user, resource, Arrays.toString(privileges)));
+        assertTrue(hasAccess(user, resource, privileges));
+        for (String privilege : privileges) {
+            // user IN the policy --> has individual privileges to the specific resource
+            LOG.debug(String.format("Asserting user %s HAS access %s privilege %s", user, resource, privilege));
+            assertTrue(hasAccess(user, resource, privilege));
+        }
+    }
+
+    protected void checkUserDeniedResourceAccess(String user, Map<Policy.ResourceType, String> resource, String[] privileges) throws IOException {
+        // user IN the policy --> has all possible privileges to the specific resource
+        LOG.debug(String.format("Asserting user %s HAS NO access %s privileges %s", user, resource, Arrays.toString(privileges)));
+        assertFalse(hasAccess(user, resource, privileges));
+        for (String privilege : privileges) {
+            // user IN the policy --> has individual privileges to the specific resource
+            LOG.debug(String.format("Asserting user %s HAS No access %s privilege %s", user, resource, privilege));
+            assertFalse(hasAccess(user, resource, privilege));
+        }
+    }
+
+    protected void createPolicy(Policy policy) throws IOException {
+        String policyJson = mapper.writeValueAsString(policy);
+        LOG.info(String.format("Creating policy %s : %s", policy.name, policyJson));
+        rest.executeRequest(RESTClient.Method.POST, RANGER_POLICY_URL, policyJson);
+        waitForPolicyRefresh();
+    }
+
+    protected void deletePolicy(Policy policy) throws IOException {
+        LOG.info("Deleting policy " + policy.name);
+        try {
+            rest.executeRequest(RESTClient.Method.DELETE, getRangerPolicyUrl(policy.name));
+        } catch (RESTClient.ResourceNotFoundException e) {
+            // ignore error when deleting a policy that does not exit
+        }
+        waitForPolicyRefresh();
+    }
+
+    protected boolean hasAccess(String user, Map<Policy.ResourceType, String> resources, String... privileges) throws IOException {
+        LOG.info("Checking access for user " + user);
+        String response = rest.executeRequest(RESTClient.Method.POST, RPS_URL, getRPSRequestPayload(user, resources, privileges));
+        Map<String, Object> responseMap = mapper.readValue(response, typeMSO);
+        boolean allowed = (Boolean)((Map)((List) responseMap.get("access")).get(0)).get("allowed");
+        LOG.info(String.format("Access for user %s is allowed = %s", user, allowed));
+        return allowed;
+    }
+
+    private void waitForPolicyRefresh() {
+        try {
+            Thread.sleep(POLICY_REFRESH_INTERVAL);
+        }
+        catch (InterruptedException e) {
+            LOG.error(e);
+        }
+    }
+
+    private String getRangerPolicyUrl(String policyName) {
+        return RANGER_POLICY_URL + "?servicename=hawq&policyname=" + policyName;
+    }
+
+    private String getRPSRequestPayload(String user, Map<Policy.ResourceType, String> resources, String[] privileges) throws IOException {
+        Map<String, Object> request = new HashMap<>();
+        request.put("requestId", 9);
+        request.put("user", user);
+        request.put("clientIp", "123.0.0.21");
+        request.put("context", "CREATE SOME DATABASE OBJECT;");
+
+        Map<String, Object> access = new HashMap<>();
+        access.put("resource", resources);
+        access.put("privileges", privileges);
+
+        Set<Map<String, Object>> accesses = new HashSet<>();
+        accesses.add(access);
+        request.put("access", accesses);
+        return new ObjectMapper().writeValueAsString(request);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/SimpleResourceTestBase.java
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/SimpleResourceTestBase.java b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/SimpleResourceTestBase.java
new file mode 100644
index 0000000..8bd18e8
--- /dev/null
+++ b/ranger-plugin/integration/service/src/test/java/org/apache/hawq/ranger/integration/service/tests/common/SimpleResourceTestBase.java
@@ -0,0 +1,114 @@
+/*
+ * 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.hawq.ranger.integration.service.tests.common;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public abstract class SimpleResourceTestBase extends ServiceTestBase {
+
+    protected Map<Policy.ResourceType, String> specificResource = new HashMap<>();
+    protected Map<Policy.ResourceType, String> parentUnknownResource = new HashMap<>();
+    protected Map<Policy.ResourceType, String> childUnknownResource = new HashMap<>();
+    protected Map<Policy.ResourceType, String> unknownResource = new HashMap<>();
+    protected String[] privileges = {};
+
+    @Before
+    public void beforeSimple() throws IOException {
+        specificResource = new HashMap<>();
+        parentUnknownResource = new HashMap<>();
+        childUnknownResource = new HashMap<>();
+        unknownResource = new HashMap<>();
+        privileges = new String[]{};
+    }
+
+    @Test
+    public void testSpecificResourceUserPolicy() throws IOException {
+        checkResourceUserPolicy(getResourceUserPolicy());
+    }
+
+    @Test
+    public void testStarResourceGpadminPolicy() throws IOException {
+        checkUserHasResourceAccess(GPADMIN_USER, specificResource, privileges);
+        // user NOT in the policy --> has NO access to the specific resource
+        assertFalse(hasAccess(UNKNOWN, specificResource, privileges));
+        // test that other existing user can't rely on gpadmin policy
+        assertFalse(hasAccess(TEST_USER, specificResource, privileges));
+        // user IN the policy --> has access to the unknown resource
+        assertTrue(hasAccess(GPADMIN_USER, unknownResource, privileges));
+    }
+
+    @Test
+    public void testSpecificResourcePublicGroupPolicy() throws IOException {
+        Policy policy = getResourceGroupPolicy();
+        createPolicy(policy);
+        checkUserHasResourceAccess(TEST_USER, specificResource, privileges);
+        // user NOT in the policy --> has access to the specific resource
+        assertTrue(hasAccess(UNKNOWN, specificResource, privileges));
+        // user IN the policy --> has NO access to the unknown resource
+        assertFalse(hasAccess(TEST_USER, unknownResource, privileges));
+        // test that user doesn't have access if policy is deleted
+        deletePolicy(policy);
+        assertFalse(hasAccess(TEST_USER, specificResource, privileges));
+    }
+
+    protected void checkResourceUserPolicy(Policy policy) throws IOException {
+        createPolicy(policy);
+        boolean policyDeleted = false;
+        try {
+            checkUserHasResourceAccess(TEST_USER, specificResource, privileges);
+            // user NOT in the policy --> has NO access to the specific resource
+            LOG.debug(String.format("Asserting user %s NO  access %s privileges %s", UNKNOWN, specificResource, Arrays.toString(privileges)));
+            assertFalse(hasAccess(UNKNOWN, specificResource, privileges));
+
+            // if resource has parents, assert edge cases
+            if (!parentUnknownResource.isEmpty()) {
+                // user IN the policy --> has access to the resource only for parentStar policies
+                assertEquals(policy.isParentStar, hasAccess(TEST_USER, parentUnknownResource, privileges));
+            }
+            if (!childUnknownResource.isEmpty()) {
+                // user IN the policy --> has access to the resource only for childStar policies
+                assertEquals(policy.isChildStar, hasAccess(TEST_USER, childUnknownResource, privileges));
+            }
+
+            // user IN the policy --> has NO access to the unknown resource
+            assertFalse(hasAccess(TEST_USER, unknownResource, privileges));
+            // test that user doesn't have access if policy is deleted
+            deletePolicy(policy);
+            policyDeleted = true;
+            assertFalse(hasAccess(TEST_USER, specificResource, privileges));
+        } finally {
+            // if a given test fails with assertion, still delete the policy not to impact other tests
+            if (!policyDeleted) {
+                deletePolicy(policy);
+            }
+        }
+    }
+
+    abstract protected Policy getResourceUserPolicy();
+    abstract protected Policy getResourceGroupPolicy();
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-database.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-database.json b/ranger-plugin/integration/service/src/test/resources/test-database.json
deleted file mode 100644
index ffa3bfe..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-database.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "DatabaseTest",
-  "policyType": 0,
-  "description": "Test policy for database resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "schema": {
-      "values": ["*"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "database": {
-      "values": ["sirotan"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "function": {
-      "values": ["*"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "create",
-      "isAllowed": true
-    }, {
-      "type": "connect",
-      "isAllowed": true
-    }, {
-      "type": "temp",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-function-2.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-function-2.json b/ranger-plugin/integration/service/src/test/resources/test-function-2.json
deleted file mode 100644
index 5ae7f0b..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-function-2.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "FunctionTest",
-  "policyType": 0,
-  "description": "Test policy for function resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "schema": {
-      "values": ["*"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "database": {
-      "values": ["*"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "function": {
-      "values": ["atan"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "execute",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-function.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-function.json b/ranger-plugin/integration/service/src/test/resources/test-function.json
deleted file mode 100644
index 74d5d83..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-function.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "FunctionTest",
-  "policyType": 0,
-  "description": "Test policy for function resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "schema": {
-      "values": ["siroschema"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "database": {
-      "values": ["sirotan"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "function": {
-      "values": ["atan"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "execute",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-language-2.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-language-2.json b/ranger-plugin/integration/service/src/test/resources/test-language-2.json
deleted file mode 100644
index 93a41fe..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-language-2.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "LanguageTest",
-  "policyType": 0,
-  "description": "Test policy for language resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "language": {
-      "values": ["sql"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "database": {
-      "values": ["*"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "usage",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-language.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-language.json b/ranger-plugin/integration/service/src/test/resources/test-language.json
deleted file mode 100644
index cba2f43..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-language.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "LanguageTest",
-  "policyType": 0,
-  "description": "Test policy for language resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "language": {
-      "values": ["sql"],
-      "isExcludes": false,
-      "isRecursive": false
-    },
-    "database": {
-      "values": ["sirotan"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "usage",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-protocol.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-protocol.json b/ranger-plugin/integration/service/src/test/resources/test-protocol.json
deleted file mode 100644
index d59caed..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-protocol.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "ProtocolTest",
-  "policyType": 0,
-  "description": "Test policy for protocol resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "protocol": {
-      "values": ["pxf"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "select",
-      "isAllowed": true
-    }, {
-      "type": "insert",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/8a5e65bf/ranger-plugin/integration/service/src/test/resources/test-tablespace.json
----------------------------------------------------------------------
diff --git a/ranger-plugin/integration/service/src/test/resources/test-tablespace.json b/ranger-plugin/integration/service/src/test/resources/test-tablespace.json
deleted file mode 100644
index a45ecea..0000000
--- a/ranger-plugin/integration/service/src/test/resources/test-tablespace.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "isEnabled": true,
-  "service": "hawq",
-  "name": "TablespaceTest",
-  "policyType": 0,
-  "description": "Test policy for tablespace resource",
-  "isAuditEnabled": true,
-  "resources": {
-    "tablespace": {
-      "values": ["pg_global"],
-      "isExcludes": false,
-      "isRecursive": false
-    }
-  },
-  "policyItems": [{
-    "accesses": [{
-      "type": "create",
-      "isAllowed": true
-    }],
-    "users": ["maria_dev"],
-    "groups": [],
-    "conditions": [],
-    "delegateAdmin": true
-  }],
-  "denyPolicyItems": [],
-  "allowExceptions": [],
-  "denyExceptions": [],
-  "dataMaskPolicyItems": [],
-  "rowFilterPolicyItems": []
-}
\ No newline at end of file