PYTHON-715 Fix tests for MongoDB >= 2.7.1 when running with auth enabled.
This commit is contained in:
parent
c2e6471ee6
commit
d7ec3a7704
@ -787,8 +787,9 @@ class Database(common.BaseObject):
|
||||
# users.
|
||||
if exc.code in common.COMMAND_NOT_FOUND_CODES:
|
||||
self._legacy_add_user(name, password, read_only, **kwargs)
|
||||
# Unauthorized. MongoDB >= 2.7.1 has a narrow localhost exception,
|
||||
# and we must add a user before sending commands.
|
||||
return
|
||||
# Unauthorized. Attempt to create the user in case of
|
||||
# localhost exception.
|
||||
elif exc.code == 13:
|
||||
self._create_or_update_user(
|
||||
True, name, password, read_only, **kwargs)
|
||||
|
||||
@ -45,6 +45,9 @@ port2 = int(os.environ.get("DB_PORT2", 27018))
|
||||
host3 = _unicode(os.environ.get("DB_IP3", 'localhost'))
|
||||
port3 = int(os.environ.get("DB_PORT3", 27019))
|
||||
|
||||
db_user = _unicode(os.environ.get("DB_USER", "user"))
|
||||
db_pwd = _unicode(os.environ.get("DB_PASSWORD", "password"))
|
||||
|
||||
|
||||
class ClientContext(object):
|
||||
|
||||
@ -70,12 +73,31 @@ class ClientContext(object):
|
||||
self.w = len(self.ismaster.get("hosts", [])) or 1
|
||||
self.setname = self.ismaster.get('setName', '')
|
||||
self.rs_client = None
|
||||
self.version = Version.from_client(self.client)
|
||||
if self.setname:
|
||||
self.rs_client = pymongo.MongoReplicaSetClient(
|
||||
pair, replicaSet=self.setname)
|
||||
self.cmd_line = self.client.admin.command('getCmdLineOpts')
|
||||
self.version = Version.from_client(self.client)
|
||||
self.auth_enabled = self._server_started_with_auth()
|
||||
try:
|
||||
self.cmd_line = self.client.admin.command('getCmdLineOpts')
|
||||
except pymongo.errors.OperationFailure as e:
|
||||
if e.code == 13:
|
||||
# Unauthorized.
|
||||
self.auth_enabled = True
|
||||
else:
|
||||
raise
|
||||
else:
|
||||
self.auth_enabled = self._server_started_with_auth()
|
||||
if self.auth_enabled:
|
||||
roles = {}
|
||||
if self.version.at_least(2, 5, 3, -1):
|
||||
roles = {'roles': ['root']}
|
||||
self.client.admin.add_user(db_user, db_pwd, **roles)
|
||||
self.client.admin.authenticate(db_user, db_pwd)
|
||||
if self.rs_client:
|
||||
self.rs_client.admin.authenticate(db_user, db_pwd)
|
||||
self.cmd_line = self.client.admin.command('getCmdLineOpts')
|
||||
# May not have this if OperationFailure was raised earlier.
|
||||
self.cmd_line = self.client.admin.command('getCmdLineOpts')
|
||||
self.test_commands_enabled = ('testCommandsEnabled=1'
|
||||
in self.cmd_line['argv'])
|
||||
self.is_mongos = (self.ismaster.get('msg') == 'isdbgrid')
|
||||
@ -143,6 +165,12 @@ class ClientContext(object):
|
||||
"Authentication is not enabled on the server",
|
||||
func=func))
|
||||
|
||||
def require_no_auth(self, func):
|
||||
"""Run a test only if the server is running without auth enabled."""
|
||||
return self._require(not self.auth_enabled,
|
||||
"Authentication must not be enabled on the server",
|
||||
func=func)
|
||||
|
||||
def require_replica_set(self, func):
|
||||
"""Run a test only if the client is connected to a replica set."""
|
||||
return self._require(self.rs_client is not None,
|
||||
@ -183,25 +211,27 @@ class IntegrationTest(unittest.TestCase):
|
||||
pass
|
||||
|
||||
|
||||
def connection_string(seeds=[pair]):
|
||||
if client_context.auth_enabled:
|
||||
return "mongodb://%s:%s@%s" % (db_user, db_pwd, ','.join(seeds))
|
||||
return "mongodb://%s" % pair
|
||||
|
||||
|
||||
def setup():
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter("always")
|
||||
|
||||
|
||||
def teardown():
|
||||
try:
|
||||
c = pymongo.MongoClient(host, port)
|
||||
except pymongo.errors.ConnectionFailure:
|
||||
# Tests where ssl=True can cause connection failures here.
|
||||
# Ignore and continue.
|
||||
return
|
||||
|
||||
c = client_context.client
|
||||
c.drop_database("pymongo-pooling-tests")
|
||||
c.drop_database("pymongo_test")
|
||||
c.drop_database("pymongo_test1")
|
||||
c.drop_database("pymongo_test2")
|
||||
c.drop_database("pymongo_test_mike")
|
||||
c.drop_database("pymongo_test_bernie")
|
||||
if client_context.auth_enabled:
|
||||
c.admin.remove_user(db_user)
|
||||
|
||||
|
||||
class PymongoTestRunner(unittest.TextTestRunner):
|
||||
|
||||
@ -235,10 +235,11 @@ class TestAuthURIOptions(unittest.TestCase):
|
||||
client = MongoClient(host, port)
|
||||
response = client.admin.command('ismaster')
|
||||
self.set_name = str(response.get('setName', ''))
|
||||
client.admin.add_user('admin', 'pass', roles=['userAdminAnyDatabase',
|
||||
'dbAdminAnyDatabase',
|
||||
'readWriteAnyDatabase',
|
||||
'clusterAdmin'])
|
||||
client_context.client.admin.add_user('admin', 'pass',
|
||||
roles=['userAdminAnyDatabase',
|
||||
'dbAdminAnyDatabase',
|
||||
'readWriteAnyDatabase',
|
||||
'clusterAdmin'])
|
||||
client.admin.authenticate('admin', 'pass')
|
||||
client.pymongo_test.add_user('user', 'pass',
|
||||
roles=['userAdmin', 'readWrite'])
|
||||
@ -314,26 +315,14 @@ class TestDelegatedAuth(unittest.TestCase):
|
||||
@client_context.require_version_max(2, 5, 3)
|
||||
@client_context.require_version_min(2, 4, 0)
|
||||
def setUp(self):
|
||||
self.client = MongoClient(host, port)
|
||||
# Give admin all privileges.
|
||||
self.client.admin.add_user('admin', 'pass',
|
||||
roles=['readAnyDatabase',
|
||||
'readWriteAnyDatabase',
|
||||
'userAdminAnyDatabase',
|
||||
'dbAdminAnyDatabase',
|
||||
'clusterAdmin'])
|
||||
self.client = client_context.client
|
||||
|
||||
def tearDown(self):
|
||||
self.client.admin.authenticate('admin', 'pass')
|
||||
self.client.pymongo_test.remove_user('user')
|
||||
self.client.pymongo_test2.remove_user('user')
|
||||
self.client.pymongo_test2.foo.remove()
|
||||
self.client.admin.remove_user('admin')
|
||||
self.client.admin.logout()
|
||||
self.client = None
|
||||
self.client.pymongo_test2.foo.drop()
|
||||
|
||||
def test_delegated_auth(self):
|
||||
self.client.admin.authenticate('admin', 'pass')
|
||||
self.client.pymongo_test2.foo.remove()
|
||||
self.client.pymongo_test2.foo.insert({})
|
||||
# User definition with no roles in pymongo_test.
|
||||
@ -342,27 +331,27 @@ class TestDelegatedAuth(unittest.TestCase):
|
||||
self.client.pymongo_test2.add_user('user',
|
||||
userSource='pymongo_test',
|
||||
roles=['read'])
|
||||
self.client.admin.logout()
|
||||
auth_c = MongoClient(host, port)
|
||||
self.assertRaises(OperationFailure,
|
||||
self.client.pymongo_test2.foo.find_one)
|
||||
auth_c.pymongo_test2.foo.find_one)
|
||||
# Auth must occur on the db where the user is defined.
|
||||
self.assertRaises(OperationFailure,
|
||||
self.client.pymongo_test2.authenticate,
|
||||
auth_c.pymongo_test2.authenticate,
|
||||
'user', 'pass')
|
||||
# Auth directly
|
||||
self.assertTrue(self.client.pymongo_test.authenticate('user', 'pass'))
|
||||
self.assertTrue(self.client.pymongo_test2.foo.find_one())
|
||||
self.client.pymongo_test.logout()
|
||||
self.assertTrue(auth_c.pymongo_test.authenticate('user', 'pass'))
|
||||
self.assertTrue(auth_c.pymongo_test2.foo.find_one())
|
||||
auth_c.pymongo_test.logout()
|
||||
self.assertRaises(OperationFailure,
|
||||
self.client.pymongo_test2.foo.find_one)
|
||||
auth_c.pymongo_test2.foo.find_one)
|
||||
# Auth using source
|
||||
self.assertTrue(self.client.pymongo_test2.authenticate(
|
||||
self.assertTrue(auth_c.pymongo_test2.authenticate(
|
||||
'user', 'pass', source='pymongo_test'))
|
||||
self.assertTrue(self.client.pymongo_test2.foo.find_one())
|
||||
self.assertTrue(auth_c.pymongo_test2.foo.find_one())
|
||||
# Must logout from the db authenticate was called on.
|
||||
self.client.pymongo_test2.logout()
|
||||
auth_c.pymongo_test2.logout()
|
||||
self.assertRaises(OperationFailure,
|
||||
self.client.pymongo_test2.foo.find_one)
|
||||
auth_c.pymongo_test2.foo.find_one)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -20,8 +20,9 @@ sys.path[0:0] = [""]
|
||||
|
||||
from bson import InvalidDocument, SON
|
||||
from bson.py3compat import string_type
|
||||
from pymongo import MongoClient
|
||||
from pymongo.errors import BulkWriteError, InvalidOperation, OperationFailure
|
||||
from test import client_context, unittest
|
||||
from test import client_context, unittest, host, port
|
||||
from test.utils import oid_generated_on_client, remove_all_users
|
||||
|
||||
|
||||
@ -1151,8 +1152,6 @@ class TestBulkAuthorization(BulkTestBase):
|
||||
super(TestBulkAuthorization, self).setUp()
|
||||
self.coll.remove()
|
||||
|
||||
self.db.add_user('dbOwner', 'pw', roles=['dbOwner'])
|
||||
self.db.authenticate('dbOwner', 'pw')
|
||||
self.db.add_user('readonly', 'pw', roles=['read'])
|
||||
self.db.command(
|
||||
'createRole', 'noremove',
|
||||
@ -1163,31 +1162,30 @@ class TestBulkAuthorization(BulkTestBase):
|
||||
roles=[])
|
||||
|
||||
self.db.add_user('noremove', 'pw', roles=['noremove'])
|
||||
self.db.logout()
|
||||
|
||||
def tearDown(self):
|
||||
self.db.logout()
|
||||
self.db.authenticate('dbOwner', 'pw')
|
||||
self.db.command('dropRole', 'noremove')
|
||||
remove_all_users(self.db)
|
||||
self.db.logout()
|
||||
self.db.connection.disconnect()
|
||||
|
||||
def test_readonly(self):
|
||||
# We test that an authorization failure aborts the batch and is raised
|
||||
# as OperationFailure.
|
||||
db = client_context.client.pymongo_test
|
||||
cli = MongoClient(host, port)
|
||||
db = cli.pymongo_test
|
||||
coll = db.test
|
||||
db.authenticate('readonly', 'pw')
|
||||
bulk = self.coll.initialize_ordered_bulk_op()
|
||||
bulk = coll.initialize_ordered_bulk_op()
|
||||
bulk.insert({'x': 1})
|
||||
self.assertRaises(OperationFailure, bulk.execute)
|
||||
|
||||
def test_no_remove(self):
|
||||
# We test that an authorization failure aborts the batch and is raised
|
||||
# as OperationFailure.
|
||||
db = client_context.client.pymongo_test
|
||||
cli = MongoClient(host, port)
|
||||
db = cli.pymongo_test
|
||||
coll = db.test
|
||||
db.authenticate('noremove', 'pw')
|
||||
bulk = self.coll.initialize_ordered_bulk_op()
|
||||
bulk = coll.initialize_ordered_bulk_op()
|
||||
bulk.insert({'x': 1})
|
||||
bulk.find({'x': 2}).upsert().replace_one({'x': 2})
|
||||
bulk.find({}).remove() # Prohibited.
|
||||
@ -1195,6 +1193,5 @@ class TestBulkAuthorization(BulkTestBase):
|
||||
self.assertRaises(OperationFailure, bulk.execute)
|
||||
self.assertEqual(set([1, 2]), set(self.coll.distinct('x')))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@ -29,7 +29,7 @@ from bson.tz_util import utc
|
||||
from pymongo.mongo_client import MongoClient
|
||||
from pymongo.database import Database
|
||||
from pymongo.pool import SocketInfo
|
||||
from pymongo import thread_util, common
|
||||
from pymongo import thread_util
|
||||
from pymongo.errors import (AutoReconnect,
|
||||
ConfigurationError,
|
||||
ConnectionFailure,
|
||||
@ -37,6 +37,7 @@ from pymongo.errors import (AutoReconnect,
|
||||
OperationFailure,
|
||||
PyMongoError)
|
||||
from test import (client_context,
|
||||
connection_string,
|
||||
host,
|
||||
pair,
|
||||
port,
|
||||
@ -46,6 +47,7 @@ from test import (client_context,
|
||||
from test.pymongo_mocks import MockClient
|
||||
from test.utils import (assertRaisesExactly,
|
||||
delay,
|
||||
get_client,
|
||||
remove_all_users,
|
||||
server_is_master_with_slave,
|
||||
TestRequestMixin,
|
||||
@ -55,13 +57,7 @@ from test.utils import (assertRaisesExactly,
|
||||
get_pool)
|
||||
|
||||
|
||||
def get_client(*args, **kwargs):
|
||||
return MongoClient(host, port, *args, **kwargs)
|
||||
|
||||
|
||||
class TestClientNoConnect(unittest.TestCase):
|
||||
"""MongoClient unit tests that don't require connecting to MongoDB."""
|
||||
|
||||
class TestClient(unittest.TestCase, TestRequestMixin):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.client = MongoClient(host, port, _connect=False)
|
||||
@ -158,7 +154,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
self.assertEqual(None, c.host)
|
||||
self.assertEqual(None, c.port)
|
||||
|
||||
c.pymongo_test.test.find_one() # Auto-connect.
|
||||
c.pymongo_test.command('ismaster') # Auto-connect.
|
||||
self.assertEqual(host, c.host)
|
||||
self.assertEqual(port, c.port)
|
||||
|
||||
@ -282,8 +278,8 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
|
||||
c.end_request()
|
||||
self.assertFalse(c.in_request())
|
||||
c.copy_database("pymongo_test", "pymongo_test2",
|
||||
"%s:%d" % (host, port))
|
||||
|
||||
c.copy_database("pymongo_test", "pymongo_test2")
|
||||
# copy_database() didn't accidentally restart the request
|
||||
self.assertFalse(c.in_request())
|
||||
|
||||
@ -295,30 +291,30 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
c.drop_database("pymongo_test1")
|
||||
|
||||
c.admin.add_user("admin", "password")
|
||||
c.admin.authenticate("admin", "password")
|
||||
auth_c = MongoClient(host, port)
|
||||
auth_c.admin.authenticate("admin", "password")
|
||||
try:
|
||||
c.pymongo_test.add_user("mike", "password")
|
||||
auth_c.pymongo_test.add_user("mike", "password")
|
||||
|
||||
self.assertRaises(OperationFailure, c.copy_database,
|
||||
self.assertRaises(OperationFailure, auth_c.copy_database,
|
||||
"pymongo_test", "pymongo_test1",
|
||||
username="foo", password="bar")
|
||||
self.assertFalse("pymongo_test1" in c.database_names())
|
||||
self.assertFalse("pymongo_test1" in auth_c.database_names())
|
||||
|
||||
self.assertRaises(OperationFailure, c.copy_database,
|
||||
self.assertRaises(OperationFailure, auth_c.copy_database,
|
||||
"pymongo_test", "pymongo_test1",
|
||||
username="mike", password="bar")
|
||||
self.assertFalse("pymongo_test1" in c.database_names())
|
||||
self.assertFalse("pymongo_test1" in auth_c.database_names())
|
||||
|
||||
c.copy_database("pymongo_test", "pymongo_test1",
|
||||
username="mike", password="password")
|
||||
self.assertTrue("pymongo_test1" in c.database_names())
|
||||
self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])
|
||||
auth_c.copy_database("pymongo_test", "pymongo_test1",
|
||||
username="mike", password="password")
|
||||
self.assertTrue("pymongo_test1" in auth_c.database_names())
|
||||
self.assertEqual("bar",
|
||||
auth_c.pymongo_test1.test.find_one()["foo"])
|
||||
finally:
|
||||
# Cleanup
|
||||
remove_all_users(c.pymongo_test)
|
||||
c.admin.remove_user("admin")
|
||||
c.admin.logout()
|
||||
c.disconnect()
|
||||
|
||||
def test_disconnect(self):
|
||||
coll = self.client.pymongo_test.bar
|
||||
@ -340,7 +336,6 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
@client_context.require_auth
|
||||
def test_auth_from_uri(self):
|
||||
self.client.admin.add_user("admin", "pass")
|
||||
self.client.admin.authenticate("admin", "pass")
|
||||
try:
|
||||
self.client.pymongo_test.add_user(
|
||||
"user", "pass", roles=['userAdmin', 'readWrite'])
|
||||
@ -378,9 +373,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
finally:
|
||||
# Clean up.
|
||||
remove_all_users(self.client.pymongo_test)
|
||||
remove_all_users(self.client.admin)
|
||||
self.client.admin.logout()
|
||||
self.client.disconnect()
|
||||
self.client.admin.remove_user('admin')
|
||||
|
||||
@client_context.require_auth
|
||||
def test_lazy_auth_raises_operation_failure(self):
|
||||
@ -394,7 +387,9 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
def test_unix_socket(self):
|
||||
if not hasattr(socket, "AF_UNIX"):
|
||||
raise SkipTest("UNIX-sockets are not supported on this system")
|
||||
if sys.platform == 'darwin' and client_context.auth_enabled:
|
||||
if (sys.platform == 'darwin' and
|
||||
client_context.auth_enabled and
|
||||
not client_context.version.at_least(2, 7, 1)):
|
||||
raise SkipTest("SERVER-8492")
|
||||
|
||||
mongodb_socket = '/tmp/mongodb-27017.sock'
|
||||
@ -491,7 +486,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
finally:
|
||||
c.document_class = dict
|
||||
|
||||
c = MongoClient(host, port, document_class=SON)
|
||||
c = get_client(pair, document_class=SON)
|
||||
db = c.pymongo_test
|
||||
|
||||
self.assertEqual(SON, c.document_class)
|
||||
@ -511,29 +506,28 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
self.assertEqual(10.5, get_pool(client).opts.socket_timeout)
|
||||
|
||||
def test_socket_timeout_ms_validation(self):
|
||||
c = get_client(socketTimeoutMS=10 * 1000)
|
||||
c = get_client(pair, socketTimeoutMS=10 * 1000)
|
||||
self.assertEqual(10, c._MongoClient__pool_opts.socket_timeout)
|
||||
|
||||
c = get_client(socketTimeoutMS=None)
|
||||
c = get_client(pair, socketTimeoutMS=None)
|
||||
self.assertEqual(None, c._MongoClient__pool_opts.socket_timeout)
|
||||
|
||||
self.assertRaises(ConfigurationError,
|
||||
get_client, socketTimeoutMS=0)
|
||||
get_client, pair, socketTimeoutMS=0)
|
||||
|
||||
self.assertRaises(ConfigurationError,
|
||||
get_client, socketTimeoutMS=-1)
|
||||
get_client, pair, socketTimeoutMS=-1)
|
||||
|
||||
self.assertRaises(ConfigurationError,
|
||||
get_client, socketTimeoutMS=1e10)
|
||||
get_client, pair, socketTimeoutMS=1e10)
|
||||
|
||||
self.assertRaises(ConfigurationError,
|
||||
get_client, socketTimeoutMS='foo')
|
||||
get_client, pair, socketTimeoutMS='foo')
|
||||
|
||||
def test_socket_timeout(self):
|
||||
no_timeout = self.client
|
||||
timeout_sec = 1
|
||||
timeout = MongoClient(
|
||||
host, port, socketTimeoutMS=1000 * timeout_sec)
|
||||
timeout = get_client(pair, socketTimeoutMS=1000 * timeout_sec)
|
||||
|
||||
no_timeout.pymongo_test.drop_collection("test")
|
||||
no_timeout.pymongo_test.test.insert({"x": 1})
|
||||
@ -560,7 +554,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
def test_tz_aware(self):
|
||||
self.assertRaises(ConfigurationError, MongoClient, tz_aware='foo')
|
||||
|
||||
aware = MongoClient(host, port, tz_aware=True)
|
||||
aware = get_client(pair, tz_aware=True)
|
||||
naive = self.client
|
||||
aware.pymongo_test.drop_collection("test")
|
||||
|
||||
@ -622,7 +616,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
def test_contextlib(self):
|
||||
import contextlib
|
||||
|
||||
client = get_client(auto_start_request=False)
|
||||
client = get_client(pair, auto_start_request=False)
|
||||
client.pymongo_test.drop_collection("test")
|
||||
client.pymongo_test.test.insert({"foo": "bar"})
|
||||
|
||||
@ -675,13 +669,13 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
for bad_horrible_value in (None, 5, 'hi!'):
|
||||
self.assertRaises(
|
||||
(TypeError, ConfigurationError),
|
||||
lambda: get_client(auto_start_request=bad_horrible_value)
|
||||
lambda: get_client(pair, auto_start_request=bad_horrible_value)
|
||||
)
|
||||
|
||||
# auto_start_request should default to False
|
||||
self.assertFalse(self.client.auto_start_request)
|
||||
|
||||
client = get_client(auto_start_request=True)
|
||||
client = get_client(pair, auto_start_request=True)
|
||||
self.assertTrue(client.auto_start_request)
|
||||
|
||||
# Assure we acquire a request socket.
|
||||
@ -834,7 +828,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
def test_operation_failure_with_request(self):
|
||||
# Ensure MongoClient doesn't close socket after it gets an error
|
||||
# response to getLastError. PYTHON-395.
|
||||
c = get_client(auto_start_request=True)
|
||||
c = get_client(pair, auto_start_request=True)
|
||||
pool = get_pool(c)
|
||||
|
||||
# Pool reserves a socket for this thread.
|
||||
@ -867,7 +861,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
_connect=False)
|
||||
|
||||
c.set_wire_version_range('a:1', 1, 5)
|
||||
c.db.collection.find_one() # Connect.
|
||||
c.db.command('ismaster') # Connect.
|
||||
self.assertEqual(c.min_wire_version, 1)
|
||||
self.assertEqual(c.max_wire_version, 5)
|
||||
|
||||
@ -889,7 +883,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
|
||||
# Starts with default max batch size.
|
||||
self.assertEqual(1000, c.max_write_batch_size)
|
||||
c.db.collection.find_one() # Connect.
|
||||
c.db.command('ismaster') # Connect.
|
||||
# Uses primary's max batch size.
|
||||
self.assertEqual(c.max_write_batch_size, 1)
|
||||
|
||||
@ -897,7 +891,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
c.mock_primary = 'b:2'
|
||||
c.disconnect()
|
||||
self.assertEqual(1000, c.max_write_batch_size)
|
||||
c.db.collection.find_one() # Connect.
|
||||
c.db.command('ismaster') # Connect.
|
||||
self.assertEqual(c.max_write_batch_size, 2)
|
||||
|
||||
def test_wire_version_mongos_ha(self):
|
||||
@ -911,7 +905,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
c.set_wire_version_range('a:1', 2, 5)
|
||||
c.set_wire_version_range('b:2', 2, 2)
|
||||
c.set_wire_version_range('c:3', 1, 1)
|
||||
c.db.collection.find_one() # Connect.
|
||||
c.db.command('ismaster') # Connect.
|
||||
|
||||
# Which member did we use?
|
||||
used_host = '%s:%s' % (c.host, c.port)
|
||||
@ -923,7 +917,7 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
c.set_wire_version_range('b:2', 0, 0)
|
||||
c.set_wire_version_range('c:3', 0, 0)
|
||||
c.disconnect()
|
||||
c.db.collection.find_one()
|
||||
c.db.command('ismaster')
|
||||
used_host = '%s:%s' % (c.host, c.port)
|
||||
expected_min, expected_max = c.mock_wire_versions[used_host]
|
||||
self.assertEqual(expected_min, c.min_wire_version)
|
||||
@ -939,20 +933,20 @@ class TestClient(IntegrationTest, TestRequestMixin):
|
||||
MongoClient, host, port, replicaSet='bad' + name)
|
||||
|
||||
def test_lazy_connect_w0(self):
|
||||
client = get_client(_connect=False)
|
||||
client = get_client(connection_string(), _connect=False)
|
||||
client.pymongo_test.test.insert({}, w=0)
|
||||
|
||||
client = get_client(_connect=False)
|
||||
client = get_client(connection_string(), _connect=False)
|
||||
client.pymongo_test.test.update({}, {'$set': {'x': 1}}, w=0)
|
||||
|
||||
client = get_client(_connect=False)
|
||||
client = get_client(connection_string(), _connect=False)
|
||||
client.pymongo_test.test.remove(w=0)
|
||||
|
||||
|
||||
class TestClientLazyConnect(IntegrationTest, _TestLazyConnectMixin):
|
||||
|
||||
def _get_client(self, **kwargs):
|
||||
return get_client(**kwargs)
|
||||
return get_client(connection_string(), **kwargs)
|
||||
|
||||
|
||||
class TestClientLazyConnectBadSeeds(IntegrationTest):
|
||||
@ -962,7 +956,7 @@ class TestClientLazyConnectBadSeeds(IntegrationTest):
|
||||
|
||||
# Assume there are no open mongods listening on a.com, b.com, ....
|
||||
bad_seeds = ['%s.com' % chr(ord('a') + i) for i in range(10)]
|
||||
return MongoClient(bad_seeds, **kwargs)
|
||||
return get_client(bad_seeds, **kwargs)
|
||||
|
||||
def test_connect(self):
|
||||
def reset(dummy):
|
||||
@ -993,7 +987,7 @@ class TestClientLazyConnectOneGoodSeed(
|
||||
|
||||
# MongoClient puts the seeds in a set before iterating, so order is
|
||||
# undefined.
|
||||
return MongoClient(seeds, **kwargs)
|
||||
return get_client(connection_string(seeds=seeds), **kwargs)
|
||||
|
||||
def test_insert(self):
|
||||
def reset(collection):
|
||||
@ -1030,7 +1024,7 @@ class TestMongoClientFailover(IntegrationTest):
|
||||
|
||||
# Force reconnect.
|
||||
c.disconnect()
|
||||
c.db.collection.find_one()
|
||||
c.db.command('ismaster')
|
||||
self.assertEqual('b', c.host)
|
||||
self.assertEqual(2, c.port)
|
||||
|
||||
@ -1059,7 +1053,7 @@ class TestMongoClientFailover(IntegrationTest):
|
||||
|
||||
# So it can reconnect.
|
||||
c.revive_host('a:1')
|
||||
c.db.collection.find_one()
|
||||
c.db.command('ismaster')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -39,7 +39,6 @@ from pymongo import message as message_module
|
||||
from pymongo import MongoClient
|
||||
from pymongo.collection import Collection
|
||||
from pymongo.command_cursor import CommandCursor
|
||||
from pymongo.database import Database
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.son_manipulator import SONManipulator
|
||||
from pymongo.errors import (DocumentTooLarge,
|
||||
@ -52,7 +51,7 @@ from pymongo.errors import (DocumentTooLarge,
|
||||
from test.test_client import get_client, IntegrationTest
|
||||
from test.utils import (is_mongos, joinall, enable_text_search, get_pool,
|
||||
oid_generated_on_client)
|
||||
from test import client_context, host, port, qcheck, unittest
|
||||
from test import client_context, host, port, pair, qcheck, unittest
|
||||
|
||||
|
||||
class TestCollectionNoConnect(unittest.TestCase):
|
||||
@ -1715,7 +1714,7 @@ class TestCollection(IntegrationTest):
|
||||
# Insert enough documents to require more than one batch
|
||||
self.db.test.insert([{'i': i} for i in range(150)])
|
||||
|
||||
client = get_client(max_pool_size=1)
|
||||
client = get_client(pair, max_pool_size=1)
|
||||
socks = get_pool(client).sockets
|
||||
self.assertEqual(1, len(socks))
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ from pymongo.mongo_client import MongoClient
|
||||
from pymongo.mongo_replica_set_client import MongoReplicaSetClient
|
||||
from pymongo.errors import ConfigurationError, OperationFailure
|
||||
from test import client_context, pair, unittest
|
||||
from test.utils import get_client, get_rs_client
|
||||
|
||||
|
||||
@client_context.require_connection
|
||||
@ -208,7 +209,7 @@ class TestCommon(unittest.TestCase):
|
||||
self.assertEqual(wc.to_dict(), coll.write_concern)
|
||||
|
||||
def test_mongo_client(self):
|
||||
m = MongoClient(pair, w=0)
|
||||
m = get_client(pair, w=0)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
doc = {"_id": ObjectId()}
|
||||
@ -217,16 +218,16 @@ class TestCommon(unittest.TestCase):
|
||||
self.assertTrue(coll.insert(doc))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoClient(pair)
|
||||
m = get_client(pair)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoClient("mongodb://%s/" % (pair,))
|
||||
m = get_client("mongodb://%s/" % (pair,))
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
m = MongoClient("mongodb://%s/?w=0" % (pair,))
|
||||
m = get_client("mongodb://%s/?w=0" % (pair,))
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc))
|
||||
|
||||
@ -237,7 +238,7 @@ class TestCommon(unittest.TestCase):
|
||||
@client_context.require_replica_set
|
||||
def test_mongo_replica_set_client(self):
|
||||
setname = client_context.setname
|
||||
m = MongoReplicaSetClient(pair, replicaSet=setname, w=0)
|
||||
m = get_rs_client(pair, replicaSet=setname, w=0)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
doc = {"_id": ObjectId()}
|
||||
|
||||
@ -46,7 +46,13 @@ from pymongo.son_manipulator import (AutoReference,
|
||||
NamespaceInjector,
|
||||
SONManipulator,
|
||||
ObjectIdShuffler)
|
||||
from test import client_context, SkipTest, unittest, host, port, IntegrationTest
|
||||
from test import (client_context,
|
||||
SkipTest,
|
||||
unittest,
|
||||
host,
|
||||
port,
|
||||
pair,
|
||||
IntegrationTest)
|
||||
from test.utils import remove_all_users, server_started_with_auth
|
||||
from test.test_client import get_client
|
||||
|
||||
@ -378,7 +384,9 @@ class TestDatabase(IntegrationTest):
|
||||
"user", "password", digestPassword=True)
|
||||
|
||||
self.client.admin.add_user("admin", "password")
|
||||
self.client.admin.authenticate("admin", "password")
|
||||
auth_c = MongoClient(pair)
|
||||
auth_c.admin.authenticate("admin", "password")
|
||||
db = auth_c.pymongo_test
|
||||
|
||||
try:
|
||||
# Add / authenticate / remove
|
||||
@ -420,18 +428,17 @@ class TestDatabase(IntegrationTest):
|
||||
# Cleanup
|
||||
finally:
|
||||
remove_all_users(db)
|
||||
self.client.pymongo_test.logout()
|
||||
self.client.admin.remove_user("admin")
|
||||
self.client.admin.logout()
|
||||
self.client.disconnect()
|
||||
db.logout()
|
||||
auth_c.admin.remove_user("admin")
|
||||
|
||||
@client_context.require_auth
|
||||
def test_make_user_readonly(self):
|
||||
admin = self.client.admin
|
||||
admin.add_user('admin', 'pw')
|
||||
auth_c = MongoClient(pair)
|
||||
admin = auth_c.admin
|
||||
self.client.admin.add_user('admin', 'pw')
|
||||
admin.authenticate('admin', 'pw')
|
||||
|
||||
db = self.client.pymongo_test
|
||||
db = auth_c.pymongo_test
|
||||
|
||||
try:
|
||||
# Make a read-write user.
|
||||
@ -455,16 +462,14 @@ class TestDatabase(IntegrationTest):
|
||||
admin.authenticate('admin', 'pw')
|
||||
remove_all_users(db)
|
||||
admin.remove_user("admin")
|
||||
admin.logout()
|
||||
db.logout()
|
||||
self.client.disconnect()
|
||||
|
||||
@client_context.require_version_min(2, 5, 3, -1)
|
||||
@client_context.require_auth
|
||||
def test_default_roles(self):
|
||||
# "Admin" user
|
||||
db = self.client.admin
|
||||
db.add_user('admin', 'pass')
|
||||
self.client.admin.add_user('admin', 'pass')
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.admin
|
||||
try:
|
||||
db.authenticate('admin', 'pass')
|
||||
info = db.command('usersInfo', 'admin')['users'][0]
|
||||
@ -481,22 +486,24 @@ class TestDatabase(IntegrationTest):
|
||||
# Cleanup
|
||||
finally:
|
||||
db.authenticate('admin', 'pass')
|
||||
remove_all_users(db)
|
||||
db.remove_user('ro-admin')
|
||||
db.remove_user('admin')
|
||||
db.logout()
|
||||
|
||||
db.connection.disconnect()
|
||||
|
||||
# "Non-admin" user
|
||||
db = self.client.pymongo_test
|
||||
db.add_user('user', 'pass')
|
||||
db = auth_c.pymongo_test
|
||||
client_context.client.pymongo_test.add_user('user', 'pass')
|
||||
try:
|
||||
db.authenticate('user', 'pass')
|
||||
info = db.command('usersInfo', 'user')['users'][0]
|
||||
self.assertEqual("dbOwner", info['roles'][0]['role'])
|
||||
db.logout()
|
||||
|
||||
# Read only "Non-admin" user
|
||||
db.add_user('ro-user', 'pass', read_only=True)
|
||||
db.logout()
|
||||
client_context.client.pymongo_test.add_user('ro-user', 'pass',
|
||||
read_only=True)
|
||||
db.authenticate('ro-user', 'pass')
|
||||
info = db.command('usersInfo', 'ro-user')['users'][0]
|
||||
self.assertEqual("read", info['roles'][0]['role'])
|
||||
@ -506,14 +513,15 @@ class TestDatabase(IntegrationTest):
|
||||
finally:
|
||||
db.authenticate('user', 'pass')
|
||||
remove_all_users(db)
|
||||
db.logout()
|
||||
self.client.disconnect()
|
||||
|
||||
@client_context.require_version_min(2, 5, 3, -1)
|
||||
@client_context.require_auth
|
||||
def test_new_user_cmds(self):
|
||||
db = self.client.pymongo_test
|
||||
db.add_user("amalia", "password", roles=["userAdmin"])
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.pymongo_test
|
||||
client_context.client.pymongo_test.add_user("amalia", "password",
|
||||
roles=["userAdmin"])
|
||||
|
||||
db.authenticate("amalia", "password")
|
||||
try:
|
||||
# This tests the ability to update user attributes.
|
||||
@ -527,15 +535,15 @@ class TestDatabase(IntegrationTest):
|
||||
self.assertEqual(amalia_user["customData"], {"secret": "koalas"})
|
||||
finally:
|
||||
db.remove_user("amalia")
|
||||
db.logout()
|
||||
self.client.disconnect()
|
||||
|
||||
@client_context.require_auth
|
||||
def test_authenticate_and_safe(self):
|
||||
db = self.client.auth_test
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.auth_test
|
||||
|
||||
db.add_user("bernie", "password",
|
||||
roles=["userAdmin", "dbAdmin", "readWrite"])
|
||||
client_context.client.auth_test.add_user(
|
||||
"bernie", "password",
|
||||
roles=["userAdmin", "dbAdmin", "readWrite"])
|
||||
db.authenticate("bernie", "password")
|
||||
try:
|
||||
db.test.remove({})
|
||||
@ -552,8 +560,6 @@ class TestDatabase(IntegrationTest):
|
||||
self.assertEqual(0, db.test.count())
|
||||
finally:
|
||||
db.remove_user("bernie")
|
||||
db.logout()
|
||||
self.client.disconnect()
|
||||
|
||||
@client_context.require_auth
|
||||
def test_authenticate_and_request(self):
|
||||
@ -561,37 +567,38 @@ class TestDatabase(IntegrationTest):
|
||||
# always runs in a request, and that it restores the request state
|
||||
# (in or not in a request) properly when it's finished.
|
||||
self.assertFalse(self.client.auto_start_request)
|
||||
db = self.client.pymongo_test
|
||||
db.add_user("mike", "password",
|
||||
roles=["userAdmin", "dbAdmin", "readWrite"])
|
||||
auth_c = MongoClient(pair)
|
||||
db = auth_c.pymongo_test
|
||||
client_context.client.pymongo_test.add_user(
|
||||
"mike", "password",
|
||||
roles=["userAdmin", "dbAdmin", "readWrite"])
|
||||
try:
|
||||
self.assertFalse(self.client.in_request())
|
||||
self.assertFalse(auth_c.in_request())
|
||||
self.assertTrue(db.authenticate("mike", "password"))
|
||||
self.assertFalse(self.client.in_request())
|
||||
self.assertFalse(auth_c.in_request())
|
||||
|
||||
request_cx = get_client(auto_start_request=True)
|
||||
request_cx = get_client(pair, auto_start_request=True)
|
||||
request_db = request_cx.pymongo_test
|
||||
self.assertTrue(request_db.authenticate("mike", "password"))
|
||||
self.assertTrue(request_cx.in_request())
|
||||
finally:
|
||||
db.authenticate("mike", "password")
|
||||
db.remove_user("mike")
|
||||
db.logout()
|
||||
request_db.logout()
|
||||
self.client.disconnect()
|
||||
|
||||
@client_context.require_auth
|
||||
def test_authenticate_multiple(self):
|
||||
# Setup
|
||||
users_db = self.client.pymongo_test
|
||||
admin_db = self.client.admin
|
||||
other_db = self.client.pymongo_test1
|
||||
users_db.test.remove()
|
||||
other_db.test.remove()
|
||||
client_context.client.drop_database("pymongo_test")
|
||||
client_context.client.drop_database("pymongo_test1")
|
||||
auth_c = MongoClient(pair)
|
||||
users_db = auth_c.pymongo_test
|
||||
admin_db = auth_c.admin
|
||||
other_db = auth_c.pymongo_test1
|
||||
|
||||
admin_db.add_user('admin', 'pass',
|
||||
roles=["userAdminAnyDatabase", "dbAdmin",
|
||||
"clusterAdmin", "readWrite"])
|
||||
client_context.client.admin.add_user(
|
||||
'admin', 'pass',
|
||||
roles=["userAdminAnyDatabase", "dbAdmin",
|
||||
"clusterAdmin", "readWrite"])
|
||||
try:
|
||||
self.assertTrue(admin_db.authenticate('admin', 'pass'))
|
||||
|
||||
@ -621,7 +628,7 @@ class TestDatabase(IntegrationTest):
|
||||
other_db.test.insert, {})
|
||||
|
||||
# Force close all sockets
|
||||
self.client.disconnect()
|
||||
auth_c.disconnect()
|
||||
|
||||
# We should still be able to write to the regular user's db
|
||||
self.assertTrue(users_db.test.remove())
|
||||
@ -634,10 +641,8 @@ class TestDatabase(IntegrationTest):
|
||||
# Cleanup
|
||||
finally:
|
||||
remove_all_users(users_db)
|
||||
remove_all_users(admin_db)
|
||||
admin_db.logout()
|
||||
users_db.logout()
|
||||
self.client.disconnect()
|
||||
client_context.client.admin.remove_user('ro-admin')
|
||||
client_context.client.admin.remove_user('admin')
|
||||
|
||||
def test_id_ordering(self):
|
||||
# PyMongo attempts to have _id show up first
|
||||
@ -679,6 +684,7 @@ class TestDatabase(IntegrationTest):
|
||||
db.test.save(obj)
|
||||
self.assertEqual(obj, db.dereference(DBRef("test", 4)))
|
||||
|
||||
@client_context.require_no_auth
|
||||
def test_eval(self):
|
||||
db = self.client.pymongo_test
|
||||
db.test.remove({})
|
||||
@ -843,6 +849,7 @@ class TestDatabase(IntegrationTest):
|
||||
self.assertEqual("buzz", db.users.find_one()["messages"][0]["title"])
|
||||
self.assertEqual("bar", db.users.find_one()["messages"][1]["title"])
|
||||
|
||||
@client_context.require_no_auth
|
||||
def test_system_js(self):
|
||||
db = self.client.pymongo_test
|
||||
db.system.js.remove()
|
||||
|
||||
@ -32,8 +32,13 @@ import gridfs
|
||||
from bson.py3compat import u, StringIO, string_type
|
||||
from gridfs.errors import (FileExists,
|
||||
NoFile)
|
||||
from test import client_context, unittest, host, port, IntegrationTest
|
||||
from test.utils import joinall
|
||||
from test import (client_context,
|
||||
connection_string,
|
||||
unittest,
|
||||
host,
|
||||
port,
|
||||
IntegrationTest)
|
||||
from test.utils import joinall, get_client
|
||||
|
||||
|
||||
class JustWrite(threading.Thread):
|
||||
@ -418,29 +423,30 @@ class TestGridfsReplicaSet(TestReplicaSetClientBase):
|
||||
|
||||
def test_gridfs_secondary(self):
|
||||
primary_host, primary_port = self.primary
|
||||
primary_connection = MongoClient(primary_host, primary_port)
|
||||
primary_connection = get_client(primary_host, primary_port)
|
||||
|
||||
secondary_host, secondary_port = self.secondaries[0]
|
||||
for secondary_connection in [
|
||||
MongoClient(secondary_host, secondary_port,
|
||||
read_preference=ReadPreference.SECONDARY),
|
||||
]:
|
||||
primary_connection.pymongo_test.drop_collection("fs.files")
|
||||
primary_connection.pymongo_test.drop_collection("fs.chunks")
|
||||
secondary_connection = get_client(
|
||||
secondary_host, secondary_port,
|
||||
read_preference=ReadPreference.SECONDARY)
|
||||
|
||||
# Should detect it's connected to secondary and not attempt to
|
||||
# create index
|
||||
fs = gridfs.GridFS(secondary_connection.pymongo_test)
|
||||
primary_connection.pymongo_test.drop_collection("fs.files")
|
||||
primary_connection.pymongo_test.drop_collection("fs.chunks")
|
||||
|
||||
# This won't detect secondary, raises error
|
||||
self.assertRaises(ConnectionFailure, fs.put, b'foo')
|
||||
# Should detect it's connected to secondary and not attempt to
|
||||
# create index
|
||||
fs = gridfs.GridFS(secondary_connection.pymongo_test)
|
||||
|
||||
# This won't detect secondary, raises error
|
||||
self.assertRaises(ConnectionFailure, fs.put, b'foo')
|
||||
|
||||
def test_gridfs_secondary_lazy(self):
|
||||
# Should detect it's connected to secondary and not attempt to
|
||||
# create index.
|
||||
secondary_host, secondary_port = self.secondaries[0]
|
||||
secondary_pair = '%s:%d' % (secondary_host, secondary_port)
|
||||
client = MongoClient(
|
||||
secondary_host, secondary_port,
|
||||
connection_string(seeds=[secondary_pair]),
|
||||
read_preference=ReadPreference.SECONDARY,
|
||||
_connect=False)
|
||||
|
||||
|
||||
@ -29,19 +29,20 @@ def setUpModule():
|
||||
pass
|
||||
|
||||
|
||||
class FindOne(threading.Thread):
|
||||
class SimpleOp(threading.Thread):
|
||||
|
||||
def __init__(self, client):
|
||||
super(FindOne, self).__init__()
|
||||
super(SimpleOp, self).__init__()
|
||||
self.client = client
|
||||
self.passed = False
|
||||
|
||||
def run(self):
|
||||
self.client.db.collection.find_one()
|
||||
self.client.db.command('ismaster')
|
||||
self.passed = True # No exception raised.
|
||||
|
||||
|
||||
def do_find_one(client, nthreads):
|
||||
threads = [FindOne(client) for _ in range(nthreads)]
|
||||
def do_simple_op(client, nthreads):
|
||||
threads = [SimpleOp(client) for _ in range(nthreads)]
|
||||
for t in threads:
|
||||
t.start()
|
||||
|
||||
@ -67,7 +68,7 @@ class TestMongosHA(unittest.TestCase):
|
||||
self.assertEqual(0, len(client.nodes))
|
||||
|
||||
# Trigger initial connection.
|
||||
do_find_one(client, nthreads)
|
||||
do_simple_op(client, nthreads)
|
||||
self.assertEqual(3, len(client.nodes))
|
||||
|
||||
def test_reconnect(self):
|
||||
@ -77,7 +78,7 @@ class TestMongosHA(unittest.TestCase):
|
||||
|
||||
# Trigger reconnect.
|
||||
client.disconnect()
|
||||
do_find_one(client, nthreads)
|
||||
do_simple_op(client, nthreads)
|
||||
self.assertEqual(3, len(client.nodes))
|
||||
|
||||
def test_failover(self):
|
||||
@ -102,12 +103,12 @@ class TestMongosHA(unittest.TestCase):
|
||||
|
||||
def f():
|
||||
try:
|
||||
client.db.collection.find_one()
|
||||
client.db.command('ismaster')
|
||||
except AutoReconnect:
|
||||
errors.append(True)
|
||||
|
||||
# Second attempt succeeds.
|
||||
client.db.collection.find_one()
|
||||
client.db.command('ismaster')
|
||||
|
||||
passed.append(True)
|
||||
|
||||
|
||||
@ -345,7 +345,7 @@ class _TestPoolingBase(object):
|
||||
def get_client(self, *args, **kwargs):
|
||||
opts = kwargs.copy()
|
||||
opts['use_greenlets'] = self.use_greenlets
|
||||
return get_client(*args, **opts)
|
||||
return get_client(host, port, *args, **opts)
|
||||
|
||||
def get_pool(self, pair, *args, **kwargs):
|
||||
kwargs['use_greenlets'] = self.use_greenlets
|
||||
@ -1156,6 +1156,7 @@ class _TestPoolSocketSharing(_TestPoolingBase):
|
||||
gr0: get results
|
||||
"""
|
||||
cx = get_client(
|
||||
host, port,
|
||||
use_greenlets=self.use_greenlets,
|
||||
auto_start_request=False
|
||||
)
|
||||
@ -1189,16 +1190,7 @@ class _TestPoolSocketSharing(_TestPoolingBase):
|
||||
|
||||
# Javascript function that pauses N seconds per document
|
||||
fn = delay(10)
|
||||
if (is_mongos(db.connection) or not
|
||||
Version.from_client(db.connection).at_least(1, 7, 2)):
|
||||
# mongos doesn't support eval so we have to use $where
|
||||
# which is less reliable in this context.
|
||||
self.assertEqual(1, db.test.find({"$where": fn}).count())
|
||||
else:
|
||||
# 'nolock' allows find_fast to start and finish while we're
|
||||
# waiting for this to complete.
|
||||
self.assertEqual({'ok': 1.0, 'retval': True},
|
||||
db.command('eval', fn, nolock=True))
|
||||
self.assertEqual(1, db.test.find({"$where": fn}).count())
|
||||
|
||||
history.append('find_slow done')
|
||||
|
||||
|
||||
@ -38,7 +38,9 @@ from test import (client_context,
|
||||
SkipTest,
|
||||
unittest,
|
||||
utils,
|
||||
IntegrationTest)
|
||||
IntegrationTest,
|
||||
db_user,
|
||||
db_pwd)
|
||||
from test.version import Version
|
||||
|
||||
|
||||
@ -212,6 +214,8 @@ class TestCommandAndReadPreference(TestReplicaSetClientBase):
|
||||
# Effectively ignore members' ping times so we can test the effect
|
||||
# of ReadPreference modes only
|
||||
latencyThresholdMS=1000*1000)
|
||||
if client_context.auth_enabled:
|
||||
self.c.admin.authenticate(db_user, db_pwd)
|
||||
self.client_version = Version.from_client(self.c)
|
||||
|
||||
def tearDown(self):
|
||||
@ -516,7 +520,7 @@ class TestMovingAverage(unittest.TestCase):
|
||||
class TestMongosConnection(IntegrationTest):
|
||||
|
||||
def test_mongos_connection(self):
|
||||
c = get_client()
|
||||
c = get_client(host, port)
|
||||
is_mongos = utils.is_mongos(c)
|
||||
|
||||
# Test default mode, PRIMARY
|
||||
@ -547,7 +551,8 @@ class TestMongosConnection(IntegrationTest):
|
||||
None, [{}]
|
||||
):
|
||||
# Create a client e.g. with read_preference=NEAREST
|
||||
c = get_client(read_preference=mode(tag_sets=tag_sets))
|
||||
c = get_client(host, port,
|
||||
read_preference=mode(tag_sets=tag_sets))
|
||||
|
||||
self.assertEqual(is_mongos, c.is_mongos)
|
||||
cursor = c.pymongo_test.test.find()
|
||||
@ -586,7 +591,8 @@ class TestMongosConnection(IntegrationTest):
|
||||
[{'dc': 'la'}, {'dc': 'sf'}],
|
||||
[{'dc': 'la'}, {'dc': 'sf'}, {}],
|
||||
):
|
||||
c = get_client(read_preference=mode(tag_sets=tag_sets))
|
||||
c = get_client(host, port,
|
||||
read_preference=mode(tag_sets=tag_sets))
|
||||
|
||||
self.assertEqual(is_mongos, c.is_mongos)
|
||||
cursor = c.pymongo_test.test.find()
|
||||
@ -599,7 +605,7 @@ class TestMongosConnection(IntegrationTest):
|
||||
'$readPreference' in cursor._Cursor__query_spec())
|
||||
|
||||
def test_only_secondary_ok_commands_have_read_prefs(self):
|
||||
c = get_client(read_preference=ReadPreference.SECONDARY)
|
||||
c = get_client(host, port, read_preference=ReadPreference.SECONDARY)
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
|
||||
@ -39,13 +39,18 @@ from pymongo.errors import (AutoReconnect,
|
||||
ConnectionFailure,
|
||||
InvalidName,
|
||||
OperationFailure, InvalidOperation)
|
||||
from test import client_context, pair, port, SkipTest, unittest
|
||||
from test import (client_context,
|
||||
connection_string,
|
||||
pair,
|
||||
port,
|
||||
SkipTest,
|
||||
unittest)
|
||||
from test.pymongo_mocks import MockReplicaSetClient
|
||||
from test.utils import (
|
||||
delay, assertReadFrom, assertReadFromAll, read_from_which_host,
|
||||
remove_all_users, assertRaisesExactly, TestRequestMixin, one,
|
||||
server_started_with_auth, pools_from_rs_client, get_pool,
|
||||
_TestLazyConnectMixin)
|
||||
get_rs_client, _TestLazyConnectMixin)
|
||||
from test.version import Version
|
||||
|
||||
|
||||
@ -90,9 +95,8 @@ class TestReplicaSetClientBase(unittest.TestCase):
|
||||
]
|
||||
|
||||
def _get_client(self, **kwargs):
|
||||
return MongoReplicaSetClient(pair,
|
||||
replicaSet=self.name,
|
||||
**kwargs)
|
||||
return get_rs_client(connection_string(),
|
||||
replicaSet=self.name, **kwargs)
|
||||
|
||||
|
||||
class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
@ -168,11 +172,9 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
@client_context.require_auth
|
||||
def test_init_disconnected_with_auth(self):
|
||||
c = client_context.rs_client
|
||||
|
||||
c.admin.add_user("admin", "pass")
|
||||
c.admin.authenticate("admin", "pass")
|
||||
try:
|
||||
c.pymongo_test.add_user("user", "pass", roles=['readWrite', 'userAdmin'])
|
||||
c.pymongo_test.add_user("user", "pass",
|
||||
roles=['readWrite', 'userAdmin'])
|
||||
|
||||
# Auth with lazy connection.
|
||||
host = one(self.hosts)
|
||||
@ -193,9 +195,6 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
finally:
|
||||
# Clean up.
|
||||
remove_all_users(c.pymongo_test)
|
||||
remove_all_users(c.admin)
|
||||
c.admin.logout()
|
||||
c.disconnect()
|
||||
|
||||
def test_connect(self):
|
||||
assertRaisesExactly(ConnectionFailure, MongoReplicaSetClient,
|
||||
@ -418,7 +417,8 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"])
|
||||
|
||||
self.assertFalse(c.in_request())
|
||||
c.copy_database("pymongo_test", "pymongo_test2", pair)
|
||||
|
||||
c.copy_database("pymongo_test", "pymongo_test2")
|
||||
# copy_database() didn't accidentally restart the request
|
||||
self.assertFalse(c.in_request())
|
||||
|
||||
@ -431,8 +431,6 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
server_started_with_auth(c)):
|
||||
c.drop_database("pymongo_test1")
|
||||
|
||||
c.admin.add_user("admin", "password")
|
||||
c.admin.authenticate("admin", "password")
|
||||
try:
|
||||
c.pymongo_test.add_user("mike", "password")
|
||||
|
||||
@ -455,10 +453,6 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
finally:
|
||||
# Cleanup
|
||||
remove_all_users(c.pymongo_test)
|
||||
c.admin.remove_user("admin")
|
||||
c.admin.logout()
|
||||
c.pymongo_test.logout()
|
||||
c.disconnect()
|
||||
|
||||
def test_get_default_database(self):
|
||||
host = one(self.hosts)
|
||||
@ -1090,7 +1084,7 @@ class TestReplicaSetWireVersion(unittest.TestCase):
|
||||
c.set_wire_version_range('a:1', 1, 5)
|
||||
c.set_wire_version_range('b:2', 0, 1)
|
||||
c.set_wire_version_range('c:3', 1, 2)
|
||||
c.db.collection.find_one() # Connect.
|
||||
c.db.command('ismaster') # Connect.
|
||||
self.assertEqual(c.min_wire_version, 1)
|
||||
self.assertEqual(c.max_wire_version, 5)
|
||||
|
||||
@ -1113,9 +1107,13 @@ class TestReplicaSetClientLazyConnect(
|
||||
TestReplicaSetClientBase,
|
||||
_TestLazyConnectMixin):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
TestReplicaSetClientBase.setUpClass()
|
||||
|
||||
def test_read_mode_secondary(self):
|
||||
client = MongoReplicaSetClient(
|
||||
pair, replicaSet=self.name, _connect=False,
|
||||
connection_string(), replicaSet=self.name, _connect=False,
|
||||
read_preference=ReadPreference.SECONDARY)
|
||||
|
||||
# No error.
|
||||
@ -1128,18 +1126,27 @@ class TestReplicaSetClientLazyConnectGevent(
|
||||
_TestLazyConnectMixin):
|
||||
use_greenlets = True
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
TestReplicaSetClientBase.setUpClass()
|
||||
|
||||
|
||||
class TestReplicaSetClientLazyConnectBadSeeds(
|
||||
TestReplicaSetClientBase,
|
||||
_TestLazyConnectMixin):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
TestReplicaSetClientBase.setUpClass()
|
||||
|
||||
def _get_client(self, **kwargs):
|
||||
kwargs.setdefault('connectTimeoutMS', 500)
|
||||
|
||||
# Assume there are no open mongods listening on a.com, b.com, ....
|
||||
bad_seeds = ['%s.com' % chr(ord('a') + i) for i in range(5)]
|
||||
seeds = ','.join(bad_seeds + [pair])
|
||||
client = MongoReplicaSetClient(seeds, replicaSet=self.name, **kwargs)
|
||||
client = MongoReplicaSetClient(
|
||||
connection_string(seeds=(bad_seeds + [pair])),
|
||||
replicaSet=self.name, **kwargs)
|
||||
|
||||
# In case of a slow test machine.
|
||||
client._refresh_timeout_sec = 30
|
||||
@ -1180,7 +1187,7 @@ class TestReplicaSetClientMaxWriteBatchSize(unittest.TestCase):
|
||||
|
||||
# Starts with default max batch size.
|
||||
self.assertEqual(1000, c.max_write_batch_size)
|
||||
c.db.collection.find_one() # Connect.
|
||||
c.db.command('ismaster') # Connect.
|
||||
|
||||
# Uses primary's max batch size.
|
||||
self.assertEqual(c.max_write_batch_size, 1)
|
||||
|
||||
@ -57,7 +57,7 @@ class TestSecondaryBecomesStandalone(unittest.TestCase):
|
||||
c.disconnect()
|
||||
|
||||
try:
|
||||
c.db.collection.find_one()
|
||||
c.db.command('ismaster')
|
||||
except ConfigurationError as e:
|
||||
self.assertTrue('not a member of replica set' in str(e))
|
||||
else:
|
||||
@ -147,7 +147,7 @@ class TestSecondaryAdded(unittest.TestCase):
|
||||
c.mock_ismaster_hosts.append('c:3')
|
||||
|
||||
c.disconnect()
|
||||
c.db.collection.find_one()
|
||||
c.db.command('ismaster')
|
||||
|
||||
self.assertEqual('a', c.host)
|
||||
self.assertEqual(1, c.port)
|
||||
|
||||
@ -17,9 +17,8 @@
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
from test import SkipTest, unittest, client_context
|
||||
from test.utils import (joinall, remove_all_users,
|
||||
server_started_with_auth, RendezvousThread)
|
||||
from test import unittest, client_context, pair
|
||||
from test.utils import joinall, remove_all_users, RendezvousThread
|
||||
from test.test_client import get_client
|
||||
from test.utils import get_pool
|
||||
from pymongo.pool import SocketInfo, _closed
|
||||
@ -185,7 +184,7 @@ class BaseTestThreads(object):
|
||||
test_threads_replica_set_connection.py.
|
||||
"""
|
||||
# Regular test client
|
||||
return get_client()
|
||||
return get_client(pair)
|
||||
|
||||
def test_threading(self):
|
||||
self.db.drop_collection("test")
|
||||
@ -253,7 +252,7 @@ class BaseTestThreads(object):
|
||||
#
|
||||
# If we've fixed PYTHON-345, then only one AutoReconnect is raised,
|
||||
# and all the threads get new request sockets.
|
||||
cx = get_client(auto_start_request=True)
|
||||
cx = get_client(pair, auto_start_request=True)
|
||||
collection = cx.db.pymongo_test
|
||||
|
||||
# acquire a request socket for the main thread
|
||||
@ -310,6 +309,11 @@ class BaseTestThreadsAuth(object):
|
||||
unittest imports this module, and once when unittest imports
|
||||
test_threads_replica_set_connection.py, which imports this module.)
|
||||
"""
|
||||
@classmethod
|
||||
@client_context.require_auth
|
||||
def setUpClass(cls):
|
||||
pass
|
||||
|
||||
def _get_client(self):
|
||||
"""
|
||||
Intended for overriding in TestThreadsAuthReplicaSet. This method
|
||||
@ -317,18 +321,19 @@ class BaseTestThreadsAuth(object):
|
||||
test_threads_replica_set_connection.py.
|
||||
"""
|
||||
# Regular test client
|
||||
return get_client()
|
||||
return get_client(pair)
|
||||
|
||||
def setUp(self):
|
||||
client = self._get_client()
|
||||
if not server_started_with_auth(client):
|
||||
raise SkipTest("Authentication is not enabled on server")
|
||||
self.client = client
|
||||
self.client.admin.add_user('admin-user', 'password',
|
||||
roles=['clusterAdmin',
|
||||
'dbAdminAnyDatabase',
|
||||
'readWriteAnyDatabase',
|
||||
'userAdminAnyDatabase'])
|
||||
# client returned from self._get_client() may already be authenticated
|
||||
# to get around restricted localhost exception in MongoDB >= 2.7.1.
|
||||
self.client.admin.logout()
|
||||
self.client.admin.authenticate("admin-user", "password")
|
||||
self.client.auth_test.add_user("test-user", "password",
|
||||
roles=['readWrite'])
|
||||
@ -338,17 +343,20 @@ class BaseTestThreadsAuth(object):
|
||||
self.client.admin.authenticate("admin-user", "password")
|
||||
remove_all_users(self.client.auth_test)
|
||||
self.client.drop_database('auth_test')
|
||||
remove_all_users(self.client.admin)
|
||||
self.client.admin.remove_user('admin-user')
|
||||
self.client.admin.logout()
|
||||
# Clear client reference so that RSC's monitor thread
|
||||
# dies.
|
||||
self.client = None
|
||||
|
||||
def test_auto_auth_login(self):
|
||||
client = self._get_client()
|
||||
client.admin.logout()
|
||||
self.assertRaises(OperationFailure, client.auth_test.test.find_one)
|
||||
|
||||
# Admin auth
|
||||
client = self._get_client()
|
||||
client.admin.logout()
|
||||
client.admin.authenticate("admin-user", "password")
|
||||
|
||||
nthreads = 10
|
||||
@ -365,6 +373,7 @@ class BaseTestThreadsAuth(object):
|
||||
|
||||
# Database-specific auth
|
||||
client = self._get_client()
|
||||
client.admin.logout()
|
||||
client.auth_test.authenticate("test-user", "password")
|
||||
|
||||
threads = []
|
||||
|
||||
@ -14,11 +14,10 @@
|
||||
|
||||
"""Test that pymongo is thread safe."""
|
||||
|
||||
from pymongo.mongo_replica_set_client import MongoReplicaSetClient
|
||||
|
||||
from test import unittest
|
||||
from test.test_threads import BaseTestThreads, BaseTestThreadsAuth
|
||||
from test.test_replica_set_client import TestReplicaSetClientBase, pair
|
||||
from test.utils import get_rs_client
|
||||
|
||||
|
||||
class TestThreadsReplicaSet(TestReplicaSetClientBase, BaseTestThreads):
|
||||
@ -40,6 +39,15 @@ class TestThreadsReplicaSet(TestReplicaSetClientBase, BaseTestThreads):
|
||||
|
||||
class TestThreadsAuthReplicaSet(TestReplicaSetClientBase, BaseTestThreadsAuth):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
TestReplicaSetClientBase.setUpClass()
|
||||
BaseTestThreadsAuth.setUpClass()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
TestReplicaSetClientBase.tearDownClass()
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Prepare to test all the same things that TestThreads tests, but do it
|
||||
@ -57,7 +65,7 @@ class TestThreadsAuthReplicaSet(TestReplicaSetClientBase, BaseTestThreadsAuth):
|
||||
Override TestThreadsAuth, so its tests run on a MongoReplicaSetClient
|
||||
instead of a regular MongoClient.
|
||||
"""
|
||||
return MongoReplicaSetClient(pair, replicaSet=self.name)
|
||||
return get_rs_client(pair, replicaSet=self.name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -23,7 +23,10 @@ import threading
|
||||
from pymongo import MongoClient, MongoReplicaSetClient
|
||||
from pymongo.errors import AutoReconnect
|
||||
from pymongo.pool import NO_REQUEST, NO_SOCKET_YET, SocketInfo
|
||||
from test import host, port, SkipTest
|
||||
from test import (SkipTest,
|
||||
client_context,
|
||||
db_user,
|
||||
db_pwd)
|
||||
from test.version import Version
|
||||
|
||||
|
||||
@ -34,6 +37,20 @@ except ImportError:
|
||||
has_gevent = False
|
||||
|
||||
|
||||
def get_client(*args, **kwargs):
|
||||
client = MongoClient(*args, **kwargs)
|
||||
if client_context.auth_enabled and kwargs.get("_connect", True):
|
||||
client.admin.authenticate(db_user, db_pwd)
|
||||
return client
|
||||
|
||||
|
||||
def get_rs_client(*args, **kwargs):
|
||||
client = MongoReplicaSetClient(*args, **kwargs)
|
||||
if client_context.auth_enabled and kwargs.get("_connect", True):
|
||||
client.admin.authenticate(db_user, db_pwd)
|
||||
return client
|
||||
|
||||
|
||||
# No functools in Python 2.4
|
||||
def my_partial(f, *args, **kwargs):
|
||||
def _f(*new_args, **new_kwargs):
|
||||
@ -126,9 +143,10 @@ def drop_collections(db):
|
||||
|
||||
def remove_all_users(db):
|
||||
if Version.from_client(db.connection).at_least(2, 5, 3, -1):
|
||||
db.command({"dropAllUsersFromDatabase": 1})
|
||||
db.command({"dropAllUsersFromDatabase": 1,
|
||||
"writeConcern": {"w": "majority"}})
|
||||
else:
|
||||
db.system.users.remove({})
|
||||
db.system.users.remove({}, w="majority")
|
||||
|
||||
|
||||
def joinall(threads):
|
||||
@ -147,8 +165,10 @@ def enable_text_search(client):
|
||||
|
||||
if isinstance(client, MongoReplicaSetClient):
|
||||
for host, port in client.secondaries:
|
||||
MongoClient(host, port).admin.command(
|
||||
'setParameter', textSearchEnabled=True)
|
||||
client = MongoClient(host, port)
|
||||
if client_context.auth_enabled:
|
||||
client.admin.authenticate(db_user, db_pwd)
|
||||
client.admin.command('setParameter', textSearchEnabled=True)
|
||||
|
||||
def assertRaisesExactly(cls, fn, *args, **kwargs):
|
||||
"""
|
||||
@ -448,7 +468,7 @@ def lazy_client_trial(reset, target, test, get_client, use_greenlets):
|
||||
if use_greenlets and not has_gevent:
|
||||
raise SkipTest('Gevent not installed')
|
||||
|
||||
collection = MongoClient(host, port).pymongo_test.test
|
||||
collection = client_context.client.pymongo_test.test
|
||||
|
||||
# Make concurrency bugs more likely to manifest.
|
||||
interval = None
|
||||
@ -463,8 +483,8 @@ def lazy_client_trial(reset, target, test, get_client, use_greenlets):
|
||||
try:
|
||||
for i in range(NTRIALS):
|
||||
reset(collection)
|
||||
lazy_client = get_client(
|
||||
_connect=False, use_greenlets=use_greenlets)
|
||||
lazy_client = get_client(_connect=False,
|
||||
use_greenlets=use_greenlets)
|
||||
|
||||
lazy_collection = lazy_client.pymongo_test.test
|
||||
run_threads(lazy_collection, target, use_greenlets)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user