You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sp...@apache.org on 2018/05/31 03:32:03 UTC
[25/86] sentry git commit: Revert "SENTRY-2208: Refactor out Sentry
service into own module from sentry-provider-db (Anthony Young-Garner,
reviewed by Sergio Pena, Steve Moist, Na Li)"
http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestNotificationProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestNotificationProcessor.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestNotificationProcessor.java
new file mode 100644
index 0000000..f227bb4
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestNotificationProcessor.java
@@ -0,0 +1,488 @@
+/*
+ * 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.sentry.provider.db.service.persistent;
+
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.Database;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.NotificationEvent;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.messaging.EventMessage;
+import org.apache.sentry.binding.metastore.messaging.json.SentryJSONMessageFactory;
+import org.apache.sentry.hdfs.UniquePathsUpdate;
+import org.apache.sentry.service.common.ServiceConstants;
+import org.apache.sentry.api.service.thrift.TSentryAuthorizable;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+// TODO 1. More tests should be added here.
+// TODO 2. Tests using actual sentry store where.
+@SuppressWarnings("unused")
+public class TestNotificationProcessor {
+
+ private static final SentryStore sentryStore = Mockito.mock(SentryStore.class);
+ private final static String hiveInstance = "server2";
+ private final static Configuration conf = new Configuration();
+ private final SentryJSONMessageFactory messageFactory = new SentryJSONMessageFactory();
+ private NotificationProcessor notificationProcessor;
+
+ @BeforeClass
+ public static void setup() {
+ conf.set("sentry.hive.sync.create", "true");
+ conf.set("sentry.hive.sync.drop", "true");
+
+ // enable HDFS sync, so perm and path changes will be saved into DB
+ conf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
+ conf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
+ }
+
+ @After
+ public void resetConf() {
+ conf.set("sentry.hive.sync.create", "true");
+ conf.set("sentry.hive.sync.drop", "true");
+ reset(sentryStore);
+ }
+
+ @Test
+ /*
+ Makes sure that appropriate sentry store methods are invoked when create database event is
+ processed.
+
+ Also, checks the hive sync configuration.
+ */
+ public void testCreateDatabase() throws Exception {
+ long seqNum = 1;
+ String dbName = "db1";
+ String uriPrefix = "hdfs:///";
+ String location = "user/hive/warehouse";
+ NotificationEvent notificationEvent;
+ TSentryAuthorizable authorizable;
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, conf);
+
+ // Create notification event
+ notificationEvent = new NotificationEvent(seqNum, 0,
+ EventMessage.EventType.CREATE_DATABASE.toString(),
+ messageFactory.buildCreateDatabaseMessage(new Database(dbName,
+ null, uriPrefix + location, null)).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb("db1");
+ //noinspection unchecked
+ verify(sentryStore, times(1)).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+
+ verify(sentryStore, times(1)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+ reset(sentryStore);
+
+ //Change the configuration and make sure that exiting privileges are not dropped
+ notificationProcessor.setSyncStoreOnCreate(false);
+ dbName = "db2";
+ notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.CREATE_DATABASE.toString(),
+ messageFactory.buildCreateDatabaseMessage(new Database(dbName,
+ null, "hdfs:///db2", null)).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb(dbName);
+
+ //noinspection unchecked
+ verify(sentryStore, times(1)).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ //making sure that privileges are not dropped
+ verify(sentryStore, times(0)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+
+ }
+
+ @Test
+ /*
+ Makes sure that appropriate sentry store methods are invoked when drop database event is
+ processed.
+
+ Also, checks the hive sync configuration.
+ */
+ public void testDropDatabase() throws Exception {
+ String dbName = "db1";
+
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, conf);
+
+ // Create notification event
+ NotificationEvent notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.DROP_DATABASE.toString(),
+ messageFactory.buildDropDatabaseMessage(new Database(dbName, null,
+ "hdfs:///db1", null)).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ TSentryAuthorizable authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb("db1");
+
+ //noinspection unchecked
+ verify(sentryStore, times(1)).deleteAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ verify(sentryStore, times(1)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+ reset(sentryStore);
+
+ // Change the configuration and make sure that exiting privileges are not dropped
+ notificationProcessor.setSyncStoreOnDrop(false);
+ dbName = "db2";
+ // Create notification event
+ notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.DROP_DATABASE.toString(),
+ messageFactory.buildDropDatabaseMessage(new Database(dbName, null,
+ "hdfs:///db2", null)).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb(dbName);
+
+ //noinspection unchecked
+ verify(sentryStore, times(1)).deleteAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ verify(sentryStore, times(0)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+ }
+
+ @Test
+ /*
+ Makes sure that appropriate sentry store methods are invoked when create table event is
+ processed.
+
+ Also, checks the hive sync configuration.
+ */
+ public void testCreateTable() throws Exception {
+ String dbName = "db1";
+ String tableName = "table1";
+
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, conf);
+
+ // Create notification event
+ StorageDescriptor sd = new StorageDescriptor();
+ sd.setLocation("hdfs:///db1.db/table1");
+ NotificationEvent notificationEvent =
+ new NotificationEvent(1, 0, EventMessage.EventType.CREATE_TABLE.toString(),
+ messageFactory.buildCreateTableMessage(new Table(tableName,
+ dbName, null, 0, 0, 0, sd, null, null, null, null, null),
+ Collections.emptyIterator()).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ TSentryAuthorizable authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb("db1");
+ authorizable.setTable(tableName);
+
+ //noinspection unchecked
+ verify(sentryStore, times(1)).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+
+ verify(sentryStore, times(1)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+ reset(sentryStore);
+
+ // Change the configuration and make sure that existing privileges are not dropped
+ notificationProcessor.setSyncStoreOnCreate(false);
+
+ // Create notification event
+ dbName = "db2";
+ tableName = "table2";
+ sd = new StorageDescriptor();
+ sd.setLocation("hdfs:///db1.db/table2");
+ notificationEvent =
+ new NotificationEvent(1, 0, EventMessage.EventType.CREATE_TABLE.toString(),
+ messageFactory.buildCreateTableMessage(new Table(tableName,
+ dbName, null, 0, 0, 0, sd, null, null, null, null, null),
+ Collections.emptyIterator()).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb(dbName);
+ authorizable.setTable(tableName);
+
+ //noinspection unchecked
+ verify(sentryStore, times(1)).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ // Making sure that privileges are not dropped
+ verify(sentryStore, times(0)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+ }
+
+ @Test
+ /*
+ Makes sure that appropriate sentry store methods are invoked when drop table event is
+ processed.
+
+ Also, checks the hive sync configuration.
+ */
+ public void testDropTable() throws Exception {
+ String dbName = "db1";
+ String tableName = "table1";
+
+ Configuration authConf = new Configuration();
+ // enable HDFS sync, so perm and path changes will be saved into DB
+ authConf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
+ authConf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
+
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, authConf);
+
+ // Create notification event
+ StorageDescriptor sd = new StorageDescriptor();
+ sd.setLocation("hdfs:///db1.db/table1");
+ NotificationEvent notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.DROP_TABLE.toString(),
+ messageFactory.buildDropTableMessage(new Table(tableName,
+ dbName, null, 0, 0, 0, sd, null, null, null, null, null)).toString());
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ TSentryAuthorizable authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb("db1");
+ authorizable.setTable(tableName);
+
+ verify(sentryStore, times(1)).deleteAllAuthzPathsMapping(Mockito.anyString(),
+ Mockito.any(UniquePathsUpdate.class));
+
+ verify(sentryStore, times(1)).dropPrivilege(authorizable,
+ NotificationProcessor.getPermUpdatableOnDrop(authorizable));
+ }
+
+ @Test
+ /*
+ Makes sure that appropriate sentry store methods are invoked when alter tables event is
+ processed.
+ */
+ public void testAlterTable() throws Exception {
+ String dbName = "db1";
+ String tableName = "table1";
+
+ String newDbName = "db1";
+ String newTableName = "table2";
+
+ Configuration authConf = new Configuration();
+ // enable HDFS sync, so perm and path changes will be saved into DB
+ authConf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
+ authConf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
+
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, authConf);
+
+ // Create notification event
+ StorageDescriptor sd = new StorageDescriptor();
+ sd.setLocation("hdfs:///db1.db/table1");
+ NotificationEvent notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.ALTER_TABLE.toString(),
+ messageFactory.buildAlterTableMessage(
+ new Table(tableName, dbName, null, 0, 0, 0, sd, null, null, null, null, null),
+ new Table(newTableName, newDbName, null, 0, 0, 0, sd, null, null, null, null, null))
+ .toString());
+ notificationEvent.setDbName(newDbName);
+ notificationEvent.setTableName(newTableName);
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ TSentryAuthorizable authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb(dbName);
+ authorizable.setTable(tableName);
+
+ TSentryAuthorizable newAuthorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ newAuthorizable.setDb(newDbName);
+ newAuthorizable.setTable(newTableName);
+
+ verify(sentryStore, times(1)).renameAuthzObj(Mockito.anyString(), Mockito.anyString(),
+ Mockito.any(UniquePathsUpdate.class));
+
+ verify(sentryStore, times(1)).renamePrivilege(authorizable, newAuthorizable,
+ NotificationProcessor.getPermUpdatableOnRename(authorizable, newAuthorizable));
+ }
+
+ @Test
+ /*
+ Makes sure that appropriate sentry store methods are invoked when alter tables event is
+ processed.
+ */
+ public void testRenameTableWithLocationUpdate() throws Exception {
+ String dbName = "db1";
+ String tableName = "table1";
+
+ String newDbName = "db1";
+ String newTableName = "table2";
+
+ Configuration authConf = new Configuration();
+ // enable HDFS sync, so perm and path changes will be saved into DB
+ authConf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
+ authConf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
+
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, authConf);
+
+ // Create notification event
+ StorageDescriptor sd = new StorageDescriptor();
+ sd.setLocation("hdfs:///db1.db/table1");
+ StorageDescriptor new_sd = new StorageDescriptor();
+ new_sd.setLocation("hdfs:///db1.db/table2");
+ NotificationEvent notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.ALTER_TABLE.toString(),
+ messageFactory.buildAlterTableMessage(
+ new Table(tableName, dbName, null, 0, 0, 0, sd, null, null, null, null, null),
+ new Table(newTableName, newDbName, null, 0, 0, 0, new_sd, null, null, null, null, null))
+ .toString());
+ notificationEvent.setDbName(newDbName);
+ notificationEvent.setTableName(newTableName);
+
+ notificationProcessor.processNotificationEvent(notificationEvent);
+
+ TSentryAuthorizable authorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ authorizable.setDb(dbName);
+ authorizable.setTable(tableName);
+
+ TSentryAuthorizable newAuthorizable = new TSentryAuthorizable(hiveInstance);
+ authorizable.setServer(hiveInstance);
+ newAuthorizable.setDb(newDbName);
+ newAuthorizable.setTable(newTableName);
+
+ verify(sentryStore, times(1)).renameAuthzPathsMapping(Mockito.anyString(), Mockito.anyString(),
+ Mockito.anyString(), Mockito.anyString(), Mockito.any(UniquePathsUpdate.class));
+
+ verify(sentryStore, times(1)).renamePrivilege(authorizable, newAuthorizable,
+ NotificationProcessor.getPermUpdatableOnRename(authorizable, newAuthorizable));
+ }
+
+ @Test
+ /*
+ Test to made sure that sentry store is not invoked when invalid alter table event is
+ processed.
+ */
+ public void testAlterTableWithInvalidEvent() throws Exception {
+ String dbName = "db1";
+ String tableName1 = "table1";
+ String tableName2 = "table2";
+ long inputEventId = 1;
+ NotificationEvent notificationEvent;
+ List<FieldSchema> partCols;
+ StorageDescriptor sd;
+ Mockito.doNothing().when(sentryStore).persistLastProcessedNotificationID(Mockito.anyLong());
+ //noinspection unchecked
+ Mockito.doNothing().when(sentryStore).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+
+ Configuration authConf = new Configuration();
+ // enable HDFS sync, so perm and path changes will be saved into DB
+ authConf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
+ authConf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
+
+ notificationProcessor = new NotificationProcessor(sentryStore,
+ hiveInstance, authConf);
+
+ // Create a table
+ sd = new StorageDescriptor();
+ sd.setLocation("hdfs://db1.db/table1");
+ partCols = new ArrayList<>();
+ partCols.add(new FieldSchema("ds", "string", ""));
+ Table table = new Table(tableName1, dbName, null, 0, 0, 0, sd, partCols,
+ null, null, null, null);
+ notificationEvent = new NotificationEvent(inputEventId, 0,
+ EventMessage.EventType.CREATE_TABLE.toString(),
+ messageFactory.buildCreateTableMessage(table, Collections.emptyIterator()).toString());
+ notificationEvent.setDbName(dbName);
+ notificationEvent.setTableName(tableName1);
+ inputEventId += 1;
+ // Process the notification
+ notificationProcessor.processNotificationEvent(notificationEvent);
+ // Make sure that addAuthzPathsMapping was invoked once to handle CREATE_TABLE notification
+ // and persistLastProcessedNotificationID was not invoked.
+ //noinspection unchecked
+ verify(sentryStore, times(1)).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ reset(sentryStore);
+
+ // Create alter table notification with out actually changing anything.
+ // This notification should not be processed by sentry server
+ // Notification should be persisted explicitly
+ notificationEvent = new NotificationEvent(1, 0,
+ EventMessage.EventType.ALTER_TABLE.toString(),
+ messageFactory.buildAlterTableMessage(
+ new Table(tableName1, dbName, null, 0, 0, 0, sd, null, null, null, null, null),
+ new Table(tableName1, dbName, null, 0, 0, 0, sd, null,
+ null, null, null, null)).toString());
+ notificationEvent.setDbName(dbName);
+ notificationEvent.setTableName(tableName1);
+ inputEventId += 1;
+ // Process the notification
+ notificationProcessor.processNotificationEvent(notificationEvent);
+ // Make sure that renameAuthzObj and deleteAuthzPathsMapping were not invoked
+ // to handle CREATE_TABLE notification
+ // and persistLastProcessedNotificationID is explicitly invoked
+ verify(sentryStore, times(0)).renameAuthzObj(Mockito.anyString(), Mockito.anyString(),
+ Mockito.any(UniquePathsUpdate.class));
+ //noinspection unchecked
+ verify(sentryStore, times(0)).deleteAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ reset(sentryStore);
+
+ // Create a table
+ sd = new StorageDescriptor();
+ sd.setLocation("hdfs://db1.db/table2");
+ partCols = new ArrayList<>();
+ partCols.add(new FieldSchema("ds", "string", ""));
+ Table table1 = new Table(tableName2, dbName, null, 0, 0, 0, sd,
+ partCols, null, null, null, null);
+ notificationEvent = new NotificationEvent(inputEventId, 0,
+ EventMessage.EventType.CREATE_TABLE.toString(),
+ messageFactory.buildCreateTableMessage(table1, Collections.emptyIterator()).toString());
+ notificationEvent.setDbName(dbName);
+ notificationEvent.setTableName(tableName2);
+ // Process the notification
+ notificationProcessor.processNotificationEvent(notificationEvent);
+ // Make sure that addAuthzPathsMapping was invoked once to handle CREATE_TABLE notification
+ // and persistLastProcessedNotificationID was not invoked.
+ //noinspection unchecked
+ verify(sentryStore, times(1)).addAuthzPathsMapping(Mockito.anyString(),
+ Mockito.anyCollection(), Mockito.any(UniquePathsUpdate.class));
+ }
+}
http://git-wip-us.apache.org/repos/asf/sentry/blob/9351d19d/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryPrivilege.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryPrivilege.java
new file mode 100644
index 0000000..c31233b
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryPrivilege.java
@@ -0,0 +1,245 @@
+/**
+ * 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.sentry.provider.db.service.persistent;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
+import org.junit.Test;
+
+public class TestSentryPrivilege {
+ @Test
+ public void testImpliesPrivilegePositive() throws Exception {
+ // 1.test server+database+table+action
+ MSentryPrivilege my = new MSentryPrivilege();
+ MSentryPrivilege your = new MSentryPrivilege();
+ my.setServerName("server1");
+ my.setDbName("db1");
+ my.setTableName("tb1");
+ my.setAction(AccessConstants.SELECT);
+ your.setServerName("server1");
+ your.setDbName("db1");
+ your.setTableName("tb1");
+ your.setAction(AccessConstants.SELECT);
+ assertTrue(my.implies(your));
+
+ my.setAction(AccessConstants.ALL);
+ assertTrue(my.implies(your));
+
+ my.setTableName("");
+ assertTrue(my.implies(your));
+
+ my.setDbName("");
+ assertTrue(my.implies(your));
+
+ my.setAction(AccessConstants.ACTION_ALL);
+ assertTrue(my.implies(your));
+
+ my.setTableName("");
+ assertTrue(my.implies(your));
+
+ my.setDbName("");
+ assertTrue(my.implies(your));
+
+ // 2.test server+URI+action using all combinations of * and ALL for action
+ String[][] actionMap = new String[][] {
+ { AccessConstants.ALL, AccessConstants.ALL },
+ { AccessConstants.ALL, AccessConstants.ACTION_ALL },
+ { AccessConstants.ACTION_ALL, AccessConstants.ALL },
+ { AccessConstants.ACTION_ALL, AccessConstants.ACTION_ALL } };
+
+ for (int actions = 0; actions < actionMap.length; actions++) {
+ my = new MSentryPrivilege();
+ your = new MSentryPrivilege();
+ my.setServerName("server1");
+ my.setAction(actionMap[actions][0]);
+ your.setServerName("server1");
+ your.setAction(actionMap[actions][1]);
+ my.setURI("hdfs://namenode:9000/path");
+ your.setURI("hdfs://namenode:9000/path");
+ assertTrue(my.implies(your));
+
+ my.setURI("hdfs://namenode:9000/path");
+ your.setURI("hdfs://namenode:9000/path/to/some/dir");
+ assertTrue(my.implies(your));
+
+ my.setURI("file:///path");
+ your.setURI("file:///path");
+ assertTrue(my.implies(your));
+
+ my.setURI("file:///path");
+ your.setURI("file:///path/to/some/dir");
+ assertTrue(my.implies(your));
+
+ // my is SERVER level privilege, your is URI level privilege
+ my.setURI("");
+ your.setURI("file:///path");
+ assertTrue(my.implies(your));
+ }
+ }
+
+ @Test
+ public void testImpliesPrivilegeNegative() throws Exception {
+ // 1.test server+database+table+action
+ MSentryPrivilege my = new MSentryPrivilege();
+ MSentryPrivilege your = new MSentryPrivilege();
+ // bad action
+ my.setServerName("server1");
+ my.setDbName("db1");
+ my.setTableName("tb1");
+ my.setAction(AccessConstants.SELECT);
+ your.setServerName("server1");
+ your.setDbName("db1");
+ your.setTableName("tb1");
+ your.setAction(AccessConstants.INSERT);
+ assertFalse(my.implies(your));
+
+ // bad action
+ your.setAction(AccessConstants.ALL);
+ assertFalse(my.implies(your));
+
+
+ // bad table
+ your.setTableName("tb2");
+ assertFalse(my.implies(your));
+
+ // bad database
+ your.setTableName("tb1");
+ your.setDbName("db2");
+ assertFalse(my.implies(your));
+
+ // bad server
+ your.setTableName("tb1");
+ your.setDbName("db1");
+ your.setServerName("server2");
+ assertFalse(my.implies(your));
+
+ // 2.test server+URI+action
+ my = new MSentryPrivilege();
+ your = new MSentryPrivilege();
+ my.setServerName("server1");
+ my.setAction(AccessConstants.ALL);
+ your.setServerName("server2");
+ your.setAction(AccessConstants.ALL);
+
+ // relative path
+ my.setURI("hdfs://namenode:9000/path");
+ your.setURI("hdfs://namenode:9000/path/to/../../other");
+ assertFalse(my.implies(your));
+ my.setURI("file:///path");
+ your.setURI("file:///path/to/../../other");
+ assertFalse(my.implies(your));
+
+ // bad uri
+ my.setURI("blah");
+ your.setURI("hdfs://namenode:9000/path/to/some/dir");
+ assertFalse(my.implies(your));
+ my.setURI("hdfs://namenode:9000/path/to/some/dir");
+ your.setURI("blah");
+ assertFalse(my.implies(your));
+
+ // bad scheme
+ my.setURI("hdfs://namenode:9000/path");
+ your.setURI("file:///path/to/some/dir");
+ assertFalse(my.implies(your));
+ my.setURI("hdfs://namenode:9000/path");
+ your.setURI("file://namenode:9000/path/to/some/dir");
+ assertFalse(my.implies(your));
+
+ // bad hostname
+ my.setURI("hdfs://namenode1:9000/path");
+ your.setURI("hdfs://namenode2:9000/path");
+ assertFalse(my.implies(your));
+
+ // bad port
+ my.setURI("hdfs://namenode:9000/path");
+ your.setURI("hdfs://namenode:9001/path");
+ assertFalse(my.implies(your));
+
+ // bad path
+ my.setURI("hdfs://namenode:9000/path1");
+ your.setURI("hdfs://namenode:9000/path2");
+ assertFalse(my.implies(your));
+ my.setURI("file:///path1");
+ your.setURI("file:///path2");
+ assertFalse(my.implies(your));
+
+ // bad server
+ your.setServerName("server2");
+ my.setURI("hdfs://namenode:9000/path1");
+ your.setURI("hdfs://namenode:9000/path1");
+ assertFalse(my.implies(your));
+
+ // bad implies
+ my.setServerName("server1");
+ my.setURI("hdfs://namenode:9000/path1");
+ your.setServerName("server1");
+ your.setURI("");
+ assertFalse(my.implies(your));
+ }
+
+ @Test
+ public void testImpliesPrivilegePositiveWithColumn() throws Exception {
+ // 1.test server+database+table+column+action
+ MSentryPrivilege my = new MSentryPrivilege();
+ MSentryPrivilege your = new MSentryPrivilege();
+ my.setServerName("server1");
+ my.setAction(AccessConstants.SELECT);
+ your.setServerName("server1");
+ your.setDbName("db1");
+ your.setTableName("tb1");
+ your.setColumnName("c1");
+ your.setAction(AccessConstants.SELECT);
+ assertTrue(my.implies(your));
+
+ my.setDbName("db1");
+ assertTrue(my.implies(your));
+
+ my.setTableName("tb1");
+ assertTrue(my.implies(your));
+
+ my.setColumnName("c1");
+ assertTrue(my.implies(your));
+ }
+
+ @Test
+ public void testImpliesPrivilegeNegativeWithColumn() throws Exception {
+ // 1.test server+database+table+column+action
+ MSentryPrivilege my = new MSentryPrivilege();
+ MSentryPrivilege your = new MSentryPrivilege();
+ // bad column
+ my.setServerName("server1");
+ my.setDbName("db1");
+ my.setTableName("tb1");
+ my.setColumnName("c1");
+ my.setAction(AccessConstants.SELECT);
+ your.setServerName("server1");
+ your.setDbName("db1");
+ your.setTableName("tb1");
+ your.setColumnName("c2");
+ your.setAction(AccessConstants.SELECT);
+ assertFalse(my.implies(your));
+
+ // bad scope
+ your.setColumnName("");
+ assertFalse(my.implies(your));
+ }
+}