def test_max_lifetime(self):
        if not LDAP:
            return

        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        pool = ConnectionManager('ldap://localhost',
                                 dn,
                                 passwd,
                                 max_lifetime=0.5,
                                 use_pool=True)

        with pool.connection('bind', 'password') as conn:
            self.assertTrue(conn.active)

        self.assertFalse(conn.active)
        self.assertTrue(conn.connected)

        # same bind and password: reuse
        with pool.connection('bind', 'passwd') as conn2:
            self.assertTrue(conn2.active)

        self.assertTrue(conn is conn2)

        time.sleep(0.6)

        # same bind and password, but max lifetime reached: new one
        with pool.connection('bind', 'passwd') as conn3:
            self.assertTrue(conn3.active)

        self.assertTrue(conn3 is not conn2)
        self.assertTrue(conn3 is not conn)
    def test_pool_full(self):
        if not LDAP:
            return
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        pool = ConnectionManager('ldap://localhost',
                                 dn,
                                 passwd,
                                 size=1,
                                 retry_delay=1.,
                                 retry_max=5,
                                 use_pool=True)

        class Worker(threading.Thread):
            def __init__(self, pool, duration):
                threading.Thread.__init__(self)
                self.pool = pool
                self.duration = duration

            def run(self):
                with self.pool.connection() as conn:  # NOQA
                    time.sleep(self.duration)

        def tryit():
            with pool.connection() as conn:  # NOQA
                pass

        # an attempt on a full pool should eventually work
        # because the connector is reused
        for i in range(10):
            tryit()

        # we have 1 non-active connector now
        self.assertEqual(len(pool), 1)

        # an attempt with a full pool should succeed if a
        # slot gets freed in less than one second.
        worker1 = Worker(pool, .4)
        worker1.start()

        try:
            tryit()
        finally:
            worker1.join()

        # an attempt with a full pool should fail
        # if no slot gets freed in less than one second.
        worker1 = Worker(pool, 1.1)
        worker1.start()
        time.sleep(0.1)
        try:
            self.assertRaises(MaxConnectionReachedError, tryit)
        finally:
            worker1.join()

        # we still have one active connector
        self.assertEqual(len(pool), 1)
Ejemplo n.º 3
0
    def test_connection(self):
        if not LDAP:
            return

        uri = ''
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        cm = ConnectionManager(uri, dn, passwd, use_pool=True, size=2)
        self.assertEqual(len(cm), 0)

        with cm.connection('dn', 'pass'):
            self.assertEqual(len(cm), 1)

            # if we ask a new one the pool will grow
            with cm.connection('dn', 'pass'):
                self.assertEqual(len(cm), 2)

                # every connector is marked active
                self.assertTrue(cm._pool[0].active)
                self.assertTrue(cm._pool[1].active)

                # if we ask a new one the pool is full
                try:
                    with cm.connection('dn', 'pass'):
                        pass
                except MaxConnectionReachedError:
                    pass
                else:
                    raise AssertionError()

            # down to one active
            self.assertFalse(cm._pool[1].active)
            self.assertTrue(cm._pool[0].active)

            # if we ask a new one the pool is full
            # but we get the inactive one
            with cm.connection('dn', 'pass'):
                self.assertEqual(len(cm), 2)

            self.assertFalse(cm._pool[1].active)
            self.assertTrue(cm._pool[0].active)

            # if we ask a new one the pool is full
            # but we get the inactive one, and rebind it
            with cm.connection('dn2', 'pass'):
                self.assertEqual(len(cm), 2)

        # the pool is still 2
        self.assertEqual(len(cm), 2)

        # every connector is marked inactive
        self.assertFalse(cm._pool[0].active)
        self.assertFalse(cm._pool[1].active)
    def test_pool_reuse(self):
        if not LDAP:
            return
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        pool = ConnectionManager('ldap://localhost', dn, passwd, use_pool=True)

        with pool.connection() as conn:
            self.assertTrue(conn.active)

        self.assertFalse(conn.active)
        self.assertTrue(conn.connected)

        with pool.connection() as conn2:
            pass

        self.assertTrue(conn is conn2)

        with pool.connection() as conn:
            conn.connected = False

        with pool.connection() as conn2:
            pass

        self.assertTrue(conn is not conn2)

        # same bind and password: reuse
        with pool.connection('bind', 'passwd') as conn:
            self.assertTrue(conn.active)

        self.assertFalse(conn.active)
        self.assertTrue(conn.connected)

        with pool.connection('bind', 'passwd') as conn2:
            pass

        self.assertTrue(conn is conn2)

        # same bind different password, inactive: rebind
        with pool.connection('bind', 'passwd') as conn:
            self.assertTrue(conn.active)

        self.assertFalse(conn.active)
        self.assertTrue(conn.connected)

        with pool.connection('bind', 'passwd2') as conn2:
            pass

        self.assertTrue(conn is conn2)
Ejemplo n.º 5
0
    def __init__(self,
                 ldapuri,
                 allow_new_users=True,
                 users_root='ou=users,dc=mozilla',
                 check_account_state=True,
                 ldap_timeout=10,
                 search_root='dc=mozilla',
                 **kw):
        self.allow_new_users = allow_new_users
        self.check_account_state = check_account_state
        self.users_root = users_root
        self.search_root = search_root
        self.ldap_timeout = ldap_timeout
        self.logger = CLIENT_HOLDER.default_client

        kw.pop("check_node", None)
        self.conn = ConnectionManager(ldapuri, **kw)
    def test_pool(self):
        if not LDAP:
            return
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        pool = ConnectionManager('ldap://localhost', dn, passwd, use_pool=True)

        workers = [LDAPWorker(pool) for i in range(10)]

        for worker in workers:
            worker.start()

        for worker in workers:
            worker.join()
            self.assertEquals(len(worker.results), 10)
            cn = worker.results[0][0][1]['cn']
            self.assertEquals(cn, ['admin'])
Ejemplo n.º 7
0
    def test_simple_bind_fails_proper_msg(self):
        if not LDAP:
            return

        # the binding fails with an LDAPError
        StateConnector.simple_bind_s = _bind_fails2
        uri = ''
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        cm = ConnectionManager(uri, dn, passwd, use_pool=True, size=2)
        self.assertEqual(len(cm), 0)
        try:
            with cm.connection('dn', 'pass'):
                pass
        except BackendError, err:
            wanted = ("BackendError\nLDAP Connector (disconnected)\n\n"
                      "I am down")
            self.assertEqual(wanted, str(err))
    def test_pool_cleanup(self):
        if not LDAP:
            return
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        pool = ConnectionManager('ldap://localhost',
                                 dn,
                                 passwd,
                                 size=1,
                                 use_pool=True)
        with pool.connection('bind1') as conn:  # NOQA
            pass

        with pool.connection('bind2') as conn:  # NOQA
            pass

        # the second call should have removed the first conn
        self.assertEqual(len(pool), 1)
Ejemplo n.º 9
0
    def test_timeout_retry(self):
        if not LDAP:
            return

        # the binding fails with an LDAPError
        StateConnector.simple_bind_s = _bind_fails3
        uri = ''
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        cm = ConnectionManager(uri, dn, passwd, use_pool=True, size=2)
        self.assertEqual(len(cm), 0)

        counter = _CALL_COUNTER
        try:
            with cm.connection('dn', 'pass'):
                pass
        except BackendError, err:
            wanted = 'BackendTimeoutError\n\nBoo'
            self.assertEqual(wanted, str(err))
Ejemplo n.º 10
0
    def test_simple_bind_fails(self):
        if not LDAP:
            return

        # the binding fails with an LDAPError
        StateConnector.simple_bind_s = _bind_fails
        uri = 'ldap://localhost:2222'
        dn = 'uid=adminuser,ou=logins,dc=mozilla'
        passwd = 'adminuser'
        cm = ConnectionManager(uri, dn, passwd, use_pool=True, size=2)
        self.assertEqual(len(cm), 0)
        wanted = ("LDAP Connector (disconnected) - who: 'dn' - uri: "
                  "'ldap://localhost:2222'")
        wanted2 = ("BackendError\nLDAP Connector (disconnected) - "
                   "who: 'dn' - uri: 'ldap://localhost:2222'\n\n"
                   "LDAP connection invalid")
        try:
            with cm.connection('dn', 'pass'):
                pass
        except BackendError, e:
            self.assertEqual(str(e.backend), wanted)
            self.assertEqual(str(e), wanted2)
    def __init__(self,
                 ldapuri,
                 sqluri,
                 use_tls=False,
                 bind_user='******',
                 bind_password='******',
                 admin_user='******',
                 admin_password='******',
                 users_root='ou=users,dc=mozilla',
                 users_base_dn=None,
                 pool_size=100,
                 pool_recycle=3600,
                 reset_on_return=True,
                 single_box=False,
                 ldap_timeout=-1,
                 nodes_scheme='https',
                 check_account_state=True,
                 create_tables=False,
                 ldap_pool_size=10,
                 ldap_use_pool=False,
                 connector_cls=StateConnector,
                 check_node=False,
                 ldap_max_lifetime=600,
                 **kw):
        self.check_account_state = check_account_state
        self.ldapuri = ldapuri
        self.sqluri = sqluri
        self.bind_user = bind_user
        self.bind_password = bind_password
        self.admin_user = admin_user
        self.admin_password = admin_password
        self.use_tls = use_tls
        self.users_root = users_root
        self.users_base_dn = users_base_dn
        self.single_box = single_box
        self.nodes_scheme = nodes_scheme
        self.ldap_timeout = ldap_timeout
        # by default, the ldap connections use the bind user
        self.conn = ConnectionManager(ldapuri,
                                      bind_user,
                                      bind_password,
                                      use_tls=use_tls,
                                      timeout=ldap_timeout,
                                      size=ldap_pool_size,
                                      use_pool=ldap_use_pool,
                                      connector_cls=connector_cls,
                                      max_lifetime=ldap_max_lifetime)
        sqlkw = {
            'pool_size': int(pool_size),
            'pool_recycle': int(pool_recycle),
            'logging_name': 'weaveserver'
        }

        if self.sqluri is not None:
            driver = urlparse.urlparse(self.sqluri).scheme.lower()
            if "mysql" in driver:
                sqlkw['pool_reset_on_return'] = reset_on_return
            engine = create_engine(sqluri, **sqlkw)
            for table in tables:
                table.metadata.bind = engine
                if create_tables:
                    table.create(checkfirst=True)
        else:
            engine = None

        self.check_node = check_node
        self.logger = CLIENT_HOLDER.default_client
        ResetCodeManager.__init__(self, engine, create_tables=create_tables)