- Fixed tests to allow support of MongoDB 3.2
- Replaced MongoDB 2.4 tests in CI by MongoDB 3.2
This commit is contained in:
		| @@ -18,6 +18,12 @@ elif [ "$MONGODB" = "3.0" ]; then | |||||||
|     sudo apt-get update |     sudo apt-get update | ||||||
|     sudo apt-get install mongodb-org-server=3.0.14 |     sudo apt-get install mongodb-org-server=3.0.14 | ||||||
|     # service should be started automatically |     # service should be started automatically | ||||||
|  | elif [ "$MONGODB" = "3.2" ]; then | ||||||
|  |     sudo apt-key adv --keyserver keyserver.ubuntu.com --recv EA312927 | ||||||
|  |     echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list | ||||||
|  |     sudo apt-get update | ||||||
|  |     sudo apt-get install mongodb-org-server=3.2.20 | ||||||
|  |     # service should be started automatically | ||||||
| else | else | ||||||
|     echo "Invalid MongoDB version, expected 2.4, 2.6, or 3.0." |     echo "Invalid MongoDB version, expected 2.4, 2.6, or 3.0." | ||||||
|     exit 1 |     exit 1 | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -27,17 +27,17 @@ matrix: | |||||||
|  |  | ||||||
|   include: |   include: | ||||||
|   - python: 2.7 |   - python: 2.7 | ||||||
|     env: MONGODB=2.4 PYMONGO=3.5 |     env: MONGODB=3.0 PYMONGO=3.5 | ||||||
|   - python: 2.7 |   - python: 2.7 | ||||||
|     env: MONGODB=3.0 PYMONGO=3.x |     env: MONGODB=3.2 PYMONGO=3.x | ||||||
|   - python: 3.5 |   - python: 3.5 | ||||||
|     env: MONGODB=2.4 PYMONGO=3.5 |     env: MONGODB=3.0 PYMONGO=3.5 | ||||||
|   - python: 3.5 |   - python: 3.5 | ||||||
|     env: MONGODB=3.0 PYMONGO=3.x |     env: MONGODB=3.2 PYMONGO=3.x | ||||||
|   - python: 3.6 |   - python: 3.6 | ||||||
|     env: MONGODB=2.4 PYMONGO=3.5 |     env: MONGODB=3.0 PYMONGO=3.5 | ||||||
|   - python: 3.6 |   - python: 3.6 | ||||||
|     env: MONGODB=3.0 PYMONGO=3.x |     env: MONGODB=3.2 PYMONGO=3.x | ||||||
|  |  | ||||||
| before_install: | before_install: | ||||||
| - bash .install_mongodb_on_travis.sh | - bash .install_mongodb_on_travis.sh | ||||||
|   | |||||||
| @@ -26,10 +26,10 @@ an `API reference <https://mongoengine-odm.readthedocs.io/apireference.html>`_. | |||||||
|  |  | ||||||
| Supported MongoDB Versions | Supported MongoDB Versions | ||||||
| ========================== | ========================== | ||||||
| MongoEngine is currently tested against MongoDB v2.4, v2.6, and v3.0. Future | MongoEngine is currently tested against MongoDB v2.6, v3.0 and v3.2. Future | ||||||
| versions should be supported as well, but aren't actively tested at the moment. | versions should be supported as well, but aren't actively tested at the moment. | ||||||
| Make sure to open an issue or submit a pull request if you experience any | Make sure to open an issue or submit a pull request if you experience any | ||||||
| problems with MongoDB v3.2+. | problems with MongoDB v3.4+. | ||||||
|  |  | ||||||
| Installation | Installation | ||||||
| ============ | ============ | ||||||
|   | |||||||
| @@ -182,8 +182,10 @@ class query_counter(object): | |||||||
|         self._ignored_query = { |         self._ignored_query = { | ||||||
|             'ns': |             'ns': | ||||||
|                 {'$ne': '%s.system.indexes' % self.db.name}, |                 {'$ne': '%s.system.indexes' % self.db.name}, | ||||||
|             'op': |             'op':                       # MONGODB < 3.2 | ||||||
|                 {'$ne': 'killcursors'} |                 {'$ne': 'killcursors'}, | ||||||
|  |             'command.killCursors':      # MONGODB >= 3.2 | ||||||
|  |                 {'$exists': False} | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     def _turn_on_profiling(self): |     def _turn_on_profiling(self): | ||||||
|   | |||||||
| @@ -1,15 +1,14 @@ | |||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| import unittest | import unittest | ||||||
| import sys | from datetime import datetime | ||||||
|  |  | ||||||
| from nose.plugins.skip import SkipTest | from nose.plugins.skip import SkipTest | ||||||
| from datetime import datetime | from pymongo.errors import OperationFailure | ||||||
| import pymongo | import pymongo | ||||||
|  |  | ||||||
| from mongoengine import * | from mongoengine import * | ||||||
| from mongoengine.connection import get_db | from mongoengine.connection import get_db | ||||||
|  | from tests.utils import get_mongodb_version, needs_mongodb_v26, MONGODB_32, MONGODB_3 | ||||||
| from tests.utils import get_mongodb_version, needs_mongodb_v26 |  | ||||||
|  |  | ||||||
| __all__ = ("IndexesTest", ) | __all__ = ("IndexesTest", ) | ||||||
|  |  | ||||||
| @@ -19,6 +18,7 @@ class IndexesTest(unittest.TestCase): | |||||||
|     def setUp(self): |     def setUp(self): | ||||||
|         self.connection = connect(db='mongoenginetest') |         self.connection = connect(db='mongoenginetest') | ||||||
|         self.db = get_db() |         self.db = get_db() | ||||||
|  |         self.mongodb_version = get_mongodb_version() | ||||||
|  |  | ||||||
|         class Person(Document): |         class Person(Document): | ||||||
|             name = StringField() |             name = StringField() | ||||||
| @@ -491,7 +491,7 @@ class IndexesTest(unittest.TestCase): | |||||||
|         obj = Test(a=1) |         obj = Test(a=1) | ||||||
|         obj.save() |         obj.save() | ||||||
|  |  | ||||||
|         IS_MONGODB_3 = get_mongodb_version()[0] >= 3 |         IS_MONGODB_3 = get_mongodb_version() >= MONGODB_3 | ||||||
|  |  | ||||||
|         # Need to be explicit about covered indexes as mongoDB doesn't know if |         # Need to be explicit about covered indexes as mongoDB doesn't know if | ||||||
|         # the documents returned might have more keys in that here. |         # the documents returned might have more keys in that here. | ||||||
| @@ -541,19 +541,24 @@ class IndexesTest(unittest.TestCase): | |||||||
|                                  [('categories', 1), ('_id', 1)]) |                                  [('categories', 1), ('_id', 1)]) | ||||||
|  |  | ||||||
|     def test_hint(self): |     def test_hint(self): | ||||||
|  |         MONGO_VER = self.mongodb_version | ||||||
|  |  | ||||||
|  |         TAGS_INDEX_NAME = 'tags_1' | ||||||
|         class BlogPost(Document): |         class BlogPost(Document): | ||||||
|             tags = ListField(StringField()) |             tags = ListField(StringField()) | ||||||
|             meta = { |             meta = { | ||||||
|                 'indexes': [ |                 'indexes': [ | ||||||
|                     'tags', |                     { | ||||||
|  |                         'fields': ['tags'], | ||||||
|  |                         'name': TAGS_INDEX_NAME | ||||||
|  |                     } | ||||||
|                 ], |                 ], | ||||||
|             } |             } | ||||||
|  |  | ||||||
|         BlogPost.drop_collection() |         BlogPost.drop_collection() | ||||||
|  |  | ||||||
|         for i in range(0, 10): |         for i in range(10): | ||||||
|             tags = [("tag %i" % n) for n in range(0, i % 2)] |             tags = [("tag %i" % n) for n in range(i % 2)] | ||||||
|             BlogPost(tags=tags).save() |             BlogPost(tags=tags).save() | ||||||
|  |  | ||||||
|         self.assertEqual(BlogPost.objects.count(), 10) |         self.assertEqual(BlogPost.objects.count(), 10) | ||||||
| @@ -563,18 +568,18 @@ class IndexesTest(unittest.TestCase): | |||||||
|         if pymongo.version != '3.0': |         if pymongo.version != '3.0': | ||||||
|             self.assertEqual(BlogPost.objects.hint([('tags', 1)]).count(), 10) |             self.assertEqual(BlogPost.objects.hint([('tags', 1)]).count(), 10) | ||||||
|  |  | ||||||
|  |         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): | ||||||
|  |                 BlogPost.objects.hint([('ZZ', 1)]).count() | ||||||
|  |         else: | ||||||
|             self.assertEqual(BlogPost.objects.hint([('ZZ', 1)]).count(), 10) |             self.assertEqual(BlogPost.objects.hint([('ZZ', 1)]).count(), 10) | ||||||
|  |  | ||||||
|         if pymongo.version >= '2.8': |         self.assertEqual(BlogPost.objects.hint(TAGS_INDEX_NAME ).count(), 10) | ||||||
|             self.assertEqual(BlogPost.objects.hint('tags').count(), 10) |  | ||||||
|         else: |  | ||||||
|             def invalid_index(): |  | ||||||
|                 BlogPost.objects.hint('tags').next() |  | ||||||
|             self.assertRaises(TypeError, invalid_index) |  | ||||||
|  |  | ||||||
|         def invalid_index_2(): |         with self.assertRaises(Exception): | ||||||
|             return BlogPost.objects.hint(('tags', 1)).next() |             BlogPost.objects.hint(('tags', 1)).next() | ||||||
|         self.assertRaises(Exception, invalid_index_2) |  | ||||||
|  |  | ||||||
|     def test_unique(self): |     def test_unique(self): | ||||||
|         """Ensure that uniqueness constraints are applied to fields. |         """Ensure that uniqueness constraints are applied to fields. | ||||||
|   | |||||||
| @@ -21,8 +21,7 @@ from mongoengine.python_support import IS_PYMONGO_3 | |||||||
| from mongoengine.queryset import (DoesNotExist, MultipleObjectsReturned, | from mongoengine.queryset import (DoesNotExist, MultipleObjectsReturned, | ||||||
|                                   QuerySet, QuerySetManager, queryset_manager) |                                   QuerySet, QuerySetManager, queryset_manager) | ||||||
|  |  | ||||||
| from tests.utils import needs_mongodb_v26, skip_pymongo3 | from tests.utils import needs_mongodb_v26, skip_pymongo3, get_mongodb_version, MONGODB_32 | ||||||
|  |  | ||||||
|  |  | ||||||
| __all__ = ("QuerySetTest",) | __all__ = ("QuerySetTest",) | ||||||
|  |  | ||||||
| @@ -30,10 +29,8 @@ __all__ = ("QuerySetTest",) | |||||||
| class db_ops_tracker(query_counter): | class db_ops_tracker(query_counter): | ||||||
|  |  | ||||||
|     def get_ops(self): |     def get_ops(self): | ||||||
|         ignore_query = { |         ignore_query = dict(self._ignored_query) | ||||||
|             'ns': {'$ne': '%s.system.indexes' % self.db.name}, |         ignore_query['command.count'] = {'$ne': 'system.profile'}   # Ignore the query issued by query_counter | ||||||
|             'command.count': {'$ne': 'system.profile'} |  | ||||||
|         } |  | ||||||
|         return list(self.db.system.profile.find(ignore_query)) |         return list(self.db.system.profile.find(ignore_query)) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -56,6 +53,8 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         self.PersonMeta = PersonMeta |         self.PersonMeta = PersonMeta | ||||||
|         self.Person = Person |         self.Person = Person | ||||||
|  |  | ||||||
|  |         self.mongodb_version = get_mongodb_version() | ||||||
|  |  | ||||||
|     def test_initialisation(self): |     def test_initialisation(self): | ||||||
|         """Ensure that a QuerySet is correctly initialised by QuerySetManager. |         """Ensure that a QuerySet is correctly initialised by QuerySetManager. | ||||||
|         """ |         """ | ||||||
| @@ -813,8 +812,8 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         self.assertEqual(record.embed.field, 2) |         self.assertEqual(record.embed.field, 2) | ||||||
|  |  | ||||||
|     def test_bulk_insert(self): |     def test_bulk_insert(self): | ||||||
|         """Ensure that bulk insert works |         """Ensure that bulk insert works""" | ||||||
|         """ |         MONGO_VER = self.mongodb_version | ||||||
|  |  | ||||||
|         class Comment(EmbeddedDocument): |         class Comment(EmbeddedDocument): | ||||||
|             name = StringField() |             name = StringField() | ||||||
| @@ -832,35 +831,41 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         # get MongoDB version info |         # get MongoDB version info | ||||||
|         connection = get_connection() |         connection = get_connection() | ||||||
|         info = connection.test.command('buildInfo') |         info = connection.test.command('buildInfo') | ||||||
|         mongodb_version = tuple([int(i) for i in info['version'].split('.')]) |  | ||||||
|  |  | ||||||
|         # Recreates the collection |         # Recreates the collection | ||||||
|         self.assertEqual(0, Blog.objects.count()) |         self.assertEqual(0, Blog.objects.count()) | ||||||
|  |  | ||||||
|         with query_counter() as q: |  | ||||||
|             self.assertEqual(q, 0) |  | ||||||
|  |  | ||||||
|         comment1 = Comment(name='testa') |         comment1 = Comment(name='testa') | ||||||
|         comment2 = Comment(name='testb') |         comment2 = Comment(name='testb') | ||||||
|         post1 = Post(comments=[comment1, comment2]) |         post1 = Post(comments=[comment1, comment2]) | ||||||
|         post2 = Post(comments=[comment2, comment2]) |         post2 = Post(comments=[comment2, comment2]) | ||||||
|  |         blogs = [Blog(title="post %s" % i, posts=[post1, post2]) | ||||||
|  |                  for i in range(99)] | ||||||
|  |  | ||||||
|             blogs = [] |         # Check bulk insert using load_bulk=False | ||||||
|             for i in range(1, 100): |         with query_counter() as q: | ||||||
|                 blogs.append(Blog(title="post %s" % i, posts=[post1, post2])) |             self.assertEqual(q, 0) | ||||||
|  |  | ||||||
|             Blog.objects.insert(blogs, load_bulk=False) |             Blog.objects.insert(blogs, load_bulk=False) | ||||||
|             # profiling logs each doc now in the bulk op |  | ||||||
|             self.assertEqual(q, 99) |             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 | ||||||
|  |  | ||||||
|  |         self.assertEqual(Blog.objects.count(), len(blogs)) | ||||||
|  |  | ||||||
|         Blog.drop_collection() |         Blog.drop_collection() | ||||||
|         Blog.ensure_indexes() |         Blog.ensure_indexes() | ||||||
|  |  | ||||||
|  |         # Check bulk insert using load_bulk=True | ||||||
|         with query_counter() as q: |         with query_counter() as q: | ||||||
|             self.assertEqual(q, 0) |             self.assertEqual(q, 0) | ||||||
|  |  | ||||||
|             Blog.objects.insert(blogs) |             Blog.objects.insert(blogs) | ||||||
|             self.assertEqual(q, 100) # 99 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 | ||||||
|  |  | ||||||
|         Blog.drop_collection() |         Blog.drop_collection() | ||||||
|  |  | ||||||
| @@ -1262,6 +1267,9 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         """Ensure that the default ordering can be cleared by calling |         """Ensure that the default ordering can be cleared by calling | ||||||
|         order_by() w/o any arguments. |         order_by() w/o any arguments. | ||||||
|         """ |         """ | ||||||
|  |         MONGO_VER = self.mongodb_version | ||||||
|  |         ORDER_BY_KEY = 'sort' if MONGO_VER == MONGODB_32 else '$orderby' | ||||||
|  |  | ||||||
|         class BlogPost(Document): |         class BlogPost(Document): | ||||||
|             title = StringField() |             title = StringField() | ||||||
|             published_date = DateTimeField() |             published_date = DateTimeField() | ||||||
| @@ -1277,7 +1285,7 @@ class QuerySetTest(unittest.TestCase): | |||||||
|             BlogPost.objects.filter(title='whatever').first() |             BlogPost.objects.filter(title='whatever').first() | ||||||
|             self.assertEqual(len(q.get_ops()), 1) |             self.assertEqual(len(q.get_ops()), 1) | ||||||
|             self.assertEqual( |             self.assertEqual( | ||||||
|                 q.get_ops()[0]['query']['$orderby'], |                 q.get_ops()[0]['query'][ORDER_BY_KEY], | ||||||
|                 {'published_date': -1} |                 {'published_date': -1} | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
| @@ -1285,14 +1293,14 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         with db_ops_tracker() as q: |         with db_ops_tracker() as q: | ||||||
|             BlogPost.objects.filter(title='whatever').order_by().first() |             BlogPost.objects.filter(title='whatever').order_by().first() | ||||||
|             self.assertEqual(len(q.get_ops()), 1) |             self.assertEqual(len(q.get_ops()), 1) | ||||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) |             self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) | ||||||
|  |  | ||||||
|         # calling an explicit order_by should use a specified sort |         # calling an explicit order_by should use a specified sort | ||||||
|         with db_ops_tracker() as q: |         with db_ops_tracker() as q: | ||||||
|             BlogPost.objects.filter(title='whatever').order_by('published_date').first() |             BlogPost.objects.filter(title='whatever').order_by('published_date').first() | ||||||
|             self.assertEqual(len(q.get_ops()), 1) |             self.assertEqual(len(q.get_ops()), 1) | ||||||
|             self.assertEqual( |             self.assertEqual( | ||||||
|                 q.get_ops()[0]['query']['$orderby'], |                 q.get_ops()[0]['query'][ORDER_BY_KEY], | ||||||
|                 {'published_date': 1} |                 {'published_date': 1} | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
| @@ -1301,11 +1309,14 @@ class QuerySetTest(unittest.TestCase): | |||||||
|             qs = BlogPost.objects.filter(title='whatever').order_by('published_date') |             qs = BlogPost.objects.filter(title='whatever').order_by('published_date') | ||||||
|             qs.order_by().first() |             qs.order_by().first() | ||||||
|             self.assertEqual(len(q.get_ops()), 1) |             self.assertEqual(len(q.get_ops()), 1) | ||||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) |             self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) | ||||||
|  |  | ||||||
|     def test_no_ordering_for_get(self): |     def test_no_ordering_for_get(self): | ||||||
|         """ Ensure that Doc.objects.get doesn't use any ordering. |         """ Ensure that Doc.objects.get doesn't use any ordering. | ||||||
|         """ |         """ | ||||||
|  |         MONGO_VER = self.mongodb_version | ||||||
|  |         ORDER_BY_KEY = 'sort' if MONGO_VER == MONGODB_32 else '$orderby' | ||||||
|  |  | ||||||
|         class BlogPost(Document): |         class BlogPost(Document): | ||||||
|             title = StringField() |             title = StringField() | ||||||
|             published_date = DateTimeField() |             published_date = DateTimeField() | ||||||
| @@ -1320,13 +1331,13 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         with db_ops_tracker() as q: |         with db_ops_tracker() as q: | ||||||
|             BlogPost.objects.get(title='whatever') |             BlogPost.objects.get(title='whatever') | ||||||
|             self.assertEqual(len(q.get_ops()), 1) |             self.assertEqual(len(q.get_ops()), 1) | ||||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) |             self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) | ||||||
|  |  | ||||||
|         # Ordering should be ignored for .get even if we set it explicitly |         # Ordering should be ignored for .get even if we set it explicitly | ||||||
|         with db_ops_tracker() as q: |         with db_ops_tracker() as q: | ||||||
|             BlogPost.objects.order_by('-title').get(title='whatever') |             BlogPost.objects.order_by('-title').get(title='whatever') | ||||||
|             self.assertEqual(len(q.get_ops()), 1) |             self.assertEqual(len(q.get_ops()), 1) | ||||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) |             self.assertNotIn(ORDER_BY_KEY, q.get_ops()[0]['query']) | ||||||
|  |  | ||||||
|     def test_find_embedded(self): |     def test_find_embedded(self): | ||||||
|         """Ensure that an embedded document is properly returned from |         """Ensure that an embedded document is properly returned from | ||||||
| @@ -2450,7 +2461,11 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         self.assertEqual(names, ['User A', 'User B', 'User C']) |         self.assertEqual(names, ['User A', 'User B', 'User C']) | ||||||
|  |  | ||||||
|     def test_comment(self): |     def test_comment(self): | ||||||
|         """Make sure adding a comment to the query works.""" |         """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' | ||||||
|  |  | ||||||
|         class User(Document): |         class User(Document): | ||||||
|             age = IntField() |             age = IntField() | ||||||
|  |  | ||||||
| @@ -2466,8 +2481,8 @@ class QuerySetTest(unittest.TestCase): | |||||||
|             ops = q.get_ops() |             ops = q.get_ops() | ||||||
|             self.assertEqual(len(ops), 2) |             self.assertEqual(len(ops), 2) | ||||||
|             for op in ops: |             for op in ops: | ||||||
|                 self.assertEqual(op['query']['$query'], {'age': {'$gte': 18}}) |                 self.assertEqual(op['query'][QUERY_KEY], {'age': {'$gte': 18}}) | ||||||
|                 self.assertEqual(op['query']['$comment'], 'looking for an adult') |                 self.assertEqual(op['query'][COMMENT_KEY], 'looking for an adult') | ||||||
|  |  | ||||||
|     def test_map_reduce(self): |     def test_map_reduce(self): | ||||||
|         """Ensure map/reduce is both mapping and reducing. |         """Ensure map/reduce is both mapping and reducing. | ||||||
| @@ -4818,7 +4833,6 @@ class QuerySetTest(unittest.TestCase): | |||||||
|             Person(name="No: %s" % i).save() |             Person(name="No: %s" % i).save() | ||||||
|  |  | ||||||
|         with query_counter() as q: |         with query_counter() as q: | ||||||
|                 try: |  | ||||||
|             self.assertEqual(q, 0) |             self.assertEqual(q, 0) | ||||||
|             people = Person.objects.no_cache() |             people = Person.objects.no_cache() | ||||||
|  |  | ||||||
| @@ -4830,14 +4844,6 @@ class QuerySetTest(unittest.TestCase): | |||||||
|  |  | ||||||
|             people.count() |             people.count() | ||||||
|             self.assertEqual(q, 3) |             self.assertEqual(q, 3) | ||||||
|                 except AssertionError as exc: |  | ||||||
|                     db = get_db() |  | ||||||
|                     msg = '' |  | ||||||
|                     for q in list(db.system.profile.find())[-50:]: |  | ||||||
|                         msg += str([q['ts'], q['ns'], q.get('query'), q['op']])+'\n' |  | ||||||
|                         msg += str(q) |  | ||||||
|                     raise AssertionError(str(exc) + '\n'+msg) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     def test_cache_not_cloned(self): |     def test_cache_not_cloned(self): | ||||||
|  |  | ||||||
| @@ -5111,35 +5117,39 @@ class QuerySetTest(unittest.TestCase): | |||||||
|             self.assertEqual(op['nreturned'], 1) |             self.assertEqual(op['nreturned'], 1) | ||||||
|  |  | ||||||
|     def test_bool_with_ordering(self): |     def test_bool_with_ordering(self): | ||||||
|  |         MONGO_VER = self.mongodb_version | ||||||
|  |         ORDER_BY_KEY = 'sort' if MONGO_VER == MONGODB_32 else '$orderby' | ||||||
|  |  | ||||||
|         class Person(Document): |         class Person(Document): | ||||||
|             name = StringField() |             name = StringField() | ||||||
|  |  | ||||||
|         Person.drop_collection() |         Person.drop_collection() | ||||||
|  |  | ||||||
|         Person(name="Test").save() |         Person(name="Test").save() | ||||||
|  |  | ||||||
|  |         # Check that bool(queryset) does not uses the orderby | ||||||
|         qs = Person.objects.order_by('name') |         qs = Person.objects.order_by('name') | ||||||
|  |  | ||||||
|         with query_counter() as q: |         with query_counter() as q: | ||||||
|  |  | ||||||
|             if qs: |             if bool(qs): | ||||||
|                 pass |                 pass | ||||||
|  |  | ||||||
|             op = q.db.system.profile.find({"ns": |             op = q.db.system.profile.find({"ns": | ||||||
|                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] |                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] | ||||||
|  |  | ||||||
|             self.assertNotIn('$orderby', op['query'], |             self.assertNotIn(ORDER_BY_KEY, op['query']) | ||||||
|                              'BaseQuerySet cannot use orderby in if stmt') |  | ||||||
|  |  | ||||||
|  |         # Check that normal query uses orderby | ||||||
|  |         qs2 = Person.objects.order_by('name') | ||||||
|         with query_counter() as p: |         with query_counter() as p: | ||||||
|  |  | ||||||
|             for x in qs: |             for x in qs2: | ||||||
|                 pass |                 pass | ||||||
|  |  | ||||||
|             op = p.db.system.profile.find({"ns": |             op = p.db.system.profile.find({"ns": | ||||||
|                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] |                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] | ||||||
|  |  | ||||||
|             self.assertIn('$orderby', op['query'], 'BaseQuerySet cannot remove orderby in for loop') |             self.assertIn(ORDER_BY_KEY, op['query']) | ||||||
|  |  | ||||||
|     def test_bool_with_ordering_from_meta_dict(self): |     def test_bool_with_ordering_from_meta_dict(self): | ||||||
|  |  | ||||||
|   | |||||||
| @@ -299,7 +299,6 @@ class ContextManagersTest(unittest.TestCase): | |||||||
|  |  | ||||||
|             cursor.close()              # issues a `killcursors` query that is ignored by the context |             cursor.close()              # issues a `killcursors` query that is ignored by the context | ||||||
|             self.assertEqual(q, 1) |             self.assertEqual(q, 1) | ||||||
|  |  | ||||||
|             _ = db.system.indexes.find_one()    # queries on db.system.indexes are ignored as well |             _ = db.system.indexes.find_one()    # queries on db.system.indexes are ignored as well | ||||||
|             self.assertEqual(q, 1) |             self.assertEqual(q, 1) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,6 +10,13 @@ from mongoengine.python_support import IS_PYMONGO_3 | |||||||
| MONGO_TEST_DB = 'mongoenginetest'   # standard name for the test database | 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): | class MongoDBTestCase(unittest.TestCase): | ||||||
|     """Base class for tests that need a mongodb connection |     """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 |     It ensures that the db is clean at the beginning and dropped at the end automatically | ||||||
| @@ -27,24 +34,26 @@ class MongoDBTestCase(unittest.TestCase): | |||||||
|  |  | ||||||
|  |  | ||||||
| def get_mongodb_version(): | def get_mongodb_version(): | ||||||
|     """Return the version tuple of the MongoDB server that the default |     """Return the version of the connected mongoDB (first 2 digits) | ||||||
|     connection is connected to. |  | ||||||
|  |     :return: tuple(int, int) | ||||||
|     """ |     """ | ||||||
|     return tuple(get_connection().server_info()['versionArray']) |     version_list = get_connection().server_info()['versionArray'][:2]     # e.g: (3, 2) | ||||||
|  |     return tuple(version_list) | ||||||
|  |  | ||||||
|  |  | ||||||
| def _decorated_with_ver_requirement(func, ver_tuple): | def _decorated_with_ver_requirement(func, version): | ||||||
|     """Return a given function decorated with the version requirement |     """Return a given function decorated with the version requirement | ||||||
|     for a particular MongoDB version tuple. |     for a particular MongoDB version tuple. | ||||||
|  |  | ||||||
|  |     :param version: The version required (tuple(int, int)) | ||||||
|     """ |     """ | ||||||
|     def _inner(*args, **kwargs): |     def _inner(*args, **kwargs): | ||||||
|         mongodb_ver = get_mongodb_version() |         MONGODB_V = get_mongodb_version() | ||||||
|         if mongodb_ver >= ver_tuple: |         if MONGODB_V >= version: | ||||||
|             return func(*args, **kwargs) |             return func(*args, **kwargs) | ||||||
|  |  | ||||||
|         raise SkipTest('Needs MongoDB v{}+'.format( |         raise SkipTest('Needs MongoDB v{}+'.format('.'.join(str(n) for n in version))) | ||||||
|             '.'.join([str(v) for v in ver_tuple]) |  | ||||||
|         )) |  | ||||||
|  |  | ||||||
|     _inner.__name__ = func.__name__ |     _inner.__name__ = func.__name__ | ||||||
|     _inner.__doc__ = func.__doc__ |     _inner.__doc__ = func.__doc__ | ||||||
| @@ -56,14 +65,14 @@ def needs_mongodb_v26(func): | |||||||
|     """Raise a SkipTest exception if we're working with MongoDB version |     """Raise a SkipTest exception if we're working with MongoDB version | ||||||
|     lower than v2.6. |     lower than v2.6. | ||||||
|     """ |     """ | ||||||
|     return _decorated_with_ver_requirement(func, (2, 6)) |     return _decorated_with_ver_requirement(func, MONGODB_26) | ||||||
|  |  | ||||||
|  |  | ||||||
| def needs_mongodb_v3(func): | def needs_mongodb_v3(func): | ||||||
|     """Raise a SkipTest exception if we're working with MongoDB version |     """Raise a SkipTest exception if we're working with MongoDB version | ||||||
|     lower than v3.0. |     lower than v3.0. | ||||||
|     """ |     """ | ||||||
|     return _decorated_with_ver_requirement(func, (3, 0)) |     return _decorated_with_ver_requirement(func, MONGODB_3) | ||||||
|  |  | ||||||
|  |  | ||||||
| def skip_pymongo3(f): | def skip_pymongo3(f): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user