/** * 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.hive.service.auth.ldap; import java.util.AbstractCollection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.SearchResult; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.apache.hive.service.auth.ldap.LdapTestUtils.*; @RunWith(MockitoJUnitRunner.class) public class TestSearchResultHandler { SearchResultHandler handler; @Test public void testHandle() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1") .addSearchResultWithDns("2", "3"); handler = new SearchResultHandler(resultCollection); List<String> expected = Arrays.asList("1", "2"); final List<String> actual = new ArrayList<>(); handler.handle(new SearchResultHandler.RecordProcessor() { @Override public boolean process(SearchResult record) throws NamingException { actual.add(record.getNameInNamespace()); return actual.size() < 2; } }); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testGetAllLdapNamesNoRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult(); handler = new SearchResultHandler(resultCollection); List<String> actual = handler.getAllLdapNames(); assertEquals("Resultset size", 0, actual.size()); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testGetAllLdapNamesWithExceptionInNamingEnumerationClose() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1") .addSearchResultWithDns("2"); doThrow(NamingException.class).when(resultCollection.iterator().next()).close(); handler = new SearchResultHandler(resultCollection); List<String> actual = handler.getAllLdapNames(); assertEquals("Resultset size", 2, actual.size()); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testGetAllLdapNames() throws NamingException { String objectDn1 = "cn=a1,dc=b,dc=c"; String objectDn2 = "cn=a2,dc=b,dc=c"; String objectDn3 = "cn=a3,dc=b,dc=c"; MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns(objectDn1) .addSearchResultWithDns(objectDn2, objectDn3); handler = new SearchResultHandler(resultCollection); List<String> expected = Arrays.asList(objectDn1, objectDn2, objectDn3); Collections.sort(expected); List<String> actual = handler.getAllLdapNames(); Collections.sort(actual); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testGetAllLdapNamesAndAttributes() throws NamingException { SearchResult searchResult1 = mockSearchResult("cn=a1,dc=b,dc=c", mockAttributes("attr1", "attr1value1")); SearchResult searchResult2 = mockSearchResult("cn=a2,dc=b,dc=c", mockAttributes("attr1", "attr1value2", "attr2", "attr2value1")); SearchResult searchResult3 = mockSearchResult("cn=a3,dc=b,dc=c", mockAttributes("attr1", "attr1value3", "attr1", "attr1value4")); SearchResult searchResult4 = mockSearchResult("cn=a4,dc=b,dc=c", mockEmptyAttributes()); MockResultCollection resultCollection = MockResultCollection.create() .addSearchResults(searchResult1) .addSearchResults(searchResult2, searchResult3) .addSearchResults(searchResult4); handler = new SearchResultHandler(resultCollection); List<String> expected = Arrays.asList( "cn=a1,dc=b,dc=c", "attr1value1", "cn=a2,dc=b,dc=c", "attr1value2", "attr2value1", "cn=a3,dc=b,dc=c", "attr1value3", "attr1value4", "cn=a4,dc=b,dc=c"); Collections.sort(expected); List<String> actual = handler.getAllLdapNamesAndAttributes(); Collections.sort(actual); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testHasSingleResultNoRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult(); handler = new SearchResultHandler(resultCollection); assertFalse(handler.hasSingleResult()); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testHasSingleResult() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1"); handler = new SearchResultHandler(resultCollection); assertTrue(handler.hasSingleResult()); assertAllNamingEnumerationsClosed(resultCollection); } @Test public void testHasSingleResultManyRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addSearchResultWithDns("1") .addSearchResultWithDns("2"); handler = new SearchResultHandler(resultCollection); assertFalse(handler.hasSingleResult()); assertAllNamingEnumerationsClosed(resultCollection); } @Test(expected = NamingException.class) public void testGetSingleLdapNameNoRecords() throws NamingException { MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult(); handler = new SearchResultHandler(resultCollection); try { handler.getSingleLdapName(); } finally { assertAllNamingEnumerationsClosed(resultCollection); } } @Test public void testGetSingleLdapName() throws NamingException { String objectDn = "cn=a,dc=b,dc=c"; MockResultCollection resultCollection = MockResultCollection.create() .addEmptySearchResult() .addSearchResultWithDns(objectDn); handler = new SearchResultHandler(resultCollection); String expected = objectDn; String actual = handler.getSingleLdapName(); assertEquals(expected, actual); assertAllNamingEnumerationsClosed(resultCollection); } private void assertAllNamingEnumerationsClosed(MockResultCollection resultCollection) throws NamingException { for (NamingEnumeration<SearchResult> namingEnumeration : resultCollection) { verify(namingEnumeration, atLeastOnce()).close(); } } private static final class MockResultCollection extends AbstractCollection<NamingEnumeration<SearchResult>> { List<NamingEnumeration<SearchResult>> results = new ArrayList<>(); static MockResultCollection create() { return new MockResultCollection(); } MockResultCollection addSearchResultWithDns(String... dns) throws NamingException { results.add(mockNamingEnumeration(dns)); return this; } MockResultCollection addSearchResults(SearchResult... dns) throws NamingException { results.add(mockNamingEnumeration(dns)); return this; } MockResultCollection addEmptySearchResult() throws NamingException { addSearchResults(); return this; } @Override public Iterator<NamingEnumeration<SearchResult>> iterator() { return results.iterator(); } @Override public int size() { return results.size(); } } }