示例#1
0
    def test_getChangeUids_multi(self):
        yield self.insertTestData(self.change14_rows + self.change13_rows + [
            fakedb.User(uid=1, identifier="one"),
            fakedb.User(uid=2, identifier="two"),
            fakedb.User(uid=99, identifier="nooo"),
            fakedb.ChangeUser(changeid=14, uid=1),
            fakedb.ChangeUser(changeid=14, uid=2),
            fakedb.ChangeUser(changeid=13, uid=99),  # not selected
        ])
        res = yield self.db.changes.getChangeUids(14)

        self.assertEqual(sorted(res), [1, 2])
示例#2
0
 def test_getChangeUids_multi(self):
     d = self.insertTestData(self.change14_rows + self.change13_rows + [
             fakedb.User(uid=1, identifier="one"),
             fakedb.User(uid=2, identifier="two"),
             fakedb.User(uid=99, identifier="nooo"),
             fakedb.ChangeUser(changeid=14, uid=1),
             fakedb.ChangeUser(changeid=14, uid=2),
             fakedb.ChangeUser(changeid=13, uid=99), # not selected
         ])
     d.addCallback(lambda _ : self.db.changes.getChangeUids(14))
     def check(res):
         self.assertEqual(sorted(res), [1, 2])
     d.addCallback(check)
     return d
示例#3
0
    def test_addChange_with_uid(self):
        d = self.insertTestData([
            fakedb.User(uid=1, identifier="one"),
        ])
        d.addCallback(lambda _:
                      self.db.changes.addChange(
                          author=u'dustin',
                          files=[],
                          comments=u'fix spelling',
                          revision=u'2d6caa52',
                          when_timestamp=epoch2datetime(OTHERTIME),
                          branch=u'master',
                          category=None,
                          revlink=None,
                          properties={},
                          repository=u'',
                          codebase=u'',
                          project=u'',
                          uid=1))
        # check all of the columns of the five relevant tables

        def check_change(changeid):
            def thd(conn):
                r = conn.execute(self.db.model.changes.select())
                r = r.fetchall()
                self.assertEqual(len(r), 1)
                self.assertEqual(r[0].changeid, changeid)
                self.assertEqual(r[0].when_timestamp, OTHERTIME)
            return self.db.pool.do(thd)
        d.addCallback(check_change)

        def check_change_files(_):
            def thd(conn):
                query = self.db.model.change_files.select()
                r = conn.execute(query)
                r = r.fetchall()
                self.assertEqual(len(r), 0)
            return self.db.pool.do(thd)
        d.addCallback(check_change_files)

        def check_change_properties(_):
            def thd(conn):
                query = self.db.model.change_properties.select()
                r = conn.execute(query)
                r = r.fetchall()
                self.assertEqual(len(r), 0)
            return self.db.pool.do(thd)
        d.addCallback(check_change_properties)

        def check_change_users(_):
            def thd(conn):
                query = self.db.model.change_users.select()
                r = conn.execute(query)
                r = r.fetchall()
                self.assertEqual(len(r), 1)
                self.assertEqual(r[0].changeid, 1)
                self.assertEqual(r[0].uid, 1)
            return self.db.pool.do(thd)
        d.addCallback(check_change_users)
        return d
示例#4
0
    def test_getChangeUids_found(self):
        yield self.insertTestData(self.change14_rows + [
            fakedb.SourceStamp(id=92),
            fakedb.User(uid=1),
            fakedb.ChangeUser(changeid=14, uid=1),
        ])
        res = yield self.db.changes.getChangeUids(14)

        self.assertEqual(res, [1])
示例#5
0
 def test_getChangeUids_found(self):
     d = self.insertTestData(self.change14_rows + [
             fakedb.User(uid=1),
             fakedb.ChangeUser(changeid=14, uid=1),
         ])
     d.addCallback(lambda _ : self.db.changes.getChangeUids(14))
     def check(res):
         self.assertEqual(res, [1])
     d.addCallback(check)
     return d
示例#6
0
    def test_getUserContact_key_not_found(self):
        self.db.insertTestData([fakedb.User(uid=1, identifier='tdurden'),
                                fakedb.UserInfo(uid=1, attr_type='svn',
                                                attr_data='tdurden'),
                                fakedb.UserInfo(uid=1, attr_type='email',
                                                attr_data='*****@*****.**')])
        d = users.getUserContact(self.master, contact_types=['blargh'], uid=1)

        def check(contact):
            self.assertEqual(contact, None)
        d.addCallback(check)
        return d
    def test_getUserContact_found(self):
        self.db.insertTestData([
            fakedb.User(uid=1, identifier='tdurden'),
            fakedb.UserInfo(uid=1, attr_type='svn', attr_data='tdurden'),
            fakedb.UserInfo(uid=1,
                            attr_type='email',
                            attr_data='*****@*****.**')
        ])
        contact = yield users.getUserContact(self.master,
                                             contact_types=['email'],
                                             uid=1)

        self.assertEqual(contact, '*****@*****.**')
示例#8
0
class TestUsersConnectorComponent(connector_component.ConnectorComponentMixin,
                                  unittest.TestCase):
    def setUp(self):
        d = self.setUpConnectorComponent(table_names=[
            'users', 'users_info', 'changes', 'change_users', 'sourcestamps',
            'patches'
        ])

        def finish_setup(_):
            self.db.users = users.UsersConnectorComponent(self.db)

        d.addCallback(finish_setup)
        return d

    def tearDown(self):
        return self.tearDownConnectorComponent()

    # sample user data

    user1_rows = [
        fakedb.User(uid=1, identifier='soap'),
        fakedb.UserInfo(uid=1, attr_type='IPv9', attr_data='0578cc6.8db024'),
    ]

    user2_rows = [
        fakedb.User(uid=2, identifier='lye'),
        fakedb.UserInfo(uid=2,
                        attr_type='git',
                        attr_data='Tyler Durden <*****@*****.**>'),
        fakedb.UserInfo(uid=2, attr_type='irc', attr_data='durden')
    ]

    user3_rows = [
        fakedb.User(uid=3,
                    identifier='marla',
                    bb_username='******',
                    bb_password='******')
    ]

    user1_dict = {
        'uid': 1,
        'identifier': u'soap',
        'bb_username': None,
        'bb_password': None,
        'IPv9': u'0578cc6.8db024',
    }

    user2_dict = {
        'uid': 2,
        'identifier': u'lye',
        'bb_username': None,
        'bb_password': None,
        'irc': u'durden',
        'git': u'Tyler Durden <*****@*****.**>'
    }

    user3_dict = {
        'uid': 3,
        'identifier': u'marla',
        'bb_username': u'marla',
        'bb_password': u'cancer',
    }

    # tests

    def test_addUser_new(self):
        d = self.db.users.findUserByAttr(identifier='soap',
                                         attr_type='subspace_net_handle',
                                         attr_data='Durden0924')

        def check_user(uid):
            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
                self.assertEqual(infos[0].attr_data, 'Durden0924')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_existing(self):
        d = self.insertTestData(self.user1_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='soapy', attr_type='IPv9', attr_data='0578cc6.8db024'))

        def check_user(uid):
            self.assertEqual(uid, 1)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')  # not changed!
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'IPv9')
                self.assertEqual(infos[0].attr_data, '0578cc6.8db024')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_findUser_existing(self):
        d = self.insertTestData(self.user1_rows + self.user2_rows +
                                self.user3_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='lye',
            attr_type='git',
            attr_data='Tyler Durden <*****@*****.**>'))

        def check_user(uid):
            self.assertEqual(uid, 2)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual((sorted(
                    [tuple(u)
                     for u in users]), sorted([tuple(i) for i in infos])), ([
                         (1, u'soap', None, None),
                         (2, u'lye', None, None),
                         (3, u'marla', u'marla', u'cancer'),
                     ], [(1, u'IPv9', u'0578cc6.8db024'),
                         (2, u'git', u'Tyler Durden <*****@*****.**>'),
                         (2, u'irc', u'durden')]))

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_race(self):
        def race_thd(conn):
            # note that this assumes that both inserts can happen "at once".
            # This is the case for DB engines that support transactions, but
            # not for MySQL.  so this test does not detect the potential MySQL
            # failure, which will generally result in a spurious failure.
            conn.execute(self.db.model.users.insert(),
                         uid=99,
                         identifier='soap')
            conn.execute(self.db.model.users_info.insert(),
                         uid=99,
                         attr_type='subspace_net_handle',
                         attr_data='Durden0924')

        d = self.db.users.findUserByAttr(identifier='soap',
                                         attr_type='subspace_net_handle',
                                         attr_data='Durden0924',
                                         _race_hook=race_thd)

        def check_user(uid):
            self.assertEqual(uid, 99)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
                self.assertEqual(infos[0].attr_data, 'Durden0924')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_existing_identifier(self):
        # see http://trac.buildbot.net/ticket/2587
        d = self.insertTestData(self.user1_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='soap',  # same identifier
            attr_type='IPv9',
            attr_data='fffffff.ffffff'))  # different attr

        def check_user(uid):
            # creates a new user
            self.assertNotEqual(uid, 1)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(
                    users_tbl.select(
                        order_by=users_tbl.c.identifier)).fetchall()
                infos = conn.execute(
                    users_info_tbl.select(
                        users_info_tbl.c.uid == uid)).fetchall()
                self.assertEqual(len(users), 2)
                self.assertEqual(users[1].uid, uid)
                self.assertEqual(users[1].identifier, 'soap_2')  # unique'd
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].attr_type, 'IPv9')
                self.assertEqual(infos[0].attr_data, 'fffffff.ffffff')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_getUser(self):
        d = self.insertTestData(self.user1_rows)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict, self.user1_dict)

        d.addCallback(check1)
        return d

    def test_getUser_bb(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(usdict):
            self.assertEqual(usdict, self.user3_dict)

        d.addCallback(check3)
        return d

    def test_getUser_multi_attr(self):
        d = self.insertTestData(self.user2_rows)

        def get1(_):
            return self.db.users.getUser(2)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict, self.user2_dict)

        d.addCallback(check1)
        return d

    def test_getUser_no_match(self):
        d = self.insertTestData(self.user1_rows)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(none):
            self.assertEqual(none, None)

        d.addCallback(check3)
        return d

    def test_getUsers_none(self):
        d = self.db.users.getUsers()

        def check(res):
            self.assertEqual(res, [])

        d.addCallback(check)
        return d

    def test_getUsers(self):
        d = self.insertTestData(self.user1_rows)

        def get(_):
            return self.db.users.getUsers()

        d.addCallback(get)

        def check(res):
            self.assertEqual(res, [dict(uid=1, identifier='soap')])

        d.addCallback(check)
        return d

    def test_getUsers_multiple(self):
        d = self.insertTestData(self.user1_rows + self.user2_rows)

        def get(_):
            return self.db.users.getUsers()

        d.addCallback(get)

        def check(res):
            self.assertEqual(res, [
                dict(uid=1, identifier='soap'),
                dict(uid=2, identifier='lye')
            ])

        d.addCallback(check)
        return d

    def test_getUserByUsername(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUserByUsername("marla")

        d.addCallback(get3)

        def check3(res):
            self.assertEqual(res, self.user3_dict)

        d.addCallback(check3)
        return d

    def test_getUserByUsername_no_match(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUserByUsername("tyler")

        d.addCallback(get3)

        def check3(none):
            self.assertEqual(none, None)

        d.addCallback(check3)
        return d

    def test_updateUser_existing_type(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv9',
                                            attr_data='abcd.1234')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], 'abcd.1234')
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_new_type(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv4'], '123.134.156.167')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_identifier(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1, identifier='lye')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'lye')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_bb(self):
        d = self.insertTestData(self.user3_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            bb_username='******',
                                            bb_password='******')

        d.addCallback(update3)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(usdict):
            self.assertEqual(usdict['bb_username'], 'boss')
            self.assertEqual(usdict['bb_password'], 'fired')
            self.assertEqual(usdict['identifier'], 'marla')  # no change

        d.addCallback(check3)
        return d

    def test_updateUser_all(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            identifier='lye',
                                            bb_username='******',
                                            bb_password='******',
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'lye')
            self.assertEqual(usdict['bb_username'], 'marla')
            self.assertEqual(usdict['bb_password'], 'cancer')
            self.assertEqual(usdict['IPv4'], '123.134.156.167')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_race(self):
        # called from the db thread, this opens a *new* connection (to avoid
        # the existing transaction) and executes a conflicting insert in that
        # connection.  This will cause the insert in the db method to fail, and
        # the data in this insert (8.8.8.8) will appear below.
        transaction_wins = []
        if (self.db.pool.engine.dialect.name == 'sqlite' and
                self.db.pool.engine.url.database not in [None, ':memory:']):
            # It's not easy to work with file-based SQLite via multiple
            # connections, because SQLAlchemy (in it's default configuration)
            # locks file during working session.
            # TODO: This probably can be supported.
            raise unittest.SkipTest(
                "It's hard to test race condition with not in-memory SQLite")

        def race_thd(conn):
            conn = self.db.pool.engine.connect()
            try:
                r = conn.execute(self.db.model.users_info.insert(),
                                 uid=1,
                                 attr_type='IPv4',
                                 attr_data='8.8.8.8')
                r.close()
            except sqlalchemy.exc.OperationalError:
                # some engine (mysql innodb) will enforce lock until the transaction is over
                transaction_wins.append(True)
                # scope variable, we modify a list so that modification is visible in parent scope

        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167',
                                            _race_hook=race_thd)

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'soap')
            if transaction_wins:
                self.assertEqual(usdict['IPv4'], '123.134.156.167')
            else:
                self.assertEqual(usdict['IPv4'], '8.8.8.8')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_identifier(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3, identifier='abcd')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_attribute(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            attr_type='abcd',
                                            attr_data='efgh')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_bb(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            attr_type='marla',
                                            attr_data='cancer')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_removeUser_uid(self):
        d = self.insertTestData(self.user1_rows)

        def remove1(_):
            return self.db.users.removeUser(1)

        d.addCallback(remove1)

        def check1(_):
            def thd(conn):
                r = conn.execute(self.db.model.users.select())
                r = r.fetchall()
                self.assertEqual(len(r), 0)

            return self.db.pool.do(thd)

        d.addCallback(check1)
        return d

    def test_removeNoMatch(self):
        d = self.insertTestData(self.user1_rows)

        def check(_):
            return self.db.users.removeUser(uid=3)

        d.addCallback(check)
        return d

    def test_identifierToUid_NoMatch(self):
        d = self.db.users.identifierToUid(identifier="soap")

        def check(res):
            self.assertEqual(res, None)

        d.addCallback(check)
        return d

    def test_identifierToUid_match(self):
        d = self.insertTestData(self.user1_rows)

        def ident2uid(_):
            return self.db.users.identifierToUid(identifier="soap")

        d.addCallback(ident2uid)

        def check(res):
            self.assertEqual(res, 1)

        d.addCallback(check)
        return d
示例#9
0
class TestUsersConnectorComponent(connector_component.ConnectorComponentMixin,
                                  unittest.TestCase):
    def setUp(self):
        d = self.setUpConnectorComponent(
            table_names=['users', 'users_info', 'changes', 'change_users'])

        def finish_setup(_):
            self.db.users = users.UsersConnectorComponent(self.db)

        d.addCallback(finish_setup)
        return d

    def tearDown(self):
        return self.tearDownConnectorComponent()

    # sample user data

    user1_rows = [
        fakedb.User(uid=1, identifier='soap'),
        fakedb.UserInfo(uid=1, attr_type='IPv9', attr_data='0578cc6.8db024'),
    ]

    user2_rows = [
        fakedb.User(uid=2, identifier='lye'),
        fakedb.UserInfo(uid=2,
                        attr_type='git',
                        attr_data='Tyler Durden <*****@*****.**>'),
        fakedb.UserInfo(uid=2, attr_type='irc', attr_data='durden')
    ]

    user3_rows = [
        fakedb.User(uid=3,
                    identifier='marla',
                    bb_username='******',
                    bb_password='******')
    ]

    user4_rows = [
        fakedb.User(uid=4,
                    identifier=u'pyflakes <*****@*****.**>',
                    bb_username=None,
                    bb_password=None)
    ]

    user1_dict = {
        'uid': 1,
        'identifier': u'soap',
        'bb_username': None,
        'bb_password': None,
        'IPv9': u'0578cc6.8db024',
    }

    user2_dict = {
        'uid': 2,
        'identifier': u'lye',
        'bb_username': None,
        'bb_password': None,
        'irc': u'durden',
        'git': u'Tyler Durden <*****@*****.**>'
    }

    user3_dict = {
        'uid': 3,
        'identifier': u'marla',
        'bb_username': u'marla',
        'bb_password': u'cancer',
    }

    user4_dict = {
        'uid': 4,
        'identifier': u'pyflakes <*****@*****.**>',
        'bb_username': None,
        'bb_password': None,
    }

    # tests

    def test_addUser_new(self):
        d = self.db.users.findUserByAttr(identifier='soap',
                                         attr_type='subspace_net_handle',
                                         attr_data='Durden0924')

        def check_user(uid):
            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
                self.assertEqual(infos[0].attr_data, 'Durden0924')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_existing(self):
        d = self.insertTestData(self.user1_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='soapy', attr_type='IPv9', attr_data='0578cc6.8db024'))

        def check_user(uid):
            self.assertEqual(uid, 1)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')  # not changed!
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'IPv9')
                self.assertEqual(infos[0].attr_data, '0578cc6.8db024')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_findUser_existing(self):
        d = self.insertTestData(self.user1_rows + self.user2_rows +
                                self.user3_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='lye',
            attr_type='git',
            attr_data='Tyler Durden <*****@*****.**>'))

        def check_user(uid):
            self.assertEqual(uid, 2)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual((sorted(
                    [tuple(u)
                     for u in users]), sorted([tuple(i) for i in infos])), ([
                         (1L, u'soap', None, None),
                         (2L, u'lye', None, None),
                         (3L, u'marla', u'marla', u'cancer'),
                     ], [(1L, u'IPv9', u'0578cc6.8db024'),
                         (2L, u'git', u'Tyler Durden <*****@*****.**>'),
                         (2L, u'irc', u'durden')]))

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_race(self):
        def race_thd(conn):
            # note that this assumes that both inserts can happen "at once".
            # This is the case for DB engines that support transactions, but
            # not for MySQL.  so this test does not detect the potential MySQL
            # failure, which will generally result in a spurious failure.
            conn.execute(self.db.model.users.insert(),
                         uid=99,
                         identifier='soap')
            conn.execute(self.db.model.users_info.insert(),
                         uid=99,
                         attr_type='subspace_net_handle',
                         attr_data='Durden0924')

        d = self.db.users.findUserByAttr(identifier='soap',
                                         attr_type='subspace_net_handle',
                                         attr_data='Durden0924',
                                         _race_hook=race_thd)

        def check_user(uid):
            self.assertEqual(uid, 99)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
                self.assertEqual(infos[0].attr_data, 'Durden0924')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_existing_identifier(self):
        d = self.insertTestData(self.user1_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='soap', attr_type='telepathIO(tm)', attr_data='hmm,lye')
                      )
        return d

    def test_getUser(self):
        d = self.insertTestData(self.user1_rows)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict, self.user1_dict)

        d.addCallback(check1)
        return d

    def test_getUser_bb(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(usdict):
            self.assertEqual(usdict, self.user3_dict)

        d.addCallback(check3)
        return d

    def test_getUser_multi_attr(self):
        d = self.insertTestData(self.user2_rows)

        def get1(_):
            return self.db.users.getUser(2)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict, self.user2_dict)

        d.addCallback(check1)
        return d

    def test_getUser_no_match(self):
        d = self.insertTestData(self.user1_rows)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(none):
            self.assertEqual(none, None)

        d.addCallback(check3)
        return d

    def test_getUsers_none(self):
        d = self.db.users.getUsers()

        def check(res):
            self.assertEqual(res, [])

        d.addCallback(check)
        return d

    def test_getUsers(self):
        d = self.insertTestData(self.user1_rows)

        def get(_):
            return self.db.users.getUsers()

        d.addCallback(get)

        def check(res):
            self.assertEqual(res, [dict(uid=1, identifier='soap')])

        d.addCallback(check)
        return d

    def test_getUsers_multiple(self):
        d = self.insertTestData(self.user1_rows + self.user2_rows)

        def get(_):
            return self.db.users.getUsers()

        d.addCallback(get)

        def check(res):
            self.assertEqual(res, [
                dict(uid=1, identifier='soap'),
                dict(uid=2, identifier='lye')
            ])

        d.addCallback(check)
        return d

    def test_getUserByUsername(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUserByUsername("marla")

        d.addCallback(get3)

        def check3(res):
            self.assertEqual(res, self.user3_dict)

        d.addCallback(check3)
        return d

    def test_getUserByUsername_no_match(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUserByUsername("tyler")

        d.addCallback(get3)

        def check3(none):
            self.assertEqual(none, None)

        d.addCallback(check3)
        return d

    def test_updateUser_existing_type(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv9',
                                            attr_data='abcd.1234')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], 'abcd.1234')
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_new_type(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv4'], '123.134.156.167')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_identifier(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1, identifier='lye')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'lye')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_bb(self):
        d = self.insertTestData(self.user3_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            bb_username='******',
                                            bb_password='******')

        d.addCallback(update3)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(usdict):
            self.assertEqual(usdict['bb_username'], 'boss')
            self.assertEqual(usdict['bb_password'], 'fired')
            self.assertEqual(usdict['identifier'], 'marla')  # no change

        d.addCallback(check3)
        return d

    def test_updateUser_all(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            identifier='lye',
                                            bb_username='******',
                                            bb_password='******',
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'lye')
            self.assertEqual(usdict['bb_username'], 'marla')
            self.assertEqual(usdict['bb_password'], 'cancer')
            self.assertEqual(usdict['IPv4'], '123.134.156.167')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_race(self):
        # called from the db thread, this opens a *new* connection (to avoid
        # the existing transaction) and executes a conflicting insert in that
        # connection.  This will cause the insert in the db method to fail, and
        # the data in this insert (8.8.8.8) will appear below.
        def race_thd(conn):
            conn = self.db.pool.engine.connect()
            conn.execute(self.db.model.users_info.insert(),
                         uid=1,
                         attr_type='IPv4',
                         attr_data='8.8.8.8')

        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167',
                                            _race_hook=race_thd)

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'soap')
            self.assertEqual(usdict['IPv4'], '8.8.8.8')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_identifier(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3, identifier='abcd')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_attribute(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            attr_type='abcd',
                                            attr_data='efgh')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_bb(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            attr_type='marla',
                                            attr_data='cancer')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_removeUser_uid(self):
        d = self.insertTestData(self.user1_rows)

        def remove1(_):
            return self.db.users.removeUser(1)

        d.addCallback(remove1)

        def check1(_):
            def thd(conn):
                r = conn.execute(self.db.model.users.select())
                r = r.fetchall()
                self.assertEqual(len(r), 0)

            return self.db.pool.do(thd)

        d.addCallback(check1)
        return d

    def test_removeNoMatch(self):
        d = self.insertTestData(self.user1_rows)

        def check(_):
            return self.db.users.removeUser(uid=3)

        d.addCallback(check)
        return d

    def test_identifierToUid_NoMatch(self):
        d = self.db.users.identifierToUid(identifier="soap")

        def check(res):
            self.assertEqual(res, None)

        d.addCallback(check)
        return d

    def test_identifierToUid_match(self):
        d = self.insertTestData(self.user1_rows)

        def ident2uid(_):
            return self.db.users.identifierToUid(identifier="soap")

        d.addCallback(ident2uid)

        def check(res):
            self.assertEqual(res, 1)

        d.addCallback(check)
        return d

    @defer.inlineCallbacks
    def test_getUidByLdapUsername_correct_username(self):
        yield self.insertTestData(self.user4_rows)
        username = '******'

        uid = yield self.db.users.getUidByLdapUsername(username)

        self.assertEqual(uid, self.user4_dict['uid'])

    @defer.inlineCallbacks
    def test_getUidByLdapUsername_wrong_username(self):
        yield self.insertTestData(self.user4_rows)
        username = '******'

        uid = yield self.db.users.getUidByLdapUsername(username)

        self.assertEqual(uid, None)
示例#10
0
    def test_sendToInterestedUsers_two_builds(self):
        from email.Message import Message
        m = Message()

        mn = MailNotifier(fromaddr="*****@*****.**", lookup=None)
        mn.sendMessage = Mock()

        def fakeGetBuilder(buildername):
            if buildername == builder.name:
                return builder
            return None
        def fakeGetBuildRequests(self, bsid):
            return defer.succeed([{"buildername":"Builder", "brid":1}])

        builder = Mock()
        builder.name = "Builder"

        build1 = FakeBuildStatus(name="build")
        build1.result = FAILURE
        build1.finished = True
        build1.reason = "testReason"
        build1.builder = builder

        build2 = FakeBuildStatus(name="build")
        build2.result = FAILURE
        build2.finished = True
        build2.reason = "testReason"
        build2.builder = builder

        def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
                            patches=None, logs=None):
            # only concerned with m['To'] and m['CC'], which are added in
            # _got_recipients later
            return m
        mn.createEmail = fakeCreateEmail

        self.db = fakedb.FakeDBConnector(self)
        self.db.insertTestData([fakedb.SourceStampSet(id=1099),
                                fakedb.Buildset(id=99, sourcestampsetid=1099,
                                                results=SUCCESS,
                                                reason="testReason"),
                                fakedb.BuildRequest(id=11, buildsetid=99,
                                                    buildername='Builder'),
                                fakedb.Build(number=0, brid=11),
                                fakedb.Build(number=1, brid=11),
                                fakedb.Change(changeid=9123),
                                fakedb.Change(changeid=9124),
                                fakedb.ChangeUser(changeid=9123, uid=1),
                                fakedb.ChangeUser(changeid=9124, uid=2),
                                fakedb.User(uid=1, identifier="tdurden"),
                                fakedb.User(uid=2, identifier="user2"),
                                fakedb.UserInfo(uid=1, attr_type='email',
                                            attr_data="*****@*****.**"),
                                fakedb.UserInfo(uid=2, attr_type='email',
                                            attr_data="*****@*****.**")
                                ])

        def _getInterestedUsers():
            # 'narrator' in this case is the owner, which tests the lookup
            return ["Big Bob <*****@*****.**>", "narrator"]
        build1.getInterestedUsers = _getInterestedUsers
        build2.getInterestedUsers = _getInterestedUsers

        def _getResponsibleUsers():
            return ["Big Bob <*****@*****.**>"]
        build1.getResponsibleUsers = _getResponsibleUsers
        build2.getResponsibleUsers = _getResponsibleUsers

        # fake sourcestamp with relevant user bits
        ss1 = Mock(name="sourcestamp")
        fake_change1 = Mock(name="change")
        fake_change1.number = 9123
        ss1.changes = [fake_change1]
        ss1.patch, ss1.addPatch = None, None

        ss2 = Mock(name="sourcestamp")
        fake_change2 = Mock(name="change")
        fake_change2.number = 9124
        ss2.changes = [fake_change2]
        ss2.patch, ss1.addPatch = None, None

        def fakeGetSS(ss):
            return lambda: ss
        build1.getSourceStamp = fakeGetSS(ss1)
        build2.getSourceStamp = fakeGetSS(ss2)

        mn.parent = self
        self.status = mn.master_status = mn.buildMessageDict = Mock()
        mn.master_status.getBuilder = fakeGetBuilder
        mn.buildMessageDict.return_value = {"body": "body", "type": "text"}

        mn.buildMessage(builder.name, [build1, build2], build1.result)
        self.assertEqual(m['To'], "[email protected], [email protected]")
示例#11
0
    def do_test_sendToInterestedUsers(self, lookup=None, extraRecipients=[],
                                      sendToInterestedUsers=True,
                                      exp_called_with=None, exp_TO=None,
                                      exp_CC=None):
        from email.Message import Message
        m = Message()

        mn = MailNotifier(fromaddr='*****@*****.**',
                          lookup=lookup,
                          sendToInterestedUsers=sendToInterestedUsers,
                          extraRecipients=extraRecipients)
        mn.sendMessage = Mock()

        def fakeGetBuild(number):
            return build
        def fakeGetBuilder(buildername):
            if buildername == builder.name:
                return builder
            return None
        def fakeGetBuildRequests(self, bsid):
            return defer.succeed([{"buildername":"Builder", "brid":1}])

        builder = Mock()
        builder.getBuild = fakeGetBuild
        builder.name = "Builder"

        build = FakeBuildStatus(name="build")
        build.result = FAILURE
        build.finished = True
        build.reason = "testReason"
        build.builder = builder

        def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
                            patches=None, logs=None):
            # only concerned with m['To'] and m['CC'], which are added in
            # _got_recipients later
            return m
        mn.createEmail = fakeCreateEmail

        self.db = fakedb.FakeDBConnector(self)
        self.db.insertTestData([fakedb.SourceStampSet(id=1099),
                                fakedb.Buildset(id=99, sourcestampsetid=1099,
                                                results=SUCCESS,
                                                reason="testReason"),
                                fakedb.BuildRequest(id=11, buildsetid=99,
                                                    buildername='Builder'),
                                fakedb.Build(number=0, brid=11),
                                fakedb.Change(changeid=9123),
                                fakedb.ChangeUser(changeid=9123, uid=1),
                                fakedb.User(uid=1, identifier="tdurden"),
                                fakedb.UserInfo(uid=1, attr_type='svn',
                                            attr_data="tdurden"),
                                fakedb.UserInfo(uid=1, attr_type='email',
                                            attr_data="*****@*****.**")
                                ])

        # fake sourcestamp with relevant user bits
        ss = Mock(name="sourcestamp")
        fake_change = Mock(name="change")
        fake_change.number = 9123
        ss.changes = [fake_change]
        ss.patch, ss.addPatch = None, None

        def fakeGetSS():
            return ss
        build.getSourceStamp = fakeGetSS

        def _getInterestedUsers():
            # 'narrator' in this case is the owner, which tests the lookup
            return ["Big Bob <*****@*****.**>", "narrator"]
        build.getInterestedUsers = _getInterestedUsers

        def _getResponsibleUsers():
            return ["Big Bob <*****@*****.**>"]
        build.getResponsibleUsers = _getResponsibleUsers

        mn.parent = self
        self.status = mn.master_status = mn.buildMessageDict = Mock()
        mn.master_status.getBuilder = fakeGetBuilder
        mn.buildMessageDict.return_value = {"body": "body", "type": "text"}

        mn.buildMessage(builder.name, [build], build.result)
        mn.sendMessage.assert_called_with(m, exp_called_with)
        self.assertEqual(m['To'], exp_TO)
        self.assertEqual(m['CC'], exp_CC)
示例#12
0
class TestUsersConnectorComponent(connector_component.ConnectorComponentMixin,
                                  unittest.TestCase):
    def setUp(self):
        d = self.setUpConnectorComponent(
            table_names=['users', 'users_info', 'changes', 'change_users'])

        def finish_setup(_):
            self.db.users = users.UsersConnectorComponent(self.db)

        d.addCallback(finish_setup)
        return d

    def tearDown(self):
        return self.tearDownConnectorComponent()

    # sample user data

    user1_rows = [
        fakedb.User(uid=1, identifier='soap'),
        fakedb.UserInfo(uid=1, attr_type='IPv9', attr_data='0578cc6.8db024'),
    ]

    user2_rows = [
        fakedb.User(uid=2, identifier='lye'),
        fakedb.UserInfo(uid=2,
                        attr_type='git',
                        attr_data='Tyler Durden <*****@*****.**>'),
        fakedb.UserInfo(uid=2, attr_type='irc', attr_data='durden')
    ]

    user3_rows = [
        fakedb.User(uid=3,
                    identifier='marla',
                    bb_username='******',
                    bb_password='******')
    ]

    user1_dict = {
        'uid': 1,
        'identifier': u'soap',
        'bb_username': None,
        'bb_password': None,
        'IPv9': u'0578cc6.8db024',
    }

    user2_dict = {
        'uid': 2,
        'identifier': u'lye',
        'bb_username': None,
        'bb_password': None,
        'irc': u'durden',
        'git': u'Tyler Durden <*****@*****.**>'
    }

    user3_dict = {
        'uid': 3,
        'identifier': u'marla',
        'bb_username': u'marla',
        'bb_password': u'cancer',
    }

    # tests

    def test_addUser_new(self):
        d = self.db.users.findUserByAttr(identifier='soap',
                                         attr_type='subspace_net_handle',
                                         attr_data='Durden0924')

        def check_user(uid):
            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
                self.assertEqual(infos[0].attr_data, 'Durden0924')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_existing(self):
        d = self.insertTestData(self.user1_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='soapy', attr_type='IPv9', attr_data='0578cc6.8db024'))

        def check_user(uid):
            self.assertEqual(uid, 1)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')  # not changed!
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'IPv9')
                self.assertEqual(infos[0].attr_data, '0578cc6.8db024')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_race(self):
        def race_thd(conn):
            # note that this assumes that both inserts can happen "at once".
            # This is the case for DB engines that support transactions, but
            # not for MySQL.  so this test does not detect the potential MySQL
            # failure, which will generally result in a spurious failure.
            conn.execute(self.db.model.users.insert(),
                         uid=99,
                         identifier='soap')
            conn.execute(self.db.model.users_info.insert(),
                         uid=99,
                         attr_type='subspace_net_handle',
                         attr_data='Durden0924')

        d = self.db.users.findUserByAttr(identifier='soap',
                                         attr_type='subspace_net_handle',
                                         attr_data='Durden0924',
                                         _race_hook=race_thd)

        def check_user(uid):
            self.assertEqual(uid, 99)

            def thd(conn):
                users_tbl = self.db.model.users
                users_info_tbl = self.db.model.users_info
                users = conn.execute(users_tbl.select()).fetchall()
                infos = conn.execute(users_info_tbl.select()).fetchall()
                self.assertEqual(len(users), 1)
                self.assertEqual(users[0].uid, uid)
                self.assertEqual(users[0].identifier, 'soap')
                self.assertEqual(len(infos), 1)
                self.assertEqual(infos[0].uid, uid)
                self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
                self.assertEqual(infos[0].attr_data, 'Durden0924')

            return self.db.pool.do(thd)

        d.addCallback(check_user)
        return d

    def test_addUser_existing_identifier(self):
        d = self.insertTestData(self.user1_rows)
        d.addCallback(lambda _: self.db.users.findUserByAttr(
            identifier='soap', attr_type='telepathIO(tm)', attr_data='hmm,lye')
                      )

        def cb(_):
            self.fail("shouldn't get here")

        def eb(f):
            f.trap(sa.exc.IntegrityError, sa.exc.ProgrammingError)
            pass  # expected

        d.addCallbacks(cb, eb)
        return d

    def test_getUser(self):
        d = self.insertTestData(self.user1_rows)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict, self.user1_dict)

        d.addCallback(check1)
        return d

    def test_getUser_bb(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(usdict):
            self.assertEqual(usdict, self.user3_dict)

        d.addCallback(check3)
        return d

    def test_getUser_multi_attr(self):
        d = self.insertTestData(self.user2_rows)

        def get1(_):
            return self.db.users.getUser(2)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict, self.user2_dict)

        d.addCallback(check1)
        return d

    def test_getUser_no_match(self):
        d = self.insertTestData(self.user1_rows)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(none):
            self.assertEqual(none, None)

        d.addCallback(check3)
        return d

    def test_getUsers_none(self):
        d = self.db.users.getUsers()

        def check(res):
            self.assertEqual(res, [])

        d.addCallback(check)
        return d

    def test_getUsers(self):
        d = self.insertTestData(self.user1_rows)

        def get(_):
            return self.db.users.getUsers()

        d.addCallback(get)

        def check(res):
            self.assertEqual(res, [dict(uid=1, identifier='soap')])

        d.addCallback(check)
        return d

    def test_getUsers_multiple(self):
        d = self.insertTestData(self.user1_rows + self.user2_rows)

        def get(_):
            return self.db.users.getUsers()

        d.addCallback(get)

        def check(res):
            self.assertEqual(res, [
                dict(uid=1, identifier='soap'),
                dict(uid=2, identifier='lye')
            ])

        d.addCallback(check)
        return d

    def test_getUserByUsername(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUserByUsername("marla")

        d.addCallback(get3)

        def check3(res):
            self.assertEqual(res, self.user3_dict)

        d.addCallback(check3)
        return d

    def test_getUserByUsername_no_match(self):
        d = self.insertTestData(self.user3_rows)

        def get3(_):
            return self.db.users.getUserByUsername("tyler")

        d.addCallback(get3)

        def check3(none):
            self.assertEqual(none, None)

        d.addCallback(check3)
        return d

    def test_updateUser_existing_type(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv9',
                                            attr_data='abcd.1234')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], 'abcd.1234')
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_new_type(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv4'], '123.134.156.167')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_identifier(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1, identifier='lye')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'lye')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_bb(self):
        d = self.insertTestData(self.user3_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            bb_username='******',
                                            bb_password='******')

        d.addCallback(update3)

        def get3(_):
            return self.db.users.getUser(3)

        d.addCallback(get3)

        def check3(usdict):
            self.assertEqual(usdict['bb_username'], 'boss')
            self.assertEqual(usdict['bb_password'], 'fired')
            self.assertEqual(usdict['identifier'], 'marla')  # no change

        d.addCallback(check3)
        return d

    def test_updateUser_all(self):
        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            identifier='lye',
                                            bb_username='******',
                                            bb_password='******',
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167')

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'lye')
            self.assertEqual(usdict['bb_username'], 'marla')
            self.assertEqual(usdict['bb_password'], 'cancer')
            self.assertEqual(usdict['IPv4'], '123.134.156.167')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_updateUser_race(self):
        def race_thd(conn):
            conn.execute(self.db.model.users_info.insert(),
                         uid=1,
                         attr_type='IPv4',
                         attr_data='8.8.8.8')

        d = self.insertTestData(self.user1_rows)

        def update1(_):
            return self.db.users.updateUser(uid=1,
                                            attr_type='IPv4',
                                            attr_data='123.134.156.167',
                                            _race_hook=race_thd)

        d.addCallback(update1)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'soap')
            self.assertEqual(usdict['IPv4'], '8.8.8.8')
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_identifier(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3, identifier='abcd')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['identifier'], 'soap')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_attribute(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            attr_type='abcd',
                                            attr_data='efgh')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_update_NoMatch_bb(self):
        d = self.insertTestData(self.user1_rows)

        def update3(_):
            return self.db.users.updateUser(uid=3,
                                            attr_type='marla',
                                            attr_data='cancer')

        d.addCallback(update3)

        def get1(_):
            return self.db.users.getUser(1)

        d.addCallback(get1)

        def check1(usdict):
            self.assertEqual(usdict['IPv9'], '0578cc6.8db024')  # no change

        d.addCallback(check1)
        return d

    def test_removeUser_uid(self):
        d = self.insertTestData(self.user1_rows)

        def remove1(_):
            return self.db.users.removeUser(1)

        d.addCallback(remove1)

        def check1(_):
            def thd(conn):
                r = conn.execute(self.db.model.users.select())
                r = r.fetchall()
                self.assertEqual(len(r), 0)

            return self.db.pool.do(thd)

        d.addCallback(check1)
        return d

    def test_removeNoMatch(self):
        d = self.insertTestData(self.user1_rows)

        def check(_):
            return self.db.users.removeUser(uid=3)

        d.addCallback(check)
        return d

    def test_identifierToUid_NoMatch(self):
        d = self.db.users.identifierToUid(identifier="soap")

        def check(res):
            self.assertEqual(res, None)

        d.addCallback(check)
        return d

    def test_identifierToUid_match(self):
        d = self.insertTestData(self.user1_rows)

        def ident2uid(_):
            return self.db.users.identifierToUid(identifier="soap")

        d.addCallback(ident2uid)

        def check(res):
            self.assertEqual(res, 1)

        d.addCallback(check)
        return d