@Test
public void testFilterKeyValueCell_happyPath() throws IOException {

	// null/empty column collection in cache for a family implies family level access
	String[] allowedFamilies = new String[] { "family1", "family2" };
	String[] deniedFamilies = new String[] { "family3", "family4" };
	String[] indeterminateFamilies = new String[] { "family5", "family6" };
	Set<String> familiesAccessAllowed = ImmutableSet.copyOf(allowedFamilies);
	Set<String> familiesAccessDenied = ImmutableSet.copyOf(deniedFamilies);
	Set<String> familiesAccessIndeterminate = ImmutableSet.copyOf(indeterminateFamilies);
	Map<String, Set<String>> columnsAccessAllowed = new HashMap<String, Set<String>>();
	String[] family7KnowGoodColumns = new String[] {"family7-column1", "family7-column2"};
	columnsAccessAllowed.put("family7", ImmutableSet.copyOf(family7KnowGoodColumns));
	String[] family8KnowGoodColumns = new String[] {"family8-column1", "family8-column2"};
	columnsAccessAllowed.put("family8", ImmutableSet.copyOf(family8KnowGoodColumns));
	// auth session
	AuthorizationSession session = createSessionMock();
	RangerAuthorizationFilter filter = new RangerAuthorizationFilter(session, familiesAccessAllowed, familiesAccessDenied, familiesAccessIndeterminate, columnsAccessAllowed);
	// evaluate access for various types of cases
	Cell aCell = mock(Cell.class);
	// families with know denied acess
	for (String family : deniedFamilies) {
		setFamilyArray(aCell, family.getBytes());
		setQualifierArray(aCell, new byte[0]);
		assertEquals(ReturnCode.NEXT_COL, filter.filterKeyValue(aCell));
	}
	// family that isn't in allowed and if cell does not have column then it should be denied
	setFamilyArray(aCell, "family7".getBytes());
	setQualifierArray(aCell, new byte[0]);
	assertEquals(ReturnCode.NEXT_COL, filter.filterKeyValue(aCell));
	// families with known partial access
	for (String column : family7KnowGoodColumns ) {
		setQualifierArray(aCell, column.getBytes());
		assertEquals(ReturnCode.INCLUDE, filter.filterKeyValue(aCell));
	}
	setFamilyArray(aCell, "family8".getBytes());
	for (String column : family8KnowGoodColumns ) {
		setQualifierArray(aCell, column.getBytes());
		assertEquals(ReturnCode.INCLUDE, filter.filterKeyValue(aCell));
	}
	// try some columns that are not in the cache
	for (String column : new String[] { "family8-column3", "family8-column4"}) {
		setQualifierArray(aCell, column.getBytes());
		assertEquals(ReturnCode.NEXT_COL, filter.filterKeyValue(aCell));
	}
	// families with known allowed access - for these we need to doctor up the session
	when(session.isAuthorized()).thenReturn(true);
	for (String family : allowedFamilies) {
		setFamilyArray(aCell, family.getBytes());
		setQualifierArray(aCell, "some-column".getBytes());
		assertEquals(ReturnCode.INCLUDE, filter.filterKeyValue(aCell));
	}
	when(session.isAuthorized()).thenReturn(false);
	for (String family : indeterminateFamilies) {
		setFamilyArray(aCell, family.getBytes());
		setQualifierArray(aCell, "some-column".getBytes());
		assertEquals(ReturnCode.NEXT_COL, filter.filterKeyValue(aCell));
	}
}