PYTHON-691 - Fix UserWarning command issues.
Don't raise UserWarning for helpers and internal calls to commands that do not obey read preference.
This commit is contained in:
parent
d703ebb832
commit
9d47f1cd3d
@ -30,6 +30,7 @@ from pymongo import ASCENDING
|
||||
from pymongo.collection import Collection
|
||||
from pymongo.cursor import Cursor
|
||||
from pymongo.errors import DuplicateKeyError
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
|
||||
try:
|
||||
_SEEK_SET = os.SEEK_SET
|
||||
@ -258,7 +259,8 @@ class GridIn(object):
|
||||
db.error()
|
||||
|
||||
md5 = db.command(
|
||||
"filemd5", self._id, root=self._coll.name)["md5"]
|
||||
"filemd5", self._id, root=self._coll.name,
|
||||
read_preference=ReadPreference.PRIMARY)["md5"]
|
||||
|
||||
self._file["md5"] = md5
|
||||
self._file["length"] = self._position
|
||||
|
||||
@ -28,6 +28,7 @@ from pymongo.cursor import Cursor
|
||||
from pymongo.errors import InvalidName, OperationFailure
|
||||
from pymongo.helpers import _check_write_command_response
|
||||
from pymongo.message import _INSERT, _UPDATE, _DELETE
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
|
||||
|
||||
try:
|
||||
@ -125,9 +126,12 @@ class Collection(common.BaseObject):
|
||||
if options:
|
||||
if "size" in options:
|
||||
options["size"] = float(options["size"])
|
||||
self.__database.command("create", self.__name, **options)
|
||||
self.__database.command("create", self.__name,
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
**options)
|
||||
else:
|
||||
self.__database.command("create", self.__name)
|
||||
self.__database.command("create", self.__name,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""Get a sub-collection of this collection by name.
|
||||
@ -1037,7 +1041,9 @@ class Collection(common.BaseObject):
|
||||
index.update(kwargs)
|
||||
|
||||
try:
|
||||
self.__database.command('createIndexes', self.name, indexes=[index])
|
||||
self.__database.command('createIndexes', self.name,
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
indexes=[index])
|
||||
except OperationFailure, exc:
|
||||
if exc.code in (59, None):
|
||||
index["ns"] = self.__full_name
|
||||
@ -1183,7 +1189,9 @@ class Collection(common.BaseObject):
|
||||
|
||||
self.__database.connection._purge_index(self.__database.name,
|
||||
self.__name, name)
|
||||
self.__database.command("dropIndexes", self.__name, index=name,
|
||||
self.__database.command("dropIndexes", self.__name,
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
index=name,
|
||||
allowable_errors=["ns not found"])
|
||||
|
||||
def reindex(self):
|
||||
@ -1195,7 +1203,8 @@ class Collection(common.BaseObject):
|
||||
|
||||
.. versionadded:: 1.11+
|
||||
"""
|
||||
return self.__database.command("reIndex", self.__name)
|
||||
return self.__database.command("reIndex", self.__name,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def index_information(self):
|
||||
"""Get information on this collection's indexes.
|
||||
@ -1416,9 +1425,10 @@ class Collection(common.BaseObject):
|
||||
raise InvalidName("collection names must not contain '$'")
|
||||
|
||||
new_name = "%s.%s" % (self.__database.name, new_name)
|
||||
self.__database.connection.admin.command("renameCollection",
|
||||
self.__full_name,
|
||||
to=new_name, **kwargs)
|
||||
client = self.__database.connection
|
||||
client.admin.command("renameCollection", self.__full_name,
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
to=new_name, **kwargs)
|
||||
|
||||
def distinct(self, key):
|
||||
"""Get a list of distinct values for `key` among all documents
|
||||
@ -1645,6 +1655,7 @@ class Collection(common.BaseObject):
|
||||
|
||||
out = self.__database.command("findAndModify", self.__name,
|
||||
allowable_errors=[no_obj_error],
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
uuid_subtype=self.uuid_subtype,
|
||||
**kwargs)
|
||||
|
||||
|
||||
@ -26,7 +26,9 @@ from pymongo.errors import (CollectionInvalid,
|
||||
ConfigurationError,
|
||||
InvalidName,
|
||||
OperationFailure)
|
||||
from pymongo import read_preferences as rp
|
||||
from pymongo.read_preferences import (modes,
|
||||
secondary_ok_commands,
|
||||
ReadPreference)
|
||||
|
||||
|
||||
def _check_name(name):
|
||||
@ -282,7 +284,7 @@ class Database(common.BaseObject):
|
||||
|
||||
command_name = command.keys()[0].lower()
|
||||
must_use_master = kwargs.pop('_use_master', False)
|
||||
if command_name not in rp.secondary_ok_commands:
|
||||
if command_name not in secondary_ok_commands:
|
||||
must_use_master = True
|
||||
|
||||
# Special-case: mapreduce can go to secondaries only if inline
|
||||
@ -323,13 +325,13 @@ class Database(common.BaseObject):
|
||||
command.update(kwargs)
|
||||
|
||||
# Warn if must_use_master will override read_preference.
|
||||
if (extra_opts['read_preference'] != rp.ReadPreference.PRIMARY and
|
||||
if (extra_opts['read_preference'] != ReadPreference.PRIMARY and
|
||||
extra_opts['_must_use_master']):
|
||||
warnings.warn("%s does not support %s read preference "
|
||||
"and will be routed to the primary instead." %
|
||||
(command_name,
|
||||
rp.modes[extra_opts['read_preference']]),
|
||||
UserWarning)
|
||||
modes[extra_opts['read_preference']]),
|
||||
UserWarning, stacklevel=3)
|
||||
|
||||
cursor = self["$cmd"].find(command, **extra_opts).limit(-1)
|
||||
for doc in cursor:
|
||||
@ -466,7 +468,8 @@ class Database(common.BaseObject):
|
||||
|
||||
self.__connection._purge_index(self.__name, name)
|
||||
|
||||
self.command("drop", unicode(name), allowable_errors=["ns not found"])
|
||||
self.command("drop", unicode(name), allowable_errors=["ns not found"],
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def validate_collection(self, name_or_collection,
|
||||
scandata=False, full=False):
|
||||
@ -504,7 +507,8 @@ class Database(common.BaseObject):
|
||||
"%s or Collection" % (basestring.__name__,))
|
||||
|
||||
result = self.command("validate", unicode(name),
|
||||
scandata=scandata, full=full)
|
||||
scandata=scandata, full=full,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
valid = True
|
||||
# Pre 1.9 results
|
||||
@ -553,7 +557,8 @@ class Database(common.BaseObject):
|
||||
|
||||
.. mongodoc:: profiling
|
||||
"""
|
||||
result = self.command("profile", -1)
|
||||
result = self.command("profile", -1,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
assert result["was"] >= 0 and result["was"] <= 2
|
||||
return result["was"]
|
||||
@ -593,9 +598,11 @@ class Database(common.BaseObject):
|
||||
raise TypeError("slow_ms must be an integer")
|
||||
|
||||
if slow_ms is not None:
|
||||
self.command("profile", level, slowms=slow_ms)
|
||||
self.command("profile", level, slowms=slow_ms,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
else:
|
||||
self.command("profile", level)
|
||||
self.command("profile", level,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def profiling_info(self):
|
||||
"""Returns a list containing current profiling information.
|
||||
@ -610,7 +617,8 @@ class Database(common.BaseObject):
|
||||
Return None if the last operation was error-free. Otherwise return the
|
||||
error that occurred.
|
||||
"""
|
||||
error = self.command("getlasterror")
|
||||
error = self.command("getlasterror",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
error_msg = error.get("err", "")
|
||||
if error_msg is None:
|
||||
return None
|
||||
@ -623,7 +631,8 @@ class Database(common.BaseObject):
|
||||
|
||||
Returns a SON object with status information.
|
||||
"""
|
||||
return self.command("getlasterror")
|
||||
return self.command("getlasterror",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def previous_error(self):
|
||||
"""Get the most recent error to have occurred on this database.
|
||||
@ -632,7 +641,8 @@ class Database(common.BaseObject):
|
||||
`Database.reset_error_history`. Returns None if no such errors have
|
||||
occurred.
|
||||
"""
|
||||
error = self.command("getpreverror")
|
||||
error = self.command("getpreverror",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
if error.get("err", 0) is None:
|
||||
return None
|
||||
return error
|
||||
@ -643,7 +653,8 @@ class Database(common.BaseObject):
|
||||
Calls to `Database.previous_error` will only return errors that have
|
||||
occurred since the most recent call to this method.
|
||||
"""
|
||||
self.command("reseterror")
|
||||
self.command("reseterror",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
@ -697,7 +708,8 @@ class Database(common.BaseObject):
|
||||
else:
|
||||
command_name = "updateUser"
|
||||
|
||||
self.command(command_name, name, **opts)
|
||||
self.command(command_name, name,
|
||||
read_preference=ReadPreference.PRIMARY, **opts)
|
||||
|
||||
def _legacy_add_user(self, name, password, read_only, **kwargs):
|
||||
"""Uses v1 system to add users, i.e. saving to system.users.
|
||||
@ -763,7 +775,8 @@ class Database(common.BaseObject):
|
||||
"read_only and roles together")
|
||||
|
||||
try:
|
||||
uinfo = self.command("usersInfo", name)
|
||||
uinfo = self.command("usersInfo", name,
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
except OperationFailure, exc:
|
||||
# MongoDB >= 2.5.3 requires the use of commands to manage
|
||||
# users. "No such command" error didn't return an error
|
||||
@ -793,6 +806,7 @@ class Database(common.BaseObject):
|
||||
|
||||
try:
|
||||
self.command("dropUser", name,
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
writeConcern=self._get_wc_override())
|
||||
except OperationFailure, exc:
|
||||
# See comment in add_user try / except above.
|
||||
@ -930,7 +944,9 @@ class Database(common.BaseObject):
|
||||
if not isinstance(code, Code):
|
||||
code = Code(code)
|
||||
|
||||
result = self.command("$eval", code, args=args)
|
||||
result = self.command("$eval", code,
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
args=args)
|
||||
return result.get("retval", None)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
|
||||
@ -61,6 +61,9 @@ from pymongo.errors import (AutoReconnect,
|
||||
InvalidURI,
|
||||
OperationFailure)
|
||||
from pymongo.member import Member
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
|
||||
|
||||
EMPTY = b("")
|
||||
|
||||
|
||||
@ -1337,13 +1340,15 @@ class MongoClient(common.BaseObject):
|
||||
def server_info(self):
|
||||
"""Get information about the MongoDB server we're connected to.
|
||||
"""
|
||||
return self.admin.command("buildinfo")
|
||||
return self.admin.command("buildinfo",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def database_names(self):
|
||||
"""Get a list of the names of all databases on the connected server.
|
||||
"""
|
||||
return [db["name"] for db in
|
||||
self.admin.command("listDatabases")["databases"]]
|
||||
self.admin.command("listDatabases",
|
||||
read_preference=ReadPreference.PRIMARY)["databases"]]
|
||||
|
||||
def drop_database(self, name_or_database):
|
||||
"""Drop a database.
|
||||
@ -1365,7 +1370,8 @@ class MongoClient(common.BaseObject):
|
||||
"%s or Database" % (basestring.__name__,))
|
||||
|
||||
self._purge_index(name)
|
||||
self[name].command("dropDatabase")
|
||||
self[name].command("dropDatabase",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def copy_database(self, from_name, to_name,
|
||||
from_host=None, username=None, password=None):
|
||||
@ -1413,12 +1419,15 @@ class MongoClient(common.BaseObject):
|
||||
|
||||
if username is not None:
|
||||
nonce = self.admin.command("copydbgetnonce",
|
||||
fromhost=from_host)["nonce"]
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
fromhost=from_host)["nonce"]
|
||||
command["username"] = username
|
||||
command["nonce"] = nonce
|
||||
command["key"] = auth._auth_key(nonce, username, password)
|
||||
|
||||
return self.admin.command("copydb", **command)
|
||||
return self.admin.command("copydb",
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
**command)
|
||||
finally:
|
||||
self.end_request()
|
||||
|
||||
@ -1467,7 +1476,8 @@ class MongoClient(common.BaseObject):
|
||||
|
||||
.. versionadded:: 2.0
|
||||
"""
|
||||
self.admin.command("fsync", **kwargs)
|
||||
self.admin.command("fsync",
|
||||
read_preference=ReadPreference.PRIMARY, **kwargs)
|
||||
|
||||
def unlock(self):
|
||||
"""Unlock a previously locked server.
|
||||
|
||||
@ -59,6 +59,7 @@ from pymongo.errors import (AutoReconnect,
|
||||
DuplicateKeyError,
|
||||
OperationFailure,
|
||||
InvalidOperation)
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from pymongo.thread_util import DummyLock
|
||||
|
||||
EMPTY = b("")
|
||||
@ -1832,13 +1833,15 @@ class MongoReplicaSetClient(common.BaseObject):
|
||||
def server_info(self):
|
||||
"""Get information about the MongoDB primary we're connected to.
|
||||
"""
|
||||
return self.admin.command("buildinfo")
|
||||
return self.admin.command("buildinfo",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def database_names(self):
|
||||
"""Get a list of the names of all databases on the connected server.
|
||||
"""
|
||||
return [db["name"] for db in
|
||||
self.admin.command("listDatabases")["databases"]]
|
||||
self.admin.command("listDatabases",
|
||||
read_preference=ReadPreference.PRIMARY)["databases"]]
|
||||
|
||||
def drop_database(self, name_or_database):
|
||||
"""Drop a database.
|
||||
@ -1860,7 +1863,8 @@ class MongoReplicaSetClient(common.BaseObject):
|
||||
"%s or Database" % (basestring.__name__,))
|
||||
|
||||
self._purge_index(name)
|
||||
self[name].command("dropDatabase")
|
||||
self[name].command("dropDatabase",
|
||||
read_preference=ReadPreference.PRIMARY)
|
||||
|
||||
def copy_database(self, from_name, to_name,
|
||||
from_host=None, username=None, password=None):
|
||||
@ -1906,12 +1910,15 @@ class MongoReplicaSetClient(common.BaseObject):
|
||||
|
||||
if username is not None:
|
||||
nonce = self.admin.command("copydbgetnonce",
|
||||
fromhost=from_host)["nonce"]
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
fromhost=from_host)["nonce"]
|
||||
command["username"] = username
|
||||
command["nonce"] = nonce
|
||||
command["key"] = auth._auth_key(nonce, username, password)
|
||||
|
||||
return self.admin.command("copydb", **command)
|
||||
return self.admin.command("copydb",
|
||||
read_preference=ReadPreference.PRIMARY,
|
||||
**command)
|
||||
finally:
|
||||
self.end_request()
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import sys
|
||||
import time
|
||||
import thread
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
@ -43,6 +44,7 @@ from pymongo.errors import (AutoReconnect,
|
||||
from test import version, host, port, pair
|
||||
from test.pymongo_mocks import MockClient
|
||||
from test.utils import (assertRaisesExactly,
|
||||
catch_warnings,
|
||||
delay,
|
||||
is_mongos,
|
||||
remove_all_users,
|
||||
@ -315,11 +317,16 @@ class TestClient(unittest.TestCase, TestRequestMixin):
|
||||
def test_from_uri(self):
|
||||
c = MongoClient(host, port)
|
||||
|
||||
self.assertEqual(c, MongoClient("mongodb://%s:%d" % (host, port)))
|
||||
self.assertTrue(MongoClient(
|
||||
"mongodb://%s:%d" % (host, port), slave_okay=True).slave_okay)
|
||||
self.assertTrue(MongoClient(
|
||||
"mongodb://%s:%d/?slaveok=true;w=2" % (host, port)).slave_okay)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
self.assertEqual(c, MongoClient("mongodb://%s:%d" % (host, port)))
|
||||
self.assertTrue(MongoClient(
|
||||
"mongodb://%s:%d" % (host, port), slave_okay=True).slave_okay)
|
||||
self.assertTrue(MongoClient(
|
||||
"mongodb://%s:%d/?slaveok=true;w=2" % (host, port)).slave_okay)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_get_default_database(self):
|
||||
c = MongoClient("mongodb://%s:%d/foo" % (host, port), _connect=False)
|
||||
|
||||
@ -51,8 +51,8 @@ from pymongo.errors import (DocumentTooLarge,
|
||||
OperationFailure,
|
||||
WTimeoutError)
|
||||
from test.test_client import get_client
|
||||
from test.utils import (is_mongos, joinall, enable_text_search, get_pool,
|
||||
oid_generated_on_client)
|
||||
from test.utils import (catch_warnings, enable_text_search,
|
||||
get_pool, is_mongos, joinall, oid_generated_on_client)
|
||||
from test import (qcheck,
|
||||
version)
|
||||
|
||||
@ -226,19 +226,21 @@ class TestCollection(unittest.TestCase):
|
||||
def test_deprecated_ttl_index_kwarg(self):
|
||||
db = self.db
|
||||
|
||||
# In Python 2.6+ we could use the catch_warnings context
|
||||
# manager to test this warning nicely. As we can't do that
|
||||
# we must test raising errors before the ignore filter is applied.
|
||||
warnings.simplefilter("error", DeprecationWarning)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("error", DeprecationWarning)
|
||||
self.assertRaises(DeprecationWarning, lambda:
|
||||
db.test.ensure_index("goodbye", ttl=10))
|
||||
finally:
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter("ignore")
|
||||
ctx.exit()
|
||||
|
||||
self.assertEqual("goodbye_1",
|
||||
db.test.ensure_index("goodbye", ttl=10))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
self.assertEqual("goodbye_1",
|
||||
db.test.ensure_index("goodbye", ttl=10))
|
||||
finally:
|
||||
ctx.exit()
|
||||
self.assertEqual(None, db.test.ensure_index("goodbye"))
|
||||
|
||||
def test_ensure_unique_index_threaded(self):
|
||||
@ -853,10 +855,15 @@ class TestCollection(unittest.TestCase):
|
||||
)
|
||||
|
||||
# Misconfigured value for safe
|
||||
self.assertRaises(
|
||||
TypeError,
|
||||
lambda: db.test.insert([{'i': 2}] * 2, safe=1),
|
||||
)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
self.assertRaises(
|
||||
TypeError,
|
||||
lambda: db.test.insert([{'i': 2}] * 2, safe=1),
|
||||
)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_insert_iterables(self):
|
||||
db = self.db
|
||||
@ -979,10 +986,16 @@ class TestCollection(unittest.TestCase):
|
||||
db.test.insert({"_id": 2, "x": 2})
|
||||
|
||||
# No error
|
||||
db.test.insert({"_id": 1, "x": 1}, safe=False)
|
||||
db.test.save({"_id": 1, "x": 1}, safe=False)
|
||||
db.test.insert({"_id": 2, "x": 2}, safe=False)
|
||||
db.test.save({"_id": 2, "x": 2}, safe=False)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
db.test.insert({"_id": 1, "x": 1}, safe=False)
|
||||
db.test.save({"_id": 1, "x": 1}, safe=False)
|
||||
db.test.insert({"_id": 2, "x": 2}, safe=False)
|
||||
db.test.save({"_id": 2, "x": 2}, safe=False)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
db.test.insert({"_id": 1, "x": 1}, w=0)
|
||||
db.test.save({"_id": 1, "x": 1}, w=0)
|
||||
db.test.insert({"_id": 2, "x": 2}, w=0)
|
||||
@ -2200,47 +2213,51 @@ class TestCollection(unittest.TestCase):
|
||||
for j in xrange(5):
|
||||
c.insert({'j': j, 'i': 0})
|
||||
|
||||
sort={'j': DESCENDING}
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort={'j': ASCENDING}
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=[('j', DESCENDING)]
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=[('j', ASCENDING)]
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=SON([('j', DESCENDING)])
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=SON([('j', ASCENDING)])
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
sort=OrderedDict([('j', DESCENDING)])
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
sort={'j': DESCENDING}
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=OrderedDict([('j', ASCENDING)])
|
||||
sort={'j': ASCENDING}
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
except ImportError:
|
||||
pass
|
||||
# Test that a standard dict with two keys is rejected.
|
||||
sort={'j': DESCENDING, 'foo': DESCENDING}
|
||||
self.assertRaises(TypeError, c.find_and_modify, {},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)
|
||||
sort=[('j', DESCENDING)]
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=[('j', ASCENDING)]
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=SON([('j', DESCENDING)])
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=SON([('j', ASCENDING)])
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
sort=OrderedDict([('j', DESCENDING)])
|
||||
self.assertEqual(4, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
sort=OrderedDict([('j', ASCENDING)])
|
||||
self.assertEqual(0, c.find_and_modify({},
|
||||
{'$inc': {'i': 1}},
|
||||
sort=sort)['j'])
|
||||
except ImportError:
|
||||
pass
|
||||
# Test that a standard dict with two keys is rejected.
|
||||
sort={'j': DESCENDING, 'foo': DESCENDING}
|
||||
self.assertRaises(TypeError, c.find_and_modify,
|
||||
{}, {'$inc': {'i': 1}}, sort=sort)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_find_with_nested(self):
|
||||
if not version.at_least(self.db.connection, (2, 0, 0)):
|
||||
|
||||
@ -31,7 +31,7 @@ from pymongo.mongo_client import MongoClient
|
||||
from pymongo.mongo_replica_set_client import MongoReplicaSetClient
|
||||
from pymongo.errors import ConfigurationError, OperationFailure
|
||||
from test import host, port, pair, version
|
||||
from test.utils import drop_collections
|
||||
from test.utils import catch_warnings, drop_collections
|
||||
|
||||
have_uuid = True
|
||||
try:
|
||||
@ -44,11 +44,9 @@ class TestCommon(unittest.TestCase):
|
||||
|
||||
def test_baseobject(self):
|
||||
|
||||
# In Python 2.6+ we could use the catch_warnings context
|
||||
# manager to test this warning nicely. As we can't do that
|
||||
# we must test raising errors before the ignore filter is applied.
|
||||
warnings.simplefilter("error", UserWarning)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("error", UserWarning)
|
||||
self.assertRaises(UserWarning, lambda:
|
||||
MongoClient(host, port, wtimeout=1000, w=0))
|
||||
try:
|
||||
@ -61,191 +59,195 @@ class TestCommon(unittest.TestCase):
|
||||
except UserWarning:
|
||||
self.fail()
|
||||
finally:
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter("ignore")
|
||||
ctx.exit()
|
||||
|
||||
# Connection tests
|
||||
c = Connection(pair)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
db.drop_collection("test")
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertFalse(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertFalse(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
c = Connection(pair)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
db.drop_collection("test")
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertFalse(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertFalse(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
|
||||
self.assertEqual((False, {}), coll._get_write_mode())
|
||||
coll.safe = False
|
||||
coll.write_concern.update(w=1)
|
||||
self.assertEqual((True, {}), coll._get_write_mode())
|
||||
coll.write_concern.update(w=3)
|
||||
self.assertEqual((True, {'w': 3}), coll._get_write_mode())
|
||||
self.assertEqual((False, {}), coll._get_write_mode())
|
||||
coll.safe = False
|
||||
coll.write_concern.update(w=1)
|
||||
self.assertEqual((True, {}), coll._get_write_mode())
|
||||
coll.write_concern.update(w=3)
|
||||
self.assertEqual((True, {'w': 3}), coll._get_write_mode())
|
||||
|
||||
coll.safe = True
|
||||
coll.write_concern.update(w=0)
|
||||
self.assertEqual((False, {}), coll._get_write_mode())
|
||||
coll.safe = True
|
||||
coll.write_concern.update(w=0)
|
||||
self.assertEqual((False, {}), coll._get_write_mode())
|
||||
|
||||
coll = db.test
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=True)
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
coll = db.test
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=True)
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
|
||||
# MongoClient test
|
||||
c = MongoClient(pair)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
db.drop_collection("test")
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
# MongoClient test
|
||||
c = MongoClient(pair)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
db.drop_collection("test")
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
|
||||
self.assertEqual((True, {}), coll._get_write_mode())
|
||||
coll.safe = False
|
||||
coll.write_concern.update(w=1)
|
||||
self.assertEqual((True, {}), coll._get_write_mode())
|
||||
coll.write_concern.update(w=3)
|
||||
self.assertEqual((True, {'w': 3}), coll._get_write_mode())
|
||||
self.assertEqual((True, {}), coll._get_write_mode())
|
||||
coll.safe = False
|
||||
coll.write_concern.update(w=1)
|
||||
self.assertEqual((True, {}), coll._get_write_mode())
|
||||
coll.write_concern.update(w=3)
|
||||
self.assertEqual((True, {'w': 3}), coll._get_write_mode())
|
||||
|
||||
coll.safe = True
|
||||
coll.write_concern.update(w=0)
|
||||
self.assertEqual((False, {}), coll._get_write_mode())
|
||||
coll.safe = True
|
||||
coll.write_concern.update(w=0)
|
||||
self.assertEqual((False, {}), coll._get_write_mode())
|
||||
|
||||
coll = db.test
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=True)
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
coll = db.test
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=True)
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
|
||||
# Setting any safe operations overrides explicit safe
|
||||
self.assertTrue(MongoClient(host, port, wtimeout=1000, safe=False).safe)
|
||||
# Setting any safe operations overrides explicit safe
|
||||
self.assertTrue(MongoClient(host, port, wtimeout=1000, safe=False).safe)
|
||||
|
||||
c = MongoClient(pair, slaveok=True, w='majority',
|
||||
wtimeout=300, fsync=True, j=True)
|
||||
self.assertTrue(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
d = {'w': 'majority', 'wtimeout': 300, 'fsync': True, 'j': True}
|
||||
self.assertEqual(d, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
self.assertTrue(db.slave_okay)
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual(d, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertTrue(coll.slave_okay)
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual(d, coll.get_lasterror_options())
|
||||
cursor = coll.find()
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=False)
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
c = MongoClient(pair, slaveok=True, w='majority',
|
||||
wtimeout=300, fsync=True, j=True)
|
||||
self.assertTrue(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
d = {'w': 'majority', 'wtimeout': 300, 'fsync': True, 'j': True}
|
||||
self.assertEqual(d, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
self.assertTrue(db.slave_okay)
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual(d, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertTrue(coll.slave_okay)
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual(d, coll.get_lasterror_options())
|
||||
cursor = coll.find()
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=False)
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
|
||||
c = MongoClient('mongodb://%s/?'
|
||||
'w=2;wtimeoutMS=300;fsync=true;'
|
||||
'journal=true' % (pair,))
|
||||
self.assertTrue(c.safe)
|
||||
d = {'w': 2, 'wtimeout': 300, 'fsync': True, 'j': True}
|
||||
self.assertEqual(d, c.get_lasterror_options())
|
||||
c = MongoClient('mongodb://%s/?'
|
||||
'w=2;wtimeoutMS=300;fsync=true;'
|
||||
'journal=true' % (pair,))
|
||||
self.assertTrue(c.safe)
|
||||
d = {'w': 2, 'wtimeout': 300, 'fsync': True, 'j': True}
|
||||
self.assertEqual(d, c.get_lasterror_options())
|
||||
|
||||
c = MongoClient('mongodb://%s/?'
|
||||
'slaveok=true;w=1;wtimeout=300;'
|
||||
'fsync=true;j=true' % (pair,))
|
||||
self.assertTrue(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
d = {'w': 1, 'wtimeout': 300, 'fsync': True, 'j': True}
|
||||
self.assertEqual(d, c.get_lasterror_options())
|
||||
self.assertEqual(d, c.write_concern)
|
||||
db = c.pymongo_test
|
||||
self.assertTrue(db.slave_okay)
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual(d, db.get_lasterror_options())
|
||||
self.assertEqual(d, db.write_concern)
|
||||
coll = db.test
|
||||
self.assertTrue(coll.slave_okay)
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual(d, coll.get_lasterror_options())
|
||||
self.assertEqual(d, coll.write_concern)
|
||||
cursor = coll.find()
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=False)
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
c = MongoClient('mongodb://%s/?'
|
||||
'slaveok=true;w=1;wtimeout=300;'
|
||||
'fsync=true;j=true' % (pair,))
|
||||
self.assertTrue(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
d = {'w': 1, 'wtimeout': 300, 'fsync': True, 'j': True}
|
||||
self.assertEqual(d, c.get_lasterror_options())
|
||||
self.assertEqual(d, c.write_concern)
|
||||
db = c.pymongo_test
|
||||
self.assertTrue(db.slave_okay)
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual(d, db.get_lasterror_options())
|
||||
self.assertEqual(d, db.write_concern)
|
||||
coll = db.test
|
||||
self.assertTrue(coll.slave_okay)
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual(d, coll.get_lasterror_options())
|
||||
self.assertEqual(d, coll.write_concern)
|
||||
cursor = coll.find()
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=False)
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
|
||||
c.unset_lasterror_options()
|
||||
self.assertTrue(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
c.safe = False
|
||||
self.assertFalse(c.safe)
|
||||
c.slave_okay = False
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
self.assertEqual({}, c.write_concern)
|
||||
db = c.pymongo_test
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertFalse(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
self.assertEqual({}, db.write_concern)
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertFalse(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
self.assertEqual({}, coll.write_concern)
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=True)
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
c.unset_lasterror_options()
|
||||
self.assertTrue(c.slave_okay)
|
||||
self.assertTrue(c.safe)
|
||||
c.safe = False
|
||||
self.assertFalse(c.safe)
|
||||
c.slave_okay = False
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
self.assertEqual({}, c.write_concern)
|
||||
db = c.pymongo_test
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertFalse(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
self.assertEqual({}, db.write_concern)
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertFalse(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
self.assertEqual({}, coll.write_concern)
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = coll.find(slave_okay=True)
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
|
||||
coll.set_lasterror_options(fsync=True)
|
||||
self.assertEqual({'fsync': True}, coll.get_lasterror_options())
|
||||
self.assertEqual({'fsync': True}, coll.write_concern)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
self.assertEqual({}, db.write_concern)
|
||||
self.assertFalse(db.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
self.assertEqual({}, c.write_concern)
|
||||
self.assertFalse(c.safe)
|
||||
coll.set_lasterror_options(fsync=True)
|
||||
self.assertEqual({'fsync': True}, coll.get_lasterror_options())
|
||||
self.assertEqual({'fsync': True}, coll.write_concern)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
self.assertEqual({}, db.write_concern)
|
||||
self.assertFalse(db.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
self.assertEqual({}, c.write_concern)
|
||||
self.assertFalse(c.safe)
|
||||
|
||||
db.set_lasterror_options(w='majority')
|
||||
self.assertEqual({'fsync': True}, coll.get_lasterror_options())
|
||||
self.assertEqual({'fsync': True}, coll.write_concern)
|
||||
self.assertEqual({'w': 'majority'}, db.get_lasterror_options())
|
||||
self.assertEqual({'w': 'majority'}, db.write_concern)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
self.assertEqual({}, c.write_concern)
|
||||
self.assertFalse(c.safe)
|
||||
db.slave_okay = True
|
||||
self.assertTrue(db.slave_okay)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(coll.slave_okay)
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = db.coll2.find()
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
cursor = db.coll2.find(slave_okay=False)
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
db.set_lasterror_options(w='majority')
|
||||
self.assertEqual({'fsync': True}, coll.get_lasterror_options())
|
||||
self.assertEqual({'fsync': True}, coll.write_concern)
|
||||
self.assertEqual({'w': 'majority'}, db.get_lasterror_options())
|
||||
self.assertEqual({'w': 'majority'}, db.write_concern)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
self.assertEqual({}, c.write_concern)
|
||||
self.assertFalse(c.safe)
|
||||
db.slave_okay = True
|
||||
self.assertTrue(db.slave_okay)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(coll.slave_okay)
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
cursor = db.coll2.find()
|
||||
self.assertTrue(cursor._Cursor__slave_okay)
|
||||
cursor = db.coll2.find(slave_okay=False)
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
|
||||
self.assertRaises(ConfigurationError, coll.set_lasterror_options, foo=20)
|
||||
self.assertRaises(TypeError, coll._BaseObject__set_slave_okay, 20)
|
||||
self.assertRaises(TypeError, coll._BaseObject__set_safe, 20)
|
||||
self.assertRaises(ConfigurationError, coll.set_lasterror_options, foo=20)
|
||||
self.assertRaises(TypeError, coll._BaseObject__set_slave_okay, 20)
|
||||
self.assertRaises(TypeError, coll._BaseObject__set_safe, 20)
|
||||
|
||||
coll.remove()
|
||||
self.assertEqual(None, coll.find_one(slave_okay=True))
|
||||
coll.unset_lasterror_options()
|
||||
coll.set_lasterror_options(w=4, wtimeout=10)
|
||||
# Fails if we don't have 4 active nodes or we don't have replication...
|
||||
self.assertRaises(OperationFailure, coll.insert, {'foo': 'bar'})
|
||||
# Succeeds since we override the lasterror settings per query.
|
||||
self.assertTrue(coll.insert({'foo': 'bar'}, fsync=True))
|
||||
drop_collections(db)
|
||||
coll.remove()
|
||||
self.assertEqual(None, coll.find_one(slave_okay=True))
|
||||
coll.unset_lasterror_options()
|
||||
coll.set_lasterror_options(w=4, wtimeout=10)
|
||||
# Fails if we don't have 4 active nodes or we don't have replication...
|
||||
self.assertRaises(OperationFailure, coll.insert, {'foo': 'bar'})
|
||||
# Succeeds since we override the lasterror settings per query.
|
||||
self.assertTrue(coll.insert({'foo': 'bar'}, fsync=True))
|
||||
drop_collections(db)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_uuid_subtype(self):
|
||||
if not have_uuid:
|
||||
@ -439,30 +441,36 @@ class TestCommon(unittest.TestCase):
|
||||
m = MongoClient(pair, w=0)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
doc = {"_id": ObjectId()}
|
||||
coll.insert(doc)
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertTrue(coll.insert(doc))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoClient(pair)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
doc = {"_id": ObjectId()}
|
||||
coll.insert(doc)
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertTrue(coll.insert(doc))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoClient("mongodb://%s/" % (pair,))
|
||||
self.assertTrue(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
m = MongoClient("mongodb://%s/?w=0" % (pair,))
|
||||
self.assertFalse(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc))
|
||||
m = MongoClient(pair)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoClient("mongodb://%s/" % (pair,))
|
||||
self.assertTrue(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
m = MongoClient("mongodb://%s/?w=0" % (pair,))
|
||||
self.assertFalse(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
# Equality tests
|
||||
self.assertEqual(m, MongoClient("mongodb://%s/?w=0" % (pair,)))
|
||||
@ -478,30 +486,36 @@ class TestCommon(unittest.TestCase):
|
||||
m = MongoReplicaSetClient(pair, replicaSet=setname, w=0)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
doc = {"_id": ObjectId()}
|
||||
coll.insert(doc)
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertTrue(coll.insert(doc))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoReplicaSetClient(pair, replicaSet=setname)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
doc = {"_id": ObjectId()}
|
||||
coll.insert(doc)
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertTrue(coll.insert(doc))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoReplicaSetClient("mongodb://%s/?replicaSet=%s" % (pair, setname))
|
||||
self.assertTrue(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
m = MongoReplicaSetClient("mongodb://%s/?replicaSet=%s;w=0" % (pair, setname))
|
||||
self.assertFalse(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc))
|
||||
m = MongoReplicaSetClient(pair, replicaSet=setname)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc, safe=False))
|
||||
self.assertTrue(coll.insert(doc, w=0))
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, safe=True)
|
||||
self.assertRaises(OperationFailure, coll.insert, doc, w=1)
|
||||
|
||||
m = MongoReplicaSetClient("mongodb://%s/?replicaSet=%s" % (pair, setname))
|
||||
self.assertTrue(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertRaises(OperationFailure, coll.insert, doc)
|
||||
m = MongoReplicaSetClient("mongodb://%s/?replicaSet=%s;w=0" % (pair, setname))
|
||||
self.assertFalse(m.safe)
|
||||
coll = m.pymongo_test.write_concern_test
|
||||
self.assertTrue(coll.insert(doc))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -19,6 +19,8 @@ import random
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from nose.plugins.skip import SkipTest
|
||||
@ -37,7 +39,8 @@ from pymongo.errors import (InvalidOperation,
|
||||
ExecutionTimeout)
|
||||
from test import version
|
||||
from test.test_client import get_client
|
||||
from test.utils import is_mongos, get_command_line, server_started_with_auth
|
||||
from test.utils import (catch_warnings, is_mongos,
|
||||
get_command_line, server_started_with_auth)
|
||||
|
||||
|
||||
class TestCursor(unittest.TestCase):
|
||||
@ -1100,8 +1103,11 @@ self.assertFalse(c2.alive)
|
||||
pass
|
||||
|
||||
client = self.db.connection
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
client.set_cursor_manager(CManager)
|
||||
|
||||
docs = []
|
||||
cursor = self.db.test.find().batch_size(10)
|
||||
docs.append(cursor.next())
|
||||
@ -1115,6 +1121,7 @@ self.assertFalse(c2.alive)
|
||||
self.assertEqual(len(docs), 200)
|
||||
finally:
|
||||
client.set_cursor_manager(CursorManager)
|
||||
ctx.exit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@ -47,8 +47,8 @@ from pymongo.son_manipulator import (AutoReference,
|
||||
NamespaceInjector,
|
||||
ObjectIdShuffler)
|
||||
from test import version
|
||||
from test.utils import (get_command_line, is_mongos,
|
||||
remove_all_users, server_started_with_auth)
|
||||
from test.utils import (catch_warnings, get_command_line,
|
||||
is_mongos, remove_all_users, server_started_with_auth)
|
||||
from test.test_client import get_client
|
||||
|
||||
|
||||
@ -368,15 +368,15 @@ class TestDatabase(unittest.TestCase):
|
||||
"user", 'password', True, roles=['read'])
|
||||
|
||||
if version.at_least(self.client, (2, 5, 3, -1)):
|
||||
warnings.simplefilter("error", DeprecationWarning)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("error", DeprecationWarning)
|
||||
self.assertRaises(DeprecationWarning, db.add_user,
|
||||
"user", "password")
|
||||
self.assertRaises(DeprecationWarning, db.add_user,
|
||||
"user", "password", True)
|
||||
finally:
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter("ignore")
|
||||
ctx.exit()
|
||||
|
||||
self.assertRaises(ConfigurationError, db.add_user,
|
||||
"user", "password", digestPassword=True)
|
||||
@ -947,8 +947,9 @@ class TestDatabase(unittest.TestCase):
|
||||
self.fail("_check_command_response didn't raise OperationFailure")
|
||||
|
||||
def test_command_read_pref_warning(self):
|
||||
warnings.simplefilter("error", UserWarning)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("error", UserWarning)
|
||||
self.assertRaises(UserWarning, self.client.pymongo_test.command,
|
||||
'ping', read_preference=ReadPreference.SECONDARY)
|
||||
try:
|
||||
@ -957,8 +958,7 @@ class TestDatabase(unittest.TestCase):
|
||||
except UserWarning:
|
||||
self.fail("Shouldn't have raised UserWarning.")
|
||||
finally:
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter("ignore")
|
||||
ctx.exit()
|
||||
|
||||
def test_command_max_time_ms(self):
|
||||
if not version.at_least(self.client, (2, 5, 3, -1)):
|
||||
|
||||
@ -16,25 +16,25 @@
|
||||
|
||||
"""Tests for the gridfs package.
|
||||
"""
|
||||
import sys
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from pymongo.mongo_client import MongoClient
|
||||
from pymongo.errors import ConnectionFailure
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from test.test_replica_set_client import TestReplicaSetClientBase
|
||||
|
||||
import datetime
|
||||
import unittest
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
import gridfs
|
||||
|
||||
from bson.py3compat import b, StringIO
|
||||
from gridfs.errors import (FileExists,
|
||||
NoFile)
|
||||
from gridfs.errors import (FileExists, NoFile)
|
||||
from pymongo.errors import ConnectionFailure
|
||||
from pymongo.mongo_client import MongoClient
|
||||
from pymongo.read_preferences import ReadPreference
|
||||
from test.test_client import get_client
|
||||
from test.utils import joinall
|
||||
from test.test_replica_set_client import TestReplicaSetClientBase
|
||||
from test.utils import catch_warnings, joinall
|
||||
|
||||
|
||||
class JustWrite(threading.Thread):
|
||||
@ -416,20 +416,25 @@ class TestGridfsReplicaSet(TestReplicaSetClientBase):
|
||||
primary_connection = MongoClient(primary_host, primary_port)
|
||||
|
||||
secondary_host, secondary_port = self.secondaries[0]
|
||||
for secondary_connection in [
|
||||
MongoClient(secondary_host, secondary_port, slave_okay=True),
|
||||
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")
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
for secondary_connection in [
|
||||
MongoClient(secondary_host, secondary_port, slave_okay=True),
|
||||
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")
|
||||
|
||||
# Should detect it's connected to secondary and not attempt to
|
||||
# create index
|
||||
fs = gridfs.GridFS(secondary_connection.pymongo_test)
|
||||
# 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'))
|
||||
# This won't detect secondary, raises error
|
||||
self.assertRaises(ConnectionFailure, fs.put, b('foo'))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_gridfs_secondary_lazy(self):
|
||||
# Should detect it's connected to secondary and not attempt to
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
@ -28,27 +29,33 @@ from pymongo.replica_set_connection import ReplicaSetConnection
|
||||
from pymongo.errors import ConfigurationError
|
||||
from test import host, port, pair
|
||||
from test.test_replica_set_client import TestReplicaSetClientBase
|
||||
from test.utils import get_pool
|
||||
from test.utils import catch_warnings, get_pool
|
||||
|
||||
|
||||
class TestConnection(unittest.TestCase):
|
||||
def test_connection(self):
|
||||
c = Connection(host, port)
|
||||
self.assertTrue(c.auto_start_request)
|
||||
self.assertEqual(None, c.max_pool_size)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
|
||||
# Connection's writes are unacknowledged by default
|
||||
doc = {"_id": ObjectId()}
|
||||
coll = c.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
coll.insert(doc)
|
||||
coll.insert(doc)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
self.assertTrue(c.auto_start_request)
|
||||
self.assertEqual(None, c.max_pool_size)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
|
||||
c = Connection("mongodb://%s:%s/?safe=true" % (host, port))
|
||||
self.assertTrue(c.safe)
|
||||
# Connection's writes are unacknowledged by default
|
||||
doc = {"_id": ObjectId()}
|
||||
coll = c.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
coll.insert(doc)
|
||||
coll.insert(doc)
|
||||
|
||||
c = Connection("mongodb://%s:%s/?safe=true" % (host, port))
|
||||
self.assertTrue(c.safe)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
# To preserve legacy Connection's behavior, max_size should be None.
|
||||
# Pool should handle this without error.
|
||||
@ -73,23 +80,29 @@ class TestConnection(unittest.TestCase):
|
||||
class TestReplicaSetConnection(TestReplicaSetClientBase):
|
||||
def test_replica_set_connection(self):
|
||||
c = ReplicaSetConnection(pair, replicaSet=self.name)
|
||||
self.assertTrue(c.auto_start_request)
|
||||
self.assertEqual(None, c.max_pool_size)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
|
||||
# ReplicaSetConnection's writes are unacknowledged by default
|
||||
doc = {"_id": ObjectId()}
|
||||
coll = c.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
coll.insert(doc)
|
||||
coll.insert(doc)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
self.assertTrue(c.auto_start_request)
|
||||
self.assertEqual(None, c.max_pool_size)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertFalse(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
|
||||
c = ReplicaSetConnection("mongodb://%s:%s/?replicaSet=%s&safe=true" % (
|
||||
host, port, self.name))
|
||||
# ReplicaSetConnection's writes are unacknowledged by default
|
||||
doc = {"_id": ObjectId()}
|
||||
coll = c.pymongo_test.write_concern_test
|
||||
coll.drop()
|
||||
coll.insert(doc)
|
||||
coll.insert(doc)
|
||||
|
||||
self.assertTrue(c.safe)
|
||||
c = ReplicaSetConnection("mongodb://%s:%s/?replicaSet=%s&safe=true" % (
|
||||
host, port, self.name))
|
||||
|
||||
self.assertTrue(c.safe)
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
# To preserve legacy ReplicaSetConnection's behavior, max_size should
|
||||
# be None. Pool should handle this without error.
|
||||
|
||||
@ -20,6 +20,8 @@ import sys
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from nose.plugins.skip import SkipTest
|
||||
@ -35,7 +37,7 @@ from pymongo.mongo_client import MongoClient
|
||||
from pymongo.collection import Collection
|
||||
from pymongo.master_slave_connection import MasterSlaveConnection
|
||||
from test import host, port, host2, port2, host3, port3
|
||||
from test.utils import TestRequestMixin, get_pool
|
||||
from test.utils import TestRequestMixin, catch_warnings, get_pool
|
||||
|
||||
|
||||
class TestMasterSlaveConnection(unittest.TestCase, TestRequestMixin):
|
||||
@ -363,7 +365,7 @@ class TestMasterSlaveConnection(unittest.TestCase, TestRequestMixin):
|
||||
|
||||
def test_kill_cursor_explicit(self):
|
||||
c = self.client
|
||||
c.slave_okay = True
|
||||
c.read_preference = ReadPreference.SECONDARY_PREFERRED
|
||||
db = c.pymongo_test
|
||||
|
||||
test = db.master_slave_test_kill_cursor_explicit
|
||||
@ -412,60 +414,65 @@ class TestMasterSlaveConnection(unittest.TestCase, TestRequestMixin):
|
||||
self.assertRaises(OperationFailure, lambda: list(cursor2))
|
||||
|
||||
def test_base_object(self):
|
||||
c = self.client
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
coll.drop()
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
self.assertTrue(bool(cursor._Cursor__read_preference))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
c = self.client
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(c.safe)
|
||||
self.assertEqual({}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual({}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
coll.drop()
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual({}, coll.get_lasterror_options())
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
self.assertTrue(bool(cursor._Cursor__read_preference))
|
||||
|
||||
w = 1 + len(self.slaves)
|
||||
wtimeout=10000 # Wait 10 seconds for replication to complete
|
||||
c.set_lasterror_options(w=w, wtimeout=wtimeout)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(c.safe)
|
||||
self.assertEqual({'w': w, 'wtimeout': wtimeout}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual({'w': w, 'wtimeout': wtimeout}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual({'w': w, 'wtimeout': wtimeout},
|
||||
coll.get_lasterror_options())
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
self.assertTrue(bool(cursor._Cursor__read_preference))
|
||||
w = 1 + len(self.slaves)
|
||||
wtimeout=10000 # Wait 10 seconds for replication to complete
|
||||
c.set_lasterror_options(w=w, wtimeout=wtimeout)
|
||||
self.assertFalse(c.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(c.safe)
|
||||
self.assertEqual({'w': w, 'wtimeout': wtimeout}, c.get_lasterror_options())
|
||||
db = c.pymongo_test
|
||||
self.assertFalse(db.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(db.safe)
|
||||
self.assertEqual({'w': w, 'wtimeout': wtimeout}, db.get_lasterror_options())
|
||||
coll = db.test
|
||||
self.assertFalse(coll.slave_okay)
|
||||
self.assertTrue(bool(c.read_preference))
|
||||
self.assertTrue(coll.safe)
|
||||
self.assertEqual({'w': w, 'wtimeout': wtimeout},
|
||||
coll.get_lasterror_options())
|
||||
cursor = coll.find()
|
||||
self.assertFalse(cursor._Cursor__slave_okay)
|
||||
self.assertTrue(bool(cursor._Cursor__read_preference))
|
||||
|
||||
coll.insert({'foo': 'bar'})
|
||||
self.assertEqual(1, coll.find({'foo': 'bar'}).count())
|
||||
self.assertTrue(coll.find({'foo': 'bar'}))
|
||||
coll.remove({'foo': 'bar'})
|
||||
self.assertEqual(0, coll.find({'foo': 'bar'}).count())
|
||||
coll.insert({'foo': 'bar'})
|
||||
self.assertEqual(1, coll.find({'foo': 'bar'}).count())
|
||||
self.assertTrue(coll.find({'foo': 'bar'}))
|
||||
coll.remove({'foo': 'bar'})
|
||||
self.assertEqual(0, coll.find({'foo': 'bar'}).count())
|
||||
|
||||
c.safe = False
|
||||
c.unset_lasterror_options()
|
||||
self.assertFalse(self.client.slave_okay)
|
||||
self.assertTrue(bool(self.client.read_preference))
|
||||
self.assertFalse(self.client.safe)
|
||||
self.assertEqual({}, self.client.get_lasterror_options())
|
||||
c.safe = False
|
||||
c.unset_lasterror_options()
|
||||
self.assertFalse(self.client.slave_okay)
|
||||
self.assertTrue(bool(self.client.read_preference))
|
||||
self.assertFalse(self.client.safe)
|
||||
self.assertEqual({}, self.client.get_lasterror_options())
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_document_class(self):
|
||||
c = MasterSlaveConnection(self.master, self.slaves)
|
||||
|
||||
@ -14,9 +14,9 @@
|
||||
|
||||
"""Test the replica_set_connection module."""
|
||||
import random
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
from nose.plugins.skip import SkipTest
|
||||
|
||||
@ -32,6 +32,7 @@ from pymongo.errors import ConfigurationError
|
||||
from test.test_replica_set_client import TestReplicaSetClientBase
|
||||
from test.test_client import get_client
|
||||
from test import version, utils, host, port
|
||||
from test.utils import catch_warnings
|
||||
|
||||
|
||||
class TestReadPreferencesBase(TestReplicaSetClientBase):
|
||||
@ -278,8 +279,13 @@ class TestCommandAndReadPreference(TestReplicaSetClientBase):
|
||||
# Test generic 'command' method. Some commands obey read preference,
|
||||
# most don't.
|
||||
# Disobedient commands, always go to primary
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command('ping'))
|
||||
self._test_fn(False, lambda: self.c.admin.command('buildinfo'))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command('ping'))
|
||||
self._test_fn(False, lambda: self.c.admin.command('buildinfo'))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
# Obedient commands.
|
||||
self._test_fn(True, lambda: self.c.pymongo_test.command('group', {
|
||||
@ -342,7 +348,12 @@ class TestCommandAndReadPreference(TestReplicaSetClientBase):
|
||||
|
||||
# Text search.
|
||||
if version.at_least(self.c, (2, 3, 2)):
|
||||
utils.enable_text_search(self.c)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
utils.enable_text_search(self.c)
|
||||
finally:
|
||||
ctx.exit()
|
||||
db = self.c.pymongo_test
|
||||
|
||||
# Only way to create an index and wait for all members to build it.
|
||||
@ -366,20 +377,25 @@ class TestCommandAndReadPreference(TestReplicaSetClientBase):
|
||||
|
||||
# Non-inline mapreduce always goes to primary, doesn't obey read prefs.
|
||||
# Test with command in a SON and with kwargs
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(SON([
|
||||
('mapreduce', 'test'),
|
||||
('map', 'function() { }'),
|
||||
('reduce', 'function() { }'),
|
||||
('out', 'mr_out')
|
||||
])))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(SON([
|
||||
('mapreduce', 'test'),
|
||||
('map', 'function() { }'),
|
||||
('reduce', 'function() { }'),
|
||||
('out', 'mr_out')
|
||||
])))
|
||||
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
'mapreduce', 'test', map='function() { }',
|
||||
reduce='function() { }', out='mr_out'))
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
'mapreduce', 'test', map='function() { }',
|
||||
reduce='function() { }', out='mr_out'))
|
||||
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
'mapreduce', 'test', map='function() { }',
|
||||
reduce='function() { }', out={'replace': 'some_collection'}))
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
'mapreduce', 'test', map='function() { }',
|
||||
reduce='function() { }', out={'replace': 'some_collection'}))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
# Inline mapreduce obeys read prefs
|
||||
self._test_fn(True, lambda: self.c.pymongo_test.command(
|
||||
@ -405,32 +421,47 @@ class TestCommandAndReadPreference(TestReplicaSetClientBase):
|
||||
|
||||
# Aggregate with $out always goes to primary, doesn't obey read prefs.
|
||||
# Test aggregate command sent directly to db.command.
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
"aggregate", "test",
|
||||
pipeline=[{"$match": {"x": 1}}, {"$out": "agg_out"}]
|
||||
))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
"aggregate", "test",
|
||||
pipeline=[{"$match": {"x": 1}}, {"$out": "agg_out"}]
|
||||
))
|
||||
|
||||
# Test aggregate when sent through the collection aggregate function.
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.test.aggregate(
|
||||
[{"$match": {"x": 2}}, {"$out": "agg_out"}]
|
||||
))
|
||||
# Test aggregate when sent through the collection aggregate function.
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.test.aggregate(
|
||||
[{"$match": {"x": 2}}, {"$out": "agg_out"}]
|
||||
))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
self.c.pymongo_test.drop_collection("test")
|
||||
self.c.pymongo_test.drop_collection("agg_out")
|
||||
|
||||
def test_create_collection(self):
|
||||
# Collections should be created on primary, obviously
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
'create', 'some_collection%s' % random.randint(0, sys.maxint)))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.command(
|
||||
'create', 'some_collection%s' % random.randint(0, sys.maxint)))
|
||||
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.create_collection(
|
||||
'some_collection%s' % random.randint(0, sys.maxint)))
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.create_collection(
|
||||
'some_collection%s' % random.randint(0, sys.maxint)))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_drop_collection(self):
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.drop_collection(
|
||||
'some_collection'))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.drop_collection(
|
||||
'some_collection'))
|
||||
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.some_collection.drop())
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.some_collection.drop())
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_group(self):
|
||||
self._test_fn(True, lambda: self.c.pymongo_test.test.group(
|
||||
@ -440,8 +471,13 @@ class TestCommandAndReadPreference(TestReplicaSetClientBase):
|
||||
# mapreduce fails if no collection
|
||||
self.c.pymongo_test.test.insert({}, w=self.w)
|
||||
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.test.map_reduce(
|
||||
'function() { }', 'function() { }', 'mr_out'))
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
self._test_fn(False, lambda: self.c.pymongo_test.test.map_reduce(
|
||||
'function() { }', 'function() { }', 'mr_out'))
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
self._test_fn(True, lambda: self.c.pymongo_test.test.map_reduce(
|
||||
'function() { }', 'function() { }', {'inline': 1}))
|
||||
@ -517,83 +553,93 @@ class TestMongosConnection(unittest.TestCase):
|
||||
NEAREST = ReadPreference.NEAREST
|
||||
SLAVE_OKAY = _QUERY_OPTIONS['slave_okay']
|
||||
|
||||
# Test non-PRIMARY modes which can be combined with tags
|
||||
for kwarg, value, mongos_mode in (
|
||||
('read_preference', PRIMARY_PREFERRED, 'primaryPreferred'),
|
||||
('read_preference', SECONDARY, 'secondary'),
|
||||
('read_preference', SECONDARY_PREFERRED, 'secondaryPreferred'),
|
||||
('read_preference', NEAREST, 'nearest'),
|
||||
('slave_okay', True, 'secondaryPreferred'),
|
||||
('slave_okay', False, 'primary')
|
||||
):
|
||||
for tag_sets in (
|
||||
None, [{}]
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", DeprecationWarning)
|
||||
# Test non-PRIMARY modes which can be combined with tags
|
||||
for kwarg, value, mongos_mode in (
|
||||
('read_preference', PRIMARY_PREFERRED, 'primaryPreferred'),
|
||||
('read_preference', SECONDARY, 'secondary'),
|
||||
('read_preference', SECONDARY_PREFERRED, 'secondaryPreferred'),
|
||||
('read_preference', NEAREST, 'nearest'),
|
||||
('slave_okay', True, 'secondaryPreferred'),
|
||||
('slave_okay', False, 'primary')
|
||||
):
|
||||
# Create a client e.g. with read_preference=NEAREST or
|
||||
# slave_okay=True
|
||||
c = get_client(tag_sets=tag_sets, **{kwarg: value})
|
||||
for tag_sets in (
|
||||
None, [{}]
|
||||
):
|
||||
# Create a client e.g. with read_preference=NEAREST or
|
||||
# slave_okay=True
|
||||
c = get_client(tag_sets=tag_sets, **{kwarg: value})
|
||||
|
||||
self.assertEqual(is_mongos, c.is_mongos)
|
||||
cursor = c.pymongo_test.test.find()
|
||||
if is_mongos:
|
||||
# We don't set $readPreference for SECONDARY_PREFERRED
|
||||
# unless tags are in use. slaveOkay has the same effect.
|
||||
if mongos_mode == 'secondaryPreferred':
|
||||
self.assertEqual(
|
||||
None,
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
self.assertEqual(is_mongos, c.is_mongos)
|
||||
cursor = c.pymongo_test.test.find()
|
||||
if is_mongos:
|
||||
# We don't set $readPreference for SECONDARY_PREFERRED
|
||||
# unless tags are in use. slaveOkay has the same effect.
|
||||
if mongos_mode == 'secondaryPreferred':
|
||||
self.assertEqual(
|
||||
None,
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
|
||||
self.assertTrue(
|
||||
cursor._Cursor__query_options() & SLAVE_OKAY)
|
||||
self.assertTrue(
|
||||
cursor._Cursor__query_options() & SLAVE_OKAY)
|
||||
|
||||
# Don't send $readPreference for PRIMARY either
|
||||
elif mongos_mode == 'primary':
|
||||
self.assertEqual(
|
||||
None,
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
# Don't send $readPreference for PRIMARY either
|
||||
elif mongos_mode == 'primary':
|
||||
self.assertEqual(
|
||||
None,
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
|
||||
self.assertFalse(
|
||||
cursor._Cursor__query_options() & SLAVE_OKAY)
|
||||
self.assertFalse(
|
||||
cursor._Cursor__query_options() & SLAVE_OKAY)
|
||||
else:
|
||||
self.assertEqual(
|
||||
{'mode': mongos_mode},
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
|
||||
self.assertTrue(
|
||||
cursor._Cursor__query_options() & SLAVE_OKAY)
|
||||
else:
|
||||
self.assertFalse(
|
||||
'$readPreference' in cursor._Cursor__query_spec())
|
||||
|
||||
for tag_sets in (
|
||||
[{'dc': 'la'}],
|
||||
[{'dc': 'la'}, {'dc': 'sf'}],
|
||||
[{'dc': 'la'}, {'dc': 'sf'}, {}],
|
||||
):
|
||||
if kwarg == 'slave_okay':
|
||||
# Can't use tags with slave_okay True or False, need a
|
||||
# real read preference
|
||||
self.assertRaises(
|
||||
ConfigurationError,
|
||||
get_client, tag_sets=tag_sets, **{kwarg: value})
|
||||
|
||||
continue
|
||||
|
||||
c = get_client(tag_sets=tag_sets, **{kwarg: value})
|
||||
|
||||
self.assertEqual(is_mongos, c.is_mongos)
|
||||
cursor = c.pymongo_test.test.find()
|
||||
if is_mongos:
|
||||
self.assertEqual(
|
||||
{'mode': mongos_mode},
|
||||
{'mode': mongos_mode, 'tags': tag_sets},
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
|
||||
self.assertTrue(
|
||||
cursor._Cursor__query_options() & SLAVE_OKAY)
|
||||
else:
|
||||
self.assertFalse(
|
||||
'$readPreference' in cursor._Cursor__query_spec())
|
||||
|
||||
for tag_sets in (
|
||||
[{'dc': 'la'}],
|
||||
[{'dc': 'la'}, {'dc': 'sf'}],
|
||||
[{'dc': 'la'}, {'dc': 'sf'}, {}],
|
||||
):
|
||||
if kwarg == 'slave_okay':
|
||||
# Can't use tags with slave_okay True or False, need a
|
||||
# real read preference
|
||||
self.assertRaises(
|
||||
ConfigurationError,
|
||||
get_client, tag_sets=tag_sets, **{kwarg: value})
|
||||
|
||||
continue
|
||||
|
||||
c = get_client(tag_sets=tag_sets, **{kwarg: value})
|
||||
|
||||
self.assertEqual(is_mongos, c.is_mongos)
|
||||
cursor = c.pymongo_test.test.find()
|
||||
if is_mongos:
|
||||
self.assertEqual(
|
||||
{'mode': mongos_mode, 'tags': tag_sets},
|
||||
cursor._Cursor__query_spec().get('$readPreference'))
|
||||
else:
|
||||
self.assertFalse(
|
||||
'$readPreference' in cursor._Cursor__query_spec())
|
||||
else:
|
||||
self.assertFalse(
|
||||
'$readPreference' in cursor._Cursor__query_spec())
|
||||
finally:
|
||||
ctx.exit()
|
||||
|
||||
def test_only_secondary_ok_commands_have_read_prefs(self):
|
||||
c = get_client(read_preference=ReadPreference.SECONDARY)
|
||||
is_mongos = utils.is_mongos(c)
|
||||
ctx = catch_warnings()
|
||||
try:
|
||||
warnings.simplefilter("ignore", UserWarning)
|
||||
is_mongos = utils.is_mongos(c)
|
||||
finally:
|
||||
ctx.exit()
|
||||
if not is_mongos:
|
||||
raise SkipTest("Only mongos have read_prefs added to the spec")
|
||||
|
||||
|
||||
@ -260,7 +260,6 @@ class TestReplicaSetClient(TestReplicaSetClientBase, TestRequestMixin):
|
||||
read_preference=ReadPreference.SECONDARY,
|
||||
tag_sets=copy.deepcopy(tag_sets),
|
||||
secondary_acceptable_latency_ms=77)
|
||||
c.admin.command('ping')
|
||||
self.assertEqual(c.primary, self.primary)
|
||||
self.assertEqual(c.hosts, self.hosts)
|
||||
self.assertEqual(c.arbiters, self.arbiters)
|
||||
|
||||
@ -584,3 +584,83 @@ class _TestLazyConnectMixin(object):
|
||||
self.assertEqual(
|
||||
ismaster['maxMessageSizeBytes'],
|
||||
c.max_message_size)
|
||||
|
||||
|
||||
# Backport of WarningMessage from python 2.6, with fixed syntax for python 2.4.
|
||||
class WarningMessage(object):
|
||||
|
||||
"""Holds the result of a single showwarning() call."""
|
||||
|
||||
_WARNING_DETAILS = ("message", "category", "filename", "lineno", "file",
|
||||
"line")
|
||||
|
||||
def __init__(self, message, category,
|
||||
filename, lineno, file=None, line=None):
|
||||
local_values = locals()
|
||||
for attr in self._WARNING_DETAILS:
|
||||
setattr(self, attr, local_values[attr])
|
||||
self._category_name = None
|
||||
if category:
|
||||
self._category_name = category.__name__
|
||||
|
||||
def __str__(self):
|
||||
return ("{message : %r, category : %r, filename : %r, lineno : %s, "
|
||||
"line : %r}" % (self.message, self._category_name,
|
||||
self.filename, self.lineno, self.line))
|
||||
|
||||
|
||||
# Rough backport of warnings.catch_warnings from python 2.6,
|
||||
# with changes to support python 2.4.
|
||||
class CatchWarnings(object):
|
||||
"""A non-context manager version of warnings.catch_warnings.
|
||||
|
||||
The 'record' argument specifies whether warnings should be captured by a
|
||||
custom implementation of warnings.showwarning() and be appended to a list
|
||||
accessed through the `log` property. The objects appended to the list are
|
||||
arguments whose attributes mirror the arguments to showwarning().
|
||||
|
||||
The 'module' argument is to specify an alternative module to the module
|
||||
named 'warnings' and imported under that name. This argument is only useful
|
||||
when testing the warnings module itself.
|
||||
"""
|
||||
|
||||
def __init__(self, record=False, module=None):
|
||||
self._record = record
|
||||
if module is None:
|
||||
self._module = sys.modules['warnings']
|
||||
else:
|
||||
self._module = module
|
||||
|
||||
# No __enter__ so do that work here
|
||||
self._filters = self._module.filters
|
||||
self._module.filters = self._filters[:]
|
||||
self._showwarning = self._module.showwarning
|
||||
self._log = []
|
||||
if self._record:
|
||||
def showwarning(*args, **kwargs):
|
||||
self._log.append(WarningMessage(*args, **kwargs))
|
||||
self._module.showwarning = showwarning
|
||||
|
||||
@property
|
||||
def log(self):
|
||||
"""A list of any warnings recorded when using record=True."""
|
||||
return self._log
|
||||
|
||||
def __repr__(self):
|
||||
args = []
|
||||
if self._record:
|
||||
args.append("record=True")
|
||||
if self._module is not sys.modules['warnings']:
|
||||
args.append("module=%r" % self._module)
|
||||
name = type(self).__name__
|
||||
return "%s(%s)" % (name, ", ".join(args))
|
||||
|
||||
def exit(self):
|
||||
"""Revert changes to the warnings module."""
|
||||
self._module.filters = self._filters
|
||||
self._module.showwarning = self._showwarning
|
||||
|
||||
|
||||
def catch_warnings(record=False, module=None):
|
||||
"""Helper for use with CatchWarnings."""
|
||||
return CatchWarnings(record, module)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user