Add suport for Mongo 3.4 (travis, fix tests)

This commit is contained in:
Bastien Gérard
2018-10-02 21:26:14 +02:00
parent c60c2ee8d0
commit dca837b843
9 changed files with 94 additions and 50 deletions

View File

@@ -9,7 +9,8 @@ from six import iteritems
from mongoengine import *
from mongoengine.connection import get_db
from tests.utils import get_mongodb_version, requires_mongodb_gte_26, MONGODB_32, MONGODB_3
from mongoengine.mongodb_support import get_mongodb_version, MONGODB_32, MONGODB_3
from tests.utils import requires_mongodb_gte_26, requires_mongodb_lte_32, requires_mongodb_gte_34
__all__ = ("IndexesTest", )
@@ -477,6 +478,7 @@ class IndexesTest(unittest.TestCase):
def test_covered_index(self):
"""Ensure that covered indexes can be used
"""
IS_MONGODB_3 = get_mongodb_version() >= MONGODB_3
class Test(Document):
a = IntField()
@@ -492,8 +494,6 @@ class IndexesTest(unittest.TestCase):
obj = Test(a=1)
obj.save()
IS_MONGODB_3 = get_mongodb_version() >= MONGODB_3
# Need to be explicit about covered indexes as mongoDB doesn't know if
# the documents returned might have more keys in that here.
query_plan = Test.objects(id=obj.id).exclude('a').explain()
@@ -569,7 +569,7 @@ class IndexesTest(unittest.TestCase):
if pymongo.version != '3.0':
self.assertEqual(BlogPost.objects.hint([('tags', 1)]).count(), 10)
if MONGO_VER == MONGODB_32:
if MONGO_VER >= MONGODB_32:
# Mongo32 throws an error if an index exists (i.e `tags` in our case)
# and you use hint on an index name that does not exist
with self.assertRaises(OperationFailure):
@@ -601,6 +601,22 @@ class IndexesTest(unittest.TestCase):
# Ensure backwards compatibilty for errors
self.assertRaises(OperationError, post2.save)
@requires_mongodb_gte_34
def test_primary_key_unique_not_working_under_mongo_34(self):
class Blog(Document):
id = StringField(primary_key=True, unique=True)
with self.assertRaises(OperationFailure) as ctx_err:
Blog(id='garbage').save()
self.assertIn("The field 'unique' is not valid for an _id index specification", str(ctx_err.exception))
@requires_mongodb_lte_32
def test_primary_key_unique_working_under_mongo_32(self):
class Blog(Document):
id = StringField(primary_key=True, unique=True)
Blog(id='garbage').save()
def test_unique_with(self):
"""Ensure that unique_with constraints are applied to fields.
"""
@@ -760,7 +776,7 @@ class IndexesTest(unittest.TestCase):
You won't create a duplicate but you will update an existing document.
"""
class User(Document):
name = StringField(primary_key=True, unique=True)
name = StringField(primary_key=True)
password = StringField()
User.drop_collection()

View File

@@ -2113,7 +2113,7 @@ class FieldTest(MongoDBTestCase):
field_1 = StringField(db_field='f')
class Doc(Document):
my_id = IntField(required=True, unique=True, primary_key=True)
my_id = IntField(primary_key=True)
embed_me = DynamicField(db_field='e')
field_x = StringField(db_field='x')
@@ -2135,7 +2135,7 @@ class FieldTest(MongoDBTestCase):
field_1 = StringField(db_field='f')
class Doc(Document):
my_id = IntField(required=True, unique=True, primary_key=True)
my_id = IntField(primary_key=True)
embed_me = DynamicField(db_field='e')
field_x = StringField(db_field='x')

View File

@@ -18,11 +18,12 @@ from mongoengine import *
from mongoengine.connection import get_connection, get_db
from mongoengine.context_managers import query_counter, switch_db
from mongoengine.errors import InvalidQueryError
from mongoengine.mongodb_support import get_mongodb_version, MONGODB_32
from mongoengine.python_support import IS_PYMONGO_3
from mongoengine.queryset import (DoesNotExist, MultipleObjectsReturned,
QuerySet, QuerySetManager, queryset_manager)
from tests.utils import requires_mongodb_gte_26, skip_pymongo3, get_mongodb_version, MONGODB_32
from tests.utils import requires_mongodb_gte_26, skip_pymongo3
__all__ = ("QuerySetTest",)
@@ -852,8 +853,8 @@ class QuerySetTest(unittest.TestCase):
self.assertEqual(q, 0)
Blog.objects.insert(blogs, load_bulk=False)
if MONGO_VER == MONGODB_32:
self.assertEqual(q, 1) # 1 entry containing the list of inserts
if MONGO_VER >= MONGODB_32:
self.assertEqual(q, 1) # 1 entry containing the list of inserts
else:
self.assertEqual(q, len(blogs)) # 1 entry per doc inserted
@@ -869,8 +870,8 @@ class QuerySetTest(unittest.TestCase):
self.assertEqual(q, 0)
Blog.objects.insert(blogs)
if MONGO_VER == MONGODB_32:
self.assertEqual(q, 2) # 1 for insert 1 for fetch
if MONGO_VER >= MONGODB_32:
self.assertEqual(q, 2) # 1 for insert 1 for fetch
else:
self.assertEqual(q, len(blogs)+1) # + 1 to fetch all docs
@@ -1204,7 +1205,7 @@ class QuerySetTest(unittest.TestCase):
"""Ensure filters can be chained together.
"""
class Blog(Document):
id = StringField(unique=True, primary_key=True)
id = StringField(primary_key=True)
class BlogPost(Document):
blog = ReferenceField(Blog)
@@ -1316,7 +1317,7 @@ class QuerySetTest(unittest.TestCase):
order_by() w/o any arguments.
"""
MONGO_VER = self.mongodb_version
ORDER_BY_KEY = 'sort' if MONGO_VER == MONGODB_32 else '$orderby'
ORDER_BY_KEY = 'sort' if MONGO_VER >= MONGODB_32 else '$orderby'
class BlogPost(Document):
title = StringField()
@@ -2524,8 +2525,8 @@ class QuerySetTest(unittest.TestCase):
def test_comment(self):
"""Make sure adding a comment to the query gets added to the query"""
MONGO_VER = self.mongodb_version
QUERY_KEY = 'filter' if MONGO_VER == MONGODB_32 else '$query'
COMMENT_KEY = 'comment' if MONGO_VER == MONGODB_32 else '$comment'
QUERY_KEY = 'filter' if MONGO_VER >= MONGODB_32 else '$query'
COMMENT_KEY = 'comment' if MONGO_VER >= MONGODB_32 else '$comment'
class User(Document):
age = IntField()
@@ -3349,7 +3350,7 @@ class QuerySetTest(unittest.TestCase):
meta = {'indexes': [
{'fields': ['$title', "$content"],
'default_language': 'portuguese',
'weight': {'title': 10, 'content': 2}
'weights': {'title': 10, 'content': 2}
}
]}
@@ -5131,7 +5132,7 @@ class QuerySetTest(unittest.TestCase):
def test_query_reference_to_custom_pk_doc(self):
class A(Document):
id = StringField(unique=True, primary_key=True)
id = StringField(primary_key=True)
class B(Document):
a = ReferenceField(A)
@@ -5236,7 +5237,7 @@ class QuerySetTest(unittest.TestCase):
def test_bool_with_ordering(self):
MONGO_VER = self.mongodb_version
ORDER_BY_KEY = 'sort' if MONGO_VER == MONGODB_32 else '$orderby'
ORDER_BY_KEY = 'sort' if MONGO_VER >= MONGODB_32 else '$orderby'
class Person(Document):
name = StringField()

View File

@@ -1,22 +1,17 @@
import operator
import unittest
from nose.plugins.skip import SkipTest
from mongoengine import connect
from mongoengine.connection import get_db, get_connection
from mongoengine.connection import get_db
from mongoengine.mongodb_support import get_mongodb_version, MONGODB_26, MONGODB_3, MONGODB_32, MONGODB_34
from mongoengine.python_support import IS_PYMONGO_3
MONGO_TEST_DB = 'mongoenginetest' # standard name for the test database
# Constant that can be used to compare the version retrieved with
# get_mongodb_version()
MONGODB_26 = (2, 6)
MONGODB_3 = (3, 0)
MONGODB_32 = (3, 2)
class MongoDBTestCase(unittest.TestCase):
"""Base class for tests that need a mongodb connection
It ensures that the db is clean at the beginning and dropped at the end automatically
@@ -38,34 +33,39 @@ def get_as_pymongo(doc):
return doc.__class__.objects.as_pymongo().get(id=doc.id)
def get_mongodb_version():
"""Return the version of the connected mongoDB (first 2 digits)
:return: tuple(int, int)
"""
version_list = get_connection().server_info()['versionArray'][:2] # e.g: (3, 2)
return tuple(version_list)
def _decorated_with_ver_requirement(func, version):
def _decorated_with_ver_requirement(func, mongo_version_req, oper=operator.ge):
"""Return a given function decorated with the version requirement
for a particular MongoDB version tuple.
:param version: The version required (tuple(int, int))
:param mongo_version_req: The mongodb version requirement (tuple(int, int))
:param oper: The operator to apply
"""
def _inner(*args, **kwargs):
MONGODB_V = get_mongodb_version()
if MONGODB_V >= version:
mongodb_v = get_mongodb_version()
if oper(mongodb_v, mongo_version_req):
return func(*args, **kwargs)
raise SkipTest('Needs MongoDB v{}+'.format('.'.join(str(n) for n in version)))
raise SkipTest('Needs MongoDB v{}+'.format('.'.join(str(n) for n in mongo_version_req)))
_inner.__name__ = func.__name__
_inner.__doc__ = func.__doc__
return _inner
def requires_mongodb_gte_34(func):
"""Raise a SkipTest exception if we're working with MongoDB version
lower than v3.4
"""
return _decorated_with_ver_requirement(func, MONGODB_34)
def requires_mongodb_lte_32(func):
"""Raise a SkipTest exception if we're working with MongoDB version
greater than v3.2.
"""
return _decorated_with_ver_requirement(func, MONGODB_32, oper=operator.le)
def requires_mongodb_gte_26(func):
"""Raise a SkipTest exception if we're working with MongoDB version
lower than v2.6.