Replace more tearDowns with addCleanup.

This commit is contained in:
A. Jesse Jiryu Davis 2015-01-22 21:36:54 -05:00
parent 565e5faeb9
commit 301bf8066c
5 changed files with 458 additions and 496 deletions

View File

@ -643,78 +643,74 @@ class TestBulk(BulkTestBase):
def test_single_error_ordered_batch(self):
self.coll.ensure_index('a', unique=True)
self.addCleanup(self.coll.drop_index, [('a', 1)])
batch = self.coll.initialize_ordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.insert({'b': 3, 'a': 2})
try:
batch = self.coll.initialize_ordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.insert({'b': 3, 'a': 2})
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
try:
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 0,
'nInserted': 1,
'nRemoved': 0,
'upserted': [],
'writeConcernErrors': [],
'writeErrors': [
{'index': 1,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 2},
'u': {'$set': {'a': 1}},
'multi': False,
'upsert': True}}]},
result)
finally:
self.coll.drop_index([('a', 1)])
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 0,
'nInserted': 1,
'nRemoved': 0,
'upserted': [],
'writeConcernErrors': [],
'writeErrors': [
{'index': 1,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 2},
'u': {'$set': {'a': 1}},
'multi': False,
'upsert': True}}]},
result)
def test_multiple_error_ordered_batch(self):
self.coll.ensure_index('a', unique=True)
self.addCleanup(self.coll.drop_index, [('a', 1)])
batch = self.coll.initialize_ordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.find({'b': 3}).upsert().update_one({'$set': {'a': 2}})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.insert({'b': 4, 'a': 3})
batch.insert({'b': 5, 'a': 1})
try:
batch = self.coll.initialize_ordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.find({'b': 3}).upsert().update_one({'$set': {'a': 2}})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.insert({'b': 4, 'a': 3})
batch.insert({'b': 5, 'a': 1})
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
try:
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 0,
'nInserted': 1,
'nRemoved': 0,
'upserted': [],
'writeConcernErrors': [],
'writeErrors': [
{'index': 1,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 2},
'u': {'$set': {'a': 1}},
'multi': False,
'upsert': True}}]},
result)
finally:
self.coll.drop_index([('a', 1)])
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 0,
'nInserted': 1,
'nRemoved': 0,
'upserted': [],
'writeConcernErrors': [],
'writeErrors': [
{'index': 1,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 2},
'u': {'$set': {'a': 1}},
'multi': False,
'upsert': True}}]},
result)
def test_single_unordered_batch(self):
batch = self.coll.initialize_unordered_bulk_op()
@ -737,85 +733,81 @@ class TestBulk(BulkTestBase):
def test_single_error_unordered_batch(self):
self.coll.ensure_index('a', unique=True)
self.addCleanup(self.coll.drop_index, [('a', 1)])
batch = self.coll.initialize_unordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.insert({'b': 3, 'a': 2})
try:
batch = self.coll.initialize_unordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 1}})
batch.insert({'b': 3, 'a': 2})
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
try:
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 0,
'nInserted': 2,
'nRemoved': 0,
'upserted': [],
'writeConcernErrors': [],
'writeErrors': [
{'index': 1,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 2},
'u': {'$set': {'a': 1}},
'multi': False,
'upsert': True}}]},
result)
finally:
self.coll.drop_index([('a', 1)])
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 0,
'nInserted': 2,
'nRemoved': 0,
'upserted': [],
'writeConcernErrors': [],
'writeErrors': [
{'index': 1,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 2},
'u': {'$set': {'a': 1}},
'multi': False,
'upsert': True}}]},
result)
def test_multiple_error_unordered_batch(self):
self.coll.ensure_index('a', unique=True)
try:
batch = self.coll.initialize_unordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 3}})
batch.find({'b': 3}).upsert().update_one({'$set': {'a': 4}})
batch.find({'b': 4}).upsert().update_one({'$set': {'a': 3}})
batch.insert({'b': 5, 'a': 2})
batch.insert({'b': 6, 'a': 1})
self.addCleanup(self.coll.drop_index, [('a', 1)])
batch = self.coll.initialize_unordered_bulk_op()
batch.insert({'b': 1, 'a': 1})
batch.find({'b': 2}).upsert().update_one({'$set': {'a': 3}})
batch.find({'b': 3}).upsert().update_one({'$set': {'a': 4}})
batch.find({'b': 4}).upsert().update_one({'$set': {'a': 3}})
batch.insert({'b': 5, 'a': 2})
batch.insert({'b': 6, 'a': 1})
try:
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
# Assume the update at index 1 runs before the update at index 3,
# although the spec does not require it. Same for inserts.
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 2,
'nInserted': 2,
'nRemoved': 0,
'upserted': [
{'index': 1, '_id': '...'},
{'index': 2, '_id': '...'}],
'writeConcernErrors': [],
'writeErrors': [
{'index': 3,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 4},
'u': {'$set': {'a': 3}},
'multi': False,
'upsert': True}},
{'index': 5,
'code': 11000,
'errmsg': '...',
'op': {'_id': '...', 'b': 6, 'a': 1}}]},
result)
finally:
self.coll.drop_index([('a', 1)])
try:
batch.execute()
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
# Assume the update at index 1 runs before the update at index 3,
# although the spec does not require it. Same for inserts.
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 2,
'nInserted': 2,
'nRemoved': 0,
'upserted': [
{'index': 1, '_id': '...'},
{'index': 2, '_id': '...'}],
'writeConcernErrors': [],
'writeErrors': [
{'index': 3,
'code': 11000,
'errmsg': '...',
'op': {'q': {'b': 4},
'u': {'$set': {'a': 3}},
'multi': False,
'upsert': True}},
{'index': 5,
'code': 11000,
'errmsg': '...',
'op': {'_id': '...', 'b': 6, 'a': 1}}]},
result)
def test_large_inserts_ordered(self):
big = 'x' * self.coll.database.connection.max_bson_size
@ -994,42 +986,40 @@ class TestBulkWriteConcern(BulkTestBase):
self.coll.remove()
self.coll.ensure_index('a', unique=True)
self.addCleanup(self.coll.drop_index, [('a', 1)])
# Fail due to write concern support as well
# as duplicate key error on ordered batch.
batch = self.coll.initialize_ordered_bulk_op()
batch.insert({'a': 1})
batch.find({'a': 3}).upsert().replace_one({'b': 1})
batch.insert({'a': 1})
batch.insert({'a': 2})
try:
batch = self.coll.initialize_ordered_bulk_op()
batch.insert({'a': 1})
batch.find({'a': 3}).upsert().replace_one({'b': 1})
batch.insert({'a': 1})
batch.insert({'a': 2})
try:
self.cause_wtimeout(batch)
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.cause_wtimeout(batch)
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 1,
'nInserted': 1,
'nRemoved': 0,
'upserted': [{'index': 1, '_id': '...'}],
'writeErrors': [
{'index': 2,
'code': 11000,
'errmsg': '...',
'op': {'_id': '...', 'a': 1}}]},
result)
self.assertEqualResponse(
{'nMatched': 0,
'nModified': 0,
'nUpserted': 1,
'nInserted': 1,
'nRemoved': 0,
'upserted': [{'index': 1, '_id': '...'}],
'writeErrors': [
{'index': 2,
'code': 11000,
'errmsg': '...',
'op': {'_id': '...', 'a': 1}}]},
result)
self.assertEqual(2, len(result['writeConcernErrors']))
failed = result['writeErrors'][0]
self.assertTrue("duplicate" in failed['errmsg'])
finally:
self.coll.drop_index([('a', 1)])
self.assertEqual(2, len(result['writeConcernErrors']))
failed = result['writeErrors'][0]
self.assertTrue("duplicate" in failed['errmsg'])
@client_context.require_replica_set
def test_write_concern_failure_unordered(self):
@ -1062,47 +1052,45 @@ class TestBulkWriteConcern(BulkTestBase):
self.coll.remove()
self.coll.ensure_index('a', unique=True)
self.addCleanup(self.coll.drop_index, [('a', 1)])
# Fail due to write concern support as well
# as duplicate key error on unordered batch.
batch = self.coll.initialize_unordered_bulk_op()
batch.insert({'a': 1})
batch.find({'a': 3}).upsert().update_one({'$set': {'a': 3,
'b': 1}})
batch.insert({'a': 1})
batch.insert({'a': 2})
try:
batch = self.coll.initialize_unordered_bulk_op()
batch.insert({'a': 1})
batch.find({'a': 3}).upsert().update_one({'$set': {'a': 3,
'b': 1}})
batch.insert({'a': 1})
batch.insert({'a': 2})
try:
self.cause_wtimeout(batch)
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.cause_wtimeout(batch)
except BulkWriteError as exc:
result = exc.details
self.assertEqual(exc.code, 65)
else:
self.fail("Error not raised")
self.assertEqual(2, result['nInserted'])
self.assertEqual(1, result['nUpserted'])
self.assertEqual(1, len(result['writeErrors']))
# When talking to legacy servers there will be a
# write concern error for each operation.
self.assertTrue(len(result['writeConcernErrors']) > 1)
self.assertEqual(2, result['nInserted'])
self.assertEqual(1, result['nUpserted'])
self.assertEqual(1, len(result['writeErrors']))
# When talking to legacy servers there will be a
# write concern error for each operation.
self.assertTrue(len(result['writeConcernErrors']) > 1)
failed = result['writeErrors'][0]
self.assertEqual(2, failed['index'])
self.assertEqual(11000, failed['code'])
self.assertTrue(isinstance(failed['errmsg'], string_type))
self.assertEqual(1, failed['op']['a'])
failed = result['writeErrors'][0]
self.assertEqual(2, failed['index'])
self.assertEqual(11000, failed['code'])
self.assertTrue(isinstance(failed['errmsg'], string_type))
self.assertEqual(1, failed['op']['a'])
failed = result['writeConcernErrors'][0]
self.assertEqual(64, failed['code'])
self.assertTrue(isinstance(failed['errmsg'], string_type))
failed = result['writeConcernErrors'][0]
self.assertEqual(64, failed['code'])
self.assertTrue(isinstance(failed['errmsg'], string_type))
upserts = result['upserted']
self.assertEqual(1, len(upserts))
self.assertEqual(1, upserts[0]['index'])
self.assertTrue(upserts[0].get('_id'))
finally:
self.coll.drop_index([('a', 1)])
upserts = result['upserted']
self.assertEqual(1, len(upserts))
self.assertEqual(1, upserts[0]['index'])
self.assertTrue(upserts[0].get('_id'))
class TestBulkNoResults(BulkTestBase):

View File

@ -323,74 +323,68 @@ class TestClient(IntegrationTest):
@client_context.require_auth
def test_auth_from_uri(self):
self.client.admin.add_user("admin", "pass", roles=["root"])
try:
self.client.pymongo_test.add_user(
"user", "pass", roles=['userAdmin', 'readWrite'])
self.addCleanup(self.client.admin.remove_user, 'admin')
self.addCleanup(remove_all_users, self.client.pymongo_test)
with self.assertRaises(OperationFailure):
connected(rs_or_single_client(
"mongodb://a:b@%s:%d" % (host, port)))
self.client.pymongo_test.add_user(
"user", "pass", roles=['userAdmin', 'readWrite'])
# No error.
connected(rs_or_single_client_noauth(
"mongodb://admin:pass@%s:%d" % (host, port)))
with self.assertRaises(OperationFailure):
connected(rs_or_single_client(
"mongodb://a:b@%s:%d" % (host, port)))
# Wrong database.
uri = "mongodb://admin:pass@%s:%d/pymongo_test" % (host, port)
with self.assertRaises(OperationFailure):
connected(rs_or_single_client(uri))
# No error.
connected(rs_or_single_client_noauth(
"mongodb://admin:pass@%s:%d" % (host, port)))
# No error.
connected(rs_or_single_client_noauth(
"mongodb://user:pass@%s:%d/pymongo_test" % (host, port)))
# Wrong database.
uri = "mongodb://admin:pass@%s:%d/pymongo_test" % (host, port)
with self.assertRaises(OperationFailure):
connected(rs_or_single_client(uri))
# Auth with lazy connection.
rs_or_single_client(
"mongodb://user:pass@%s:%d/pymongo_test" % (host, port),
connect=False).pymongo_test.test.find_one()
# No error.
connected(rs_or_single_client_noauth(
"mongodb://user:pass@%s:%d/pymongo_test" % (host, port)))
# Wrong password.
bad_client = rs_or_single_client(
"mongodb://user:wrong@%s:%d/pymongo_test" % (host, port),
connect=False)
# Auth with lazy connection.
rs_or_single_client(
"mongodb://user:pass@%s:%d/pymongo_test" % (host, port),
connect=False).pymongo_test.test.find_one()
self.assertRaises(OperationFailure,
bad_client.pymongo_test.test.find_one)
# Wrong password.
bad_client = rs_or_single_client(
"mongodb://user:wrong@%s:%d/pymongo_test" % (host, port),
connect=False)
finally:
# Clean up.
remove_all_users(self.client.pymongo_test)
self.client.admin.remove_user('admin')
self.assertRaises(OperationFailure,
bad_client.pymongo_test.test.find_one)
@client_context.require_auth
def test_multiple_logins(self):
self.client.pymongo_test.add_user('user1', 'pass', roles=['readWrite'])
self.client.pymongo_test.add_user('user2', 'pass', roles=['readWrite'])
self.addCleanup(remove_all_users, self.client.pymongo_test)
try:
client = rs_or_single_client_noauth(
"mongodb://user1:pass@%s:%d/pymongo_test" % (host, port))
client.pymongo_test.test.find_one()
with self.assertRaises(OperationFailure):
# Can't log in to the same database with multiple users.
client.pymongo_test.authenticate('user2', 'pass')
client.pymongo_test.test.find_one()
client.pymongo_test.logout()
with self.assertRaises(OperationFailure):
client.pymongo_test.test.find_one()
client = rs_or_single_client_noauth(
"mongodb://user1:pass@%s:%d/pymongo_test" % (host, port))
client.pymongo_test.test.find_one()
with self.assertRaises(OperationFailure):
# Can't log in to the same database with multiple users.
client.pymongo_test.authenticate('user2', 'pass')
client.pymongo_test.test.find_one()
client.pymongo_test.logout()
with self.assertRaises(OperationFailure):
client.pymongo_test.test.find_one()
with self.assertRaises(OperationFailure):
client.pymongo_test.authenticate('user1', 'pass')
client.pymongo_test.authenticate('user2', 'pass')
client.pymongo_test.test.find_one()
client.pymongo_test.test.find_one()
with self.assertRaises(OperationFailure):
client.pymongo_test.authenticate('user1', 'pass')
finally:
remove_all_users(self.client.pymongo_test)
client.pymongo_test.test.find_one()
@client_context.require_auth
def test_lazy_auth_raises_operation_failure(self):
@ -879,38 +873,35 @@ class TestExhaustCursor(IntegrationTest):
collection.remove()
collection.insert([{} for _ in range(200)])
self.addCleanup(client_context.client.pymongo_test.test.drop)
try:
pool = get_pool(client)
pool._check_interval_seconds = None # Never check.
sock_info = one(pool.sockets)
pool = get_pool(client)
pool._check_interval_seconds = None # Never check.
sock_info = one(pool.sockets)
cursor = collection.find(cursor_type=EXHAUST)
cursor = collection.find(cursor_type=EXHAUST)
# Initial query succeeds.
cursor.next()
# Initial query succeeds.
cursor.next()
# Cause a server error on getmore.
def receive_message(operation, request_id):
# Discard the actual server response.
SocketInfo.receive_message(sock_info, operation, request_id)
# Cause a server error on getmore.
def receive_message(operation, request_id):
# Discard the actual server response.
SocketInfo.receive_message(sock_info, operation, request_id)
# responseFlags bit 1 is QueryFailure.
msg = struct.pack('<iiiii', 1 << 1, 0, 0, 0, 0)
msg += BSON.encode({'$err': 'mock err', 'code': 0})
return msg
# responseFlags bit 1 is QueryFailure.
msg = struct.pack('<iiiii', 1 << 1, 0, 0, 0, 0)
msg += BSON.encode({'$err': 'mock err', 'code': 0})
return msg
saved = sock_info.receive_message
sock_info.receive_message = receive_message
self.assertRaises(OperationFailure, list, cursor)
sock_info.receive_message = saved
saved = sock_info.receive_message
sock_info.receive_message = receive_message
self.assertRaises(OperationFailure, list, cursor)
sock_info.receive_message = saved
# The socket is returned the pool and it still works.
self.assertEqual(200, collection.count())
self.assertIn(sock_info, pool.sockets)
finally:
client_context.client.pymongo_test.test.drop()
# The socket is returned the pool and it still works.
self.assertEqual(200, collection.count())
self.assertIn(sock_info, pool.sockets)
def test_exhaust_query_network_error(self):
# When doing an exhaust query, the socket stays checked out on success

View File

@ -934,43 +934,41 @@ class TestCursor(IntegrationTest):
db = self.db
db.drop_collection("test")
db.create_collection("test", capped=True, size=1000, max=3)
self.addCleanup(db.drop_collection, "test")
cursor = db.test.find(cursor_type=TAILABLE)
try:
cursor = db.test.find(cursor_type=TAILABLE)
db.test.insert({"x": 1})
count = 0
for doc in cursor:
count += 1
self.assertEqual(1, doc["x"])
self.assertEqual(1, count)
db.test.insert({"x": 1})
count = 0
for doc in cursor:
count += 1
self.assertEqual(1, doc["x"])
self.assertEqual(1, count)
db.test.insert({"x": 2})
count = 0
for doc in cursor:
count += 1
self.assertEqual(2, doc["x"])
self.assertEqual(1, count)
db.test.insert({"x": 2})
count = 0
for doc in cursor:
count += 1
self.assertEqual(2, doc["x"])
self.assertEqual(1, count)
db.test.insert({"x": 3})
count = 0
for doc in cursor:
count += 1
self.assertEqual(3, doc["x"])
self.assertEqual(1, count)
db.test.insert({"x": 3})
count = 0
for doc in cursor:
count += 1
self.assertEqual(3, doc["x"])
self.assertEqual(1, count)
# Capped rollover - the collection can never
# have more than 3 documents. Just make sure
# this doesn't raise...
db.test.insert(({"x": i} for i in range(4, 7)))
self.assertEqual(0, len(list(cursor)))
# Capped rollover - the collection can never
# have more than 3 documents. Just make sure
# this doesn't raise...
db.test.insert(({"x": i} for i in range(4, 7)))
self.assertEqual(0, len(list(cursor)))
# and that the cursor doesn't think it's still alive.
self.assertFalse(cursor.alive)
# and that the cursor doesn't think it's still alive.
self.assertFalse(cursor.alive)
self.assertEqual(3, db.test.count())
self.assertEqual(3, db.test.count())
finally:
db.drop_collection("test")
def test_distinct(self):
self.db.drop_collection("test")
@ -1089,21 +1087,19 @@ class TestCursor(IntegrationTest):
# Do absolutely nothing...
pass
try:
client.set_cursor_manager(CManager)
docs = []
cursor = db.test.find().batch_size(10)
docs.append(next(cursor))
cursor.close()
docs.extend(cursor)
self.assertEqual(len(docs), 10)
cmd_cursor = {'id': cursor.cursor_id, 'firstBatch': []}
ccursor = CommandCursor(cursor.collection, cmd_cursor,
cursor.address, retrieved=cursor.retrieved)
docs.extend(ccursor)
self.assertEqual(len(docs), 200)
finally:
client.set_cursor_manager(CursorManager)
client.set_cursor_manager(CManager)
self.addCleanup(client.set_cursor_manager, CursorManager)
docs = []
cursor = db.test.find().batch_size(10)
docs.append(next(cursor))
cursor.close()
docs.extend(cursor)
self.assertEqual(len(docs), 10)
cmd_cursor = {'id': cursor.cursor_id, 'firstBatch': []}
ccursor = CommandCursor(cursor.collection, cmd_cursor,
cursor.address, retrieved=cursor.retrieved)
docs.extend(ccursor)
self.assertEqual(len(docs), 200)
if __name__ == "__main__":
unittest.main()

View File

@ -398,50 +398,48 @@ class TestDatabase(IntegrationTest):
self.assertRaises(ConfigurationError, auth_db.add_user,
"user", "password", digestPassword=True)
try:
# Add / authenticate / remove
auth_db.add_user("mike", "password", roles=["dbOwner"])
self.assertRaises(TypeError, db.authenticate, 5, "password")
self.assertRaises(TypeError, db.authenticate, "mike", 5)
self.assertRaises(OperationFailure,
db.authenticate, "mike", "not a real password")
self.assertRaises(OperationFailure,
db.authenticate, "faker", "password")
db.authenticate("mike", "password")
# Add / authenticate / remove
auth_db.add_user("mike", "password", roles=["dbOwner"])
self.addCleanup(remove_all_users, auth_db)
self.assertRaises(TypeError, db.authenticate, 5, "password")
self.assertRaises(TypeError, db.authenticate, "mike", 5)
self.assertRaises(OperationFailure,
db.authenticate, "mike", "not a real password")
self.assertRaises(OperationFailure,
db.authenticate, "faker", "password")
db.authenticate("mike", "password")
db.logout()
# Unicode name and password.
db.authenticate(u("mike"), u("password"))
db.logout()
auth_db.remove_user("mike")
self.assertRaises(OperationFailure,
db.authenticate, "mike", "password")
# Add / authenticate / change password
self.assertRaises(OperationFailure,
db.authenticate, "Gustave", u("Dor\xe9"))
auth_db.add_user("Gustave", u("Dor\xe9"), roles=["dbOwner"])
db.authenticate("Gustave", u("Dor\xe9"))
# Change password.
auth_db.add_user("Gustave", "password", roles=["dbOwner"])
db.logout()
self.assertRaises(OperationFailure,
db.authenticate, "Gustave", u("Dor\xe9"))
self.assertTrue(db.authenticate("Gustave", u("password")))
if not client_context.version.at_least(2, 5, 3, -1):
# Add a readOnly user
with ignore_deprecations():
auth_db.add_user("Ross", "password", read_only=True)
db.logout()
# Unicode name and password.
db.authenticate(u("mike"), u("password"))
db.logout()
auth_db.remove_user("mike")
self.assertRaises(OperationFailure,
db.authenticate, "mike", "password")
# Add / authenticate / change password
self.assertRaises(OperationFailure,
db.authenticate, "Gustave", u("Dor\xe9"))
auth_db.add_user("Gustave", u("Dor\xe9"), roles=["dbOwner"])
db.authenticate("Gustave", u("Dor\xe9"))
# Change password.
auth_db.add_user("Gustave", "password", roles=["dbOwner"])
db.logout()
self.assertRaises(OperationFailure,
db.authenticate, "Gustave", u("Dor\xe9"))
self.assertTrue(db.authenticate("Gustave", u("password")))
if not client_context.version.at_least(2, 5, 3, -1):
# Add a readOnly user
with ignore_deprecations():
auth_db.add_user("Ross", "password", read_only=True)
db.logout()
db.authenticate("Ross", u("password"))
self.assertTrue(
auth_db.system.users.find({"readOnly": True}).count())
finally:
remove_all_users(auth_db)
db.authenticate("Ross", u("password"))
self.assertTrue(
auth_db.system.users.find({"readOnly": True}).count())
@client_context.require_auth
def test_make_user_readonly(self):
@ -449,56 +447,49 @@ class TestDatabase(IntegrationTest):
auth_db = self.client.pymongo_test
db = rs_or_single_client_noauth().pymongo_test
try:
# Make a read-write user.
auth_db.add_user('jesse', 'pw')
# Make a read-write user.
auth_db.add_user('jesse', 'pw')
self.addCleanup(remove_all_users, auth_db)
# Check that we're read-write by default.
db.authenticate('jesse', 'pw')
db.collection.insert({})
db.logout()
# Check that we're read-write by default.
db.authenticate('jesse', 'pw')
db.collection.insert({})
db.logout()
# Make the user read-only.
auth_db.add_user('jesse', 'pw', read_only=True)
# Make the user read-only.
auth_db.add_user('jesse', 'pw', read_only=True)
db.authenticate('jesse', 'pw')
self.assertRaises(OperationFailure, db.collection.insert, {})
finally:
remove_all_users(auth_db)
db.authenticate('jesse', 'pw')
self.assertRaises(OperationFailure, db.collection.insert, {})
@client_context.require_version_min(2, 5, 3, -1)
@client_context.require_auth
def test_default_roles(self):
# "self.client" is logged in as root.
auth_admin = self.client.admin
try:
auth_admin.add_user('test_default_roles', 'pass')
info = auth_admin.command(
'usersInfo', 'test_default_roles')['users'][0]
auth_admin.add_user('test_default_roles', 'pass')
info = auth_admin.command(
'usersInfo', 'test_default_roles')['users'][0]
self.assertEqual("root", info['roles'][0]['role'])
self.assertEqual("root", info['roles'][0]['role'])
# Read only "admin" user
auth_admin.add_user('ro-admin', 'pass', read_only=True)
info = auth_admin.command('usersInfo', 'ro-admin')['users'][0]
self.assertEqual("readAnyDatabase", info['roles'][0]['role'])
finally:
auth_admin.remove_user('test_default_roles')
auth_admin.remove_user('ro-admin')
# Read only "admin" user
auth_admin.add_user('ro-admin', 'pass', read_only=True)
self.addCleanup(auth_admin.remove_user, 'ro-admin')
info = auth_admin.command('usersInfo', 'ro-admin')['users'][0]
self.assertEqual("readAnyDatabase", info['roles'][0]['role'])
# "Non-admin" user
auth_db = self.client.pymongo_test
auth_db.add_user('user', 'pass')
try:
info = auth_db.command('usersInfo', 'user')['users'][0]
self.assertEqual("dbOwner", info['roles'][0]['role'])
self.addCleanup(remove_all_users, auth_db)
info = auth_db.command('usersInfo', 'user')['users'][0]
self.assertEqual("dbOwner", info['roles'][0]['role'])
# Read only "Non-admin" user
auth_db.add_user('ro-user', 'pass', read_only=True)
info = auth_db.command('usersInfo', 'ro-user')['users'][0]
self.assertEqual("read", info['roles'][0]['role'])
finally:
remove_all_users(auth_db)
# Read only "Non-admin" user
auth_db.add_user('ro-user', 'pass', read_only=True)
info = auth_db.command('usersInfo', 'ro-user')['users'][0]
self.assertEqual("read", info['roles'][0]['role'])
@client_context.require_version_min(2, 5, 3, -1)
@client_context.require_auth
@ -506,22 +497,20 @@ class TestDatabase(IntegrationTest):
# "self.client" is logged in as root.
auth_db = self.client.pymongo_test
auth_db.add_user("amalia", "password", roles=["userAdmin"])
self.addCleanup(auth_db.remove_user, "amalia")
try:
db = rs_or_single_client_noauth().pymongo_test
db.authenticate("amalia", "password")
db = rs_or_single_client_noauth().pymongo_test
db.authenticate("amalia", "password")
# This tests the ability to update user attributes.
db.add_user("amalia", "new_password",
customData={"secret": "koalas"})
# This tests the ability to update user attributes.
db.add_user("amalia", "new_password",
customData={"secret": "koalas"})
user_info = db.command("usersInfo", "amalia")
self.assertTrue(user_info["users"])
amalia_user = user_info["users"][0]
self.assertEqual(amalia_user["user"], "amalia")
self.assertEqual(amalia_user["customData"], {"secret": "koalas"})
finally:
auth_db.remove_user("amalia")
user_info = db.command("usersInfo", "amalia")
self.assertTrue(user_info["users"])
amalia_user = user_info["users"][0]
self.assertEqual(amalia_user["user"], "amalia")
self.assertEqual(amalia_user["customData"], {"secret": "koalas"})
@client_context.require_auth
def test_authenticate_multiple(self):
@ -537,46 +526,44 @@ class TestDatabase(IntegrationTest):
users_db = client.pymongo_test
other_db = client.pymongo_test1
try:
self.assertRaises(OperationFailure, users_db.test.find_one)
self.assertRaises(OperationFailure, users_db.test.find_one)
if client_context.version.at_least(2, 5, 3, -1):
admin_db_auth.add_user('ro-admin', 'pass',
roles=["userAdmin", "readAnyDatabase"])
else:
admin_db_auth.add_user('ro-admin', 'pass', read_only=True)
if client_context.version.at_least(2, 5, 3, -1):
admin_db_auth.add_user('ro-admin', 'pass',
roles=["userAdmin", "readAnyDatabase"])
else:
admin_db_auth.add_user('ro-admin', 'pass', read_only=True)
users_db_auth.add_user('user', 'pass',
roles=["userAdmin", "readWrite"])
self.addCleanup(admin_db_auth.remove_user, 'ro-admin')
users_db_auth.add_user('user', 'pass',
roles=["userAdmin", "readWrite"])
self.addCleanup(remove_all_users, users_db_auth)
# Regular user should be able to query its own db, but
# no other.
users_db.authenticate('user', 'pass')
self.assertEqual(0, users_db.test.count())
self.assertRaises(OperationFailure, other_db.test.find_one)
# Regular user should be able to query its own db, but
# no other.
users_db.authenticate('user', 'pass')
self.assertEqual(0, users_db.test.count())
self.assertRaises(OperationFailure, other_db.test.find_one)
# Admin read-only user should be able to query any db,
# but not write.
admin_db.authenticate('ro-admin', 'pass')
self.assertEqual(0, other_db.test.count())
self.assertRaises(OperationFailure,
other_db.test.insert, {})
# Admin read-only user should be able to query any db,
# but not write.
admin_db.authenticate('ro-admin', 'pass')
self.assertEqual(0, other_db.test.count())
self.assertRaises(OperationFailure,
other_db.test.insert, {})
# Close all sockets.
client.disconnect()
# Close all sockets.
client.disconnect()
# We should still be able to write to the regular user's db.
self.assertTrue(users_db.test.remove())
# We should still be able to write to the regular user's db.
self.assertTrue(users_db.test.remove())
# And read from other dbs...
self.assertEqual(0, other_db.test.count())
# And read from other dbs...
self.assertEqual(0, other_db.test.count())
# But still not write to other dbs.
self.assertRaises(OperationFailure,
other_db.test.insert, {})
finally:
remove_all_users(users_db_auth)
admin_db_auth.remove_user('ro-admin')
# But still not write to other dbs.
self.assertRaises(OperationFailure,
other_db.test.insert, {})
def test_id_ordering(self):
# PyMongo attempts to have _id show up first

View File

@ -382,69 +382,69 @@ class TestSSL(unittest.TestCase):
raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")
if not server_started_with_auth(ssl_client):
raise SkipTest('Authentication is not enabled on server')
self.addCleanup(ssl_client['$external'].logout)
self.addCleanup(remove_all_users, ssl_client['$external'])
# Give admin all necessary privileges.
ssl_client['$external'].add_user(MONGODB_X509_USERNAME, roles=[
{'role': 'readWriteAnyDatabase', 'db': 'admin'},
{'role': 'userAdminAnyDatabase', 'db': 'admin'}])
coll = ssl_client.pymongo_test.test
self.assertRaises(OperationFailure, coll.count)
self.assertTrue(ssl_client.admin.authenticate(
MONGODB_X509_USERNAME, mechanism='MONGODB-X509'))
self.assertTrue(coll.remove())
uri = ('mongodb://%s@%s:%d/?authMechanism='
'MONGODB-X509' % (
quote_plus(MONGODB_X509_USERNAME), host, port))
# SSL options aren't supported in the URI...
self.assertTrue(MongoClient(uri,
ssl=True, ssl_certfile=CLIENT_PEM))
# Should require a username
uri = ('mongodb://%s:%d/?authMechanism=MONGODB-X509' % (host,
port))
client_bad = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
self.assertRaises(OperationFailure,
client_bad.pymongo_test.test.remove)
# Auth should fail if username and certificate do not match
uri = ('mongodb://%s@%s:%d/?authMechanism='
'MONGODB-X509' % (
quote_plus("not the username"), host, port))
bad_client = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
with self.assertRaises(OperationFailure):
bad_client.pymongo_test.test.find_one()
self.assertRaises(OperationFailure, ssl_client.admin.authenticate,
"not the username",
mechanism="MONGODB-X509")
# Invalid certificate (using CA certificate as client certificate)
uri = ('mongodb://%s@%s:%d/?authMechanism='
'MONGODB-X509' % (
quote_plus(MONGODB_X509_USERNAME), host, port))
# These tests will raise SSLError (>= 3.2) or ConnectionFailure
# (2.x) depending on where OpenSSL first sees the PEM file.
try:
self.assertRaises(OperationFailure, coll.count)
self.assertTrue(ssl_client.admin.authenticate(
MONGODB_X509_USERNAME, mechanism='MONGODB-X509'))
self.assertTrue(coll.remove())
uri = ('mongodb://%s@%s:%d/?authMechanism='
'MONGODB-X509' % (
quote_plus(MONGODB_X509_USERNAME), host, port))
# SSL options aren't supported in the URI...
self.assertTrue(MongoClient(uri,
ssl=True, ssl_certfile=CLIENT_PEM))
with client_knobs(server_wait_time=0.1):
connected(MongoClient(uri, ssl=True, ssl_certfile=CA_PEM))
except (ssl.SSLError, ConnectionFailure):
pass
else:
self.fail("Invalid certificate accepted.")
# Should require a username
uri = ('mongodb://%s:%d/?authMechanism=MONGODB-X509' % (host,
port))
client_bad = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
self.assertRaises(OperationFailure,
client_bad.pymongo_test.test.remove)
try:
with client_knobs(server_wait_time=0.1):
connected(MongoClient(pair, ssl=True, ssl_certfile=CA_PEM))
except (ssl.SSLError, ConnectionFailure):
pass
else:
self.fail("Invalid certificate accepted.")
# Auth should fail if username and certificate do not match
uri = ('mongodb://%s@%s:%d/?authMechanism='
'MONGODB-X509' % (
quote_plus("not the username"), host, port))
bad_client = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
with self.assertRaises(OperationFailure):
bad_client.pymongo_test.test.find_one()
self.assertRaises(OperationFailure, ssl_client.admin.authenticate,
"not the username",
mechanism="MONGODB-X509")
# Invalid certificate (using CA certificate as client certificate)
uri = ('mongodb://%s@%s:%d/?authMechanism='
'MONGODB-X509' % (
quote_plus(MONGODB_X509_USERNAME), host, port))
# These tests will raise SSLError (>= 3.2) or ConnectionFailure
# (2.x) depending on where OpenSSL first sees the PEM file.
try:
with client_knobs(server_wait_time=0.1):
connected(MongoClient(uri, ssl=True, ssl_certfile=CA_PEM))
except (ssl.SSLError, ConnectionFailure):
pass
else:
self.fail("Invalid certificate accepted.")
try:
with client_knobs(server_wait_time=0.1):
connected(MongoClient(pair, ssl=True, ssl_certfile=CA_PEM))
except (ssl.SSLError, ConnectionFailure):
pass
else:
self.fail("Invalid certificate accepted.")
# Cleanup
finally:
remove_all_users(ssl_client['$external'])
ssl_client['$external'].logout()
if __name__ == "__main__":
unittest.main()