/* See LICENSE for licensing and NOTICE for copyright. */ package org.ldaptive; import org.ldaptive.provider.Provider; import org.testng.annotations.AfterSuite; import org.testng.annotations.BeforeSuite; import org.testng.annotations.Parameters; /** * Contains functions that run before and after all tests. * * @author Middleware Services */ public class TestControl { /** Attribute to block on. */ public static final LdapAttribute ATTR_IDLE = new LdapAttribute("mail", "test-idle@ldaptive.org"); /** Attribute to block on. */ public static final LdapAttribute ATTR_RUNNING = new LdapAttribute("mail", "test-running@ldaptive.org"); /** Time to wait before checking if lock is available. */ public static final int WAIT_TIME = 60000; /** Type of directory being tested. */ private static String directoryType; /** Type of provider being tested. */ private static String providerType; /** * Used by tests to determine if Active Directory is being tested. * * @return whether active directory is being tested */ public static boolean isActiveDirectory() { return "ACTIVE_DIRECTORY".equals(directoryType); } /** * Used by tests to determine if Oracle Directory server is being tested. * * @return whether oracle directory server is being tested */ public static boolean isOracleDirectory() { return "ORACLE".equals(directoryType); } /** * Used by tests to determine if the JNDI provider is being tested. * * @return whether the jndi provider is being tested */ public static boolean isJndiProvider() { return "JNDI".equals(providerType); } /** * Used by tests to determine if the Apache provider is being tested. * * @return whether the apache provider is being tested */ public static boolean isApacheProvider() { return "APACHE".equals(providerType); } /** * Used by tests to determine if the OpenDJ provider is being tested. * * @return whether the opendj provider is being tested */ public static boolean isOpenDJProvider() { return "OPENDJ".equals(providerType); } /** * Obtains the lock before running all tests. * * @param ignoreLock whether to check for the global test lock * @param bindDn to lock on * * @throws Exception on test failure */ @BeforeSuite(alwaysRun = true) @Parameters({ "ldapTestsIgnoreLock", "ldapBindDn" }) public void setup(final String ignoreLock, final String bindDn) throws Exception { final Provider<?> provider = DefaultConnectionFactory.getDefaultProvider(); if (provider.getClass().getName().contains("Jndi")) { providerType = "JNDI"; } else if (provider.getClass().getName().contains("Apache")) { providerType = "APACHE"; } else if (provider.getClass().getName().contains("JLdap")) { providerType = "JLDAP"; } else if (provider.getClass().getName().contains("OpenDJ")) { providerType = "OPENDJ"; } else if (provider.getClass().getName().contains("UnboundID")) { providerType = "UNBOUNDID"; } else { throw new IllegalStateException("Unknown provider: " + provider); } final Connection conn = TestUtils.createSetupConnection(); if (!Boolean.valueOf(ignoreLock)) { boolean isTestRunning = true; // wait for other tests to finish int i = 1; while (isTestRunning) { try { conn.open(); final CompareOperation compare = new CompareOperation(conn); isTestRunning = !compare.execute(new CompareRequest(bindDn, ATTR_IDLE)).getResult(); } finally { conn.close(); if (isTestRunning) { System.err.println("Waiting for test lock..."); Thread.sleep(WAIT_TIME * i++); } } } } try { conn.open(); final ModifyOperation modify = new ModifyOperation(conn); modify.execute( new ModifyRequest(bindDn, new AttributeModification(AttributeModificationType.REPLACE, ATTR_RUNNING))); if (isAD(conn, bindDn)) { directoryType = "ACTIVE_DIRECTORY"; } else if (isOracle(conn)) { directoryType = "ORACLE"; } else { directoryType = "LDAP"; } } finally { conn.close(); } } /** * Performs an object level search for the sAMAccountName attribute used by Active Directory. * * @param conn to perform compare with * @param bindDn to perform search on * * @return whether the supplied entry is in active directory * * @throws Exception On failure. */ protected boolean isAD(final Connection conn, final String bindDn) throws Exception { final SearchOperation search = new SearchOperation(conn); final SearchRequest request = SearchRequest.newObjectScopeSearchRequest( bindDn, ReturnAttributes.NONE.value(), new SearchFilter("(sAMAccountName=*)")); try { return search.execute(request).getResult().size() == 1; } catch (LdapException e) { if (ResultCode.NO_SUCH_OBJECT == e.getResultCode() || ResultCode.NO_SUCH_ATTRIBUTE == e.getResultCode()) { return false; } throw e; } } /** * Performs an object level search on the root DSE for the vendorName attribute used by Oracle DS. * * @param conn to perform compare with * * @return whether the supplied entry contains a vendorName attribute identified by Oracle * * @throws Exception On failure. */ protected boolean isOracle(final Connection conn) throws Exception { final SearchOperation search = new SearchOperation(conn); final SearchRequest request = SearchRequest.newObjectScopeSearchRequest("", new String[] {"vendorName"}); try { final LdapEntry rootDSE = search.execute(request).getResult().getEntry(); return rootDSE.getAttribute("vendorName") != null && rootDSE.getAttribute("vendorName").getStringValue().contains("Oracle"); } catch (LdapException e) { if (ResultCode.NO_SUCH_OBJECT == e.getResultCode() || ResultCode.NO_SUCH_ATTRIBUTE == e.getResultCode()) { return false; } throw e; } } /** * Releases the lock after running all tests. * * @param bindDn to lock on * * @throws Exception on test failure */ @AfterSuite(alwaysRun = true) @Parameters("ldapBindDn") public void teardown(final String bindDn) throws Exception { try (Connection conn = TestUtils.createSetupConnection()) { conn.open(); // set attribute when tests are finished final ModifyOperation modify = new ModifyOperation(conn); modify.execute( new ModifyRequest(bindDn, new AttributeModification(AttributeModificationType.REPLACE, ATTR_IDLE))); } } }