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)); + } +}
