From 4334955e39781e273c26293833478f4e400a0170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20W=C3=B3jcik?= Date: Fri, 31 May 2019 11:01:15 +0200 Subject: [PATCH] Update the test matrix to reflect what's supported in 2019 (#2066) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we were running the test suite for several combinations of MongoDB, Python, and PyMongo: - PyPy, MongoDB v2.6, PyMongo v3.x (which really means v3.6.1 at the moment) - Python v2.7, MongoDB v2.6, PyMongo v3.x - Python v3.5, MongoDB v2.6, PyMongo v3.x - Python v3.6, MongoDB v2.6, PyMongo v3.x - Python v2.7, MongoDB v3.0, PyMongo v3.5.0 - Python v3.6, MongoDB v3.0, PyMongo v3.5.0 - Python v3.5, MongoDB v3.2, PyMongo v3.x - Python v3.6, MongoDB v3.2, PyMongo v3.x - Python v3.6, MongoDB v3.4, PyMongo v3.x - Python v3.6, MongoDB v3.6, PyMongo v3.x There were a couple issues with this setup: 1. MongoDB v2.6 – v3.2 have reached their End of Life already (v2.6 almost 3 years ago!). See the "MongoDB Server" section on https://www.mongodb.com/support-policy. 2. We were only testing two recent-ish PyMongo versions (v3.5.0 & v3.6.1). We were not testing the oldest actively supported MongoDB/PyMongo/Python setup. This PR updates the test matrix so that these problems are solved. For the sake of simplicity, it does not yet attempt to cover MongoDB v4.0: - PyPy, MongoDB v3.4, PyMongo v3.x (aka v3.6.1 at the moment) - Python v2.7, MongoDB v3.4, PyMongo v3.x - Python v3.5, MongoDB v3.4, PyMongo v3.x - Python v3.6, MongoDB v3.4, PyMongo v3.x - Python v2.7, MongoDB v3.4, PyMongo v3.4 - Python v3.6, MongoDB v3.6, PyMongo v3.x --- .travis.yml | 41 ++++++++------- README.rst | 8 +-- mongoengine/connection.py | 18 +++++-- mongoengine/mongodb_support.py | 4 -- requirements.txt | 2 +- setup.py | 2 +- tests/document/class_methods.py | 2 - tests/document/indexes.py | 89 +++++++++++++++------------------ tests/document/instance.py | 4 -- tests/queryset/geo.py | 10 +--- tests/queryset/modify.py | 3 -- tests/queryset/queryset.py | 35 +++---------- tests/utils.py | 46 ++++++----------- tox.ini | 2 +- 14 files changed, 105 insertions(+), 161 deletions(-) diff --git a/.travis.yml b/.travis.yml index 909183c1..3186ea1c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,18 @@ # PyMongo combinations. However, that would result in an overly long build # with a very large number of jobs, hence we only test a subset of all the # combinations: -# * MongoDB v2.6 is currently the "main" version tested against Python v2.7, -# v3.5, v3.6, PyPy, and PyMongo v3.x. -# * MongoDB v3.0 & v3.2 are tested against Python v2.7, v3.5 & v3.6 -# and Pymongo v3.5 & v3.x -# * MongoDB v3.4 is tested against v3.6 and Pymongo v3.x +# * MongoDB v3.4 & the latest PyMongo v3.x is currently the "main" setup, +# tested against Python v2.7, v3.5, v3.6, and PyPy. +# * Besides that, we test the lowest actively supported Python/MongoDB/PyMongo +# combination: MongoDB v3.4, PyMongo v3.4, Python v2.7. +# * MongoDB v3.6 is tested against Python v3.6, and PyMongo v3.6, v3.7, v3.8. +# +# We should periodically check MongoDB Server versions supported by MongoDB +# Inc., add newly released versions to the test matrix, and remove versions +# which have reached their End of Life. See: +# 1. https://www.mongodb.com/support-policy. +# 2. https://docs.mongodb.com/ecosystem/drivers/driver-compatibility-reference/#python-driver-compatibility +# # Reminder: Update README.rst if you change MongoDB versions we test. language: python @@ -18,7 +25,7 @@ python: - pypy env: -- MONGODB=2.6 PYMONGO=3.x +- MONGODB=3.4 PYMONGO=3.x matrix: # Finish the build as soon as one job fails @@ -26,15 +33,7 @@ matrix: include: - python: 2.7 - env: MONGODB=3.0 PYMONGO=3.5 - - python: 3.5 - env: MONGODB=3.2 PYMONGO=3.x - - python: 3.6 - env: MONGODB=3.0 PYMONGO=3.5 - - python: 3.6 - env: MONGODB=3.2 PYMONGO=3.x - - python: 3.6 - env: MONGODB=3.4 PYMONGO=3.x + env: MONGODB=3.4 PYMONGO=3.4.x - python: 3.6 env: MONGODB=3.6 PYMONGO=3.x @@ -86,15 +85,15 @@ deploy: password: secure: QMyatmWBnC6ZN3XLW2+fTBDU4LQcp1m/LjR2/0uamyeUzWKdlOoh/Wx5elOgLwt/8N9ppdPeG83ose1jOz69l5G0MUMjv8n/RIcMFSpCT59tGYqn3kh55b0cIZXFT9ar+5cxlif6a5rS72IHm5li7QQyxexJIII6Uxp0kpvUmek= - # create a source distribution and a pure python wheel for faster installs + # Create a source distribution and a pure python wheel for faster installs. distributions: "sdist bdist_wheel" - # only deploy on tagged commits (aka GitHub releases) and only for the - # parent repo's builds running Python 2.7 along with PyMongo v3.x (we run - # Travis against many different Python and PyMongo versions and we don't - # want the deploy to occur multiple times). + # Only deploy on tagged commits (aka GitHub releases) and only for the parent + # repo's builds running Python v2.7 along with PyMongo v3.x and MongoDB v3.4. + # We run Travis against many different Python, PyMongo, and MongoDB versions + # and we don't want the deploy to occur multiple times). on: tags: true repo: MongoEngine/mongoengine - condition: "$PYMONGO = 3.x" + condition: ($PYMONGO = 3.x) AND ($MONGODB = 3.4) python: 2.7 diff --git a/README.rst b/README.rst index cb279d2c..fe5f5f22 100644 --- a/README.rst +++ b/README.rst @@ -26,10 +26,10 @@ an `API reference `_. Supported MongoDB Versions ========================== -MongoEngine is currently tested against MongoDB v2.6, v3.0, v3.2, v3.4 and v3.6. Future -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 -problems with MongoDB v3.6+. +MongoEngine is currently tested against MongoDB v3.4 and v3.6. Future 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 problems +with MongoDB version > 3.6. Installation ============ diff --git a/mongoengine/connection.py b/mongoengine/connection.py index e12980e6..e0399fde 100644 --- a/mongoengine/connection.py +++ b/mongoengine/connection.py @@ -117,10 +117,22 @@ def _get_connection_settings( ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, - ReadPreference.SECONDARY_PREFERRED) - read_pf_mode = uri_options['readpreference'].lower() + ReadPreference.SECONDARY_PREFERRED, + ) + + # Starting with PyMongo v3.5, the "readpreference" option is + # returned as a string (e.g. "secondaryPreferred") and not an + # int (e.g. 3). + # TODO simplify the code below once we drop support for + # PyMongo v3.4. + read_pf_mode = uri_options['readpreference'] + if isinstance(read_pf_mode, six.string_types): + read_pf_mode = read_pf_mode.lower() for preference in read_preferences: - if preference.name.lower() == read_pf_mode: + if ( + preference.name.lower() == read_pf_mode or + preference.mode == read_pf_mode + ): conn_settings['read_preference'] = preference break else: diff --git a/mongoengine/mongodb_support.py b/mongoengine/mongodb_support.py index 8e414075..8234a616 100644 --- a/mongoengine/mongodb_support.py +++ b/mongoengine/mongodb_support.py @@ -7,10 +7,6 @@ from mongoengine.connection import get_connection # Constant that can be used to compare the version retrieved with # get_mongodb_version() MONGODB_36 = (3, 6) -MONGODB_34 = (3, 4) -MONGODB_32 = (3, 2) -MONGODB_3 = (3, 0) -MONGODB_26 = (2, 6) def get_mongodb_version(): diff --git a/requirements.txt b/requirements.txt index 38e0b20f..9bb319a5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ nose -pymongo>=3.5 +pymongo>=3.4 six==1.10.0 flake8 flake8-import-order diff --git a/setup.py b/setup.py index c8e9c038..f1f5dea7 100644 --- a/setup.py +++ b/setup.py @@ -80,7 +80,7 @@ setup( long_description=LONG_DESCRIPTION, platforms=['any'], classifiers=CLASSIFIERS, - install_requires=['pymongo>=3.5', 'six'], + install_requires=['pymongo>=3.4', 'six'], test_suite='nose.collector', **extra_opts ) diff --git a/tests/document/class_methods.py b/tests/document/class_methods.py index 421618e4..4fc648b7 100644 --- a/tests/document/class_methods.py +++ b/tests/document/class_methods.py @@ -6,7 +6,6 @@ from mongoengine.pymongo_support import list_collection_names from mongoengine.queryset import NULLIFY, PULL from mongoengine.connection import get_db -from tests.utils import requires_mongodb_gte_26 __all__ = ("ClassMethodsTest", ) @@ -187,7 +186,6 @@ class ClassMethodsTest(unittest.TestCase): self.assertEqual(BlogPostWithTags.compare_indexes(), {'missing': [], 'extra': []}) self.assertEqual(BlogPostWithCustomField.compare_indexes(), {'missing': [], 'extra': []}) - @requires_mongodb_gte_26 def test_compare_indexes_for_text_indexes(self): """ Ensure that compare_indexes behaves correctly for text indexes """ diff --git a/tests/document/indexes.py b/tests/document/indexes.py index 34771e8a..6f486e9f 100644 --- a/tests/document/indexes.py +++ b/tests/document/indexes.py @@ -9,8 +9,7 @@ from six import iteritems from mongoengine import * from mongoengine.connection import get_db -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 +from mongoengine.mongodb_support import get_mongodb_version __all__ = ("IndexesTest", ) @@ -478,8 +477,6 @@ 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() b = IntField() @@ -497,33 +494,38 @@ class IndexesTest(unittest.TestCase): # 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() - if not IS_MONGODB_3: - self.assertFalse(query_plan['indexOnly']) - else: - self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IDHACK') + self.assertEqual( + query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), + 'IDHACK' + ) query_plan = Test.objects(id=obj.id).only('id').explain() - if not IS_MONGODB_3: - self.assertTrue(query_plan['indexOnly']) - else: - self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IDHACK') + self.assertEqual( + query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), + 'IDHACK' + ) query_plan = Test.objects(a=1).only('a').exclude('id').explain() - if not IS_MONGODB_3: - self.assertTrue(query_plan['indexOnly']) - else: - self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IXSCAN') - self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('stage'), 'PROJECTION') + self.assertEqual( + query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), + 'IXSCAN' + ) + self.assertEqual( + query_plan.get('queryPlanner').get('winningPlan').get('stage'), + 'PROJECTION' + ) query_plan = Test.objects(a=1).explain() - if not IS_MONGODB_3: - self.assertFalse(query_plan['indexOnly']) - else: - self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), 'IXSCAN') - self.assertEqual(query_plan.get('queryPlanner').get('winningPlan').get('stage'), 'FETCH') + self.assertEqual( + query_plan.get('queryPlanner').get('winningPlan').get('inputStage').get('stage'), + 'IXSCAN' + ) + self.assertEqual( + query_plan.get('queryPlanner').get('winningPlan').get('stage'), + 'FETCH' + ) def test_index_on_id(self): - class BlogPost(Document): meta = { 'indexes': [ @@ -565,13 +567,10 @@ class IndexesTest(unittest.TestCase): self.assertEqual(BlogPost.objects.count(), 10) self.assertEqual(BlogPost.objects.hint().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) + # MongoDB v3.2+ 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() self.assertEqual(BlogPost.objects.hint(TAGS_INDEX_NAME).count(), 10) @@ -598,9 +597,8 @@ class IndexesTest(unittest.TestCase): # Ensure backwards compatibility for errors self.assertRaises(OperationError, post2.save) - @requires_mongodb_gte_34 - def test_primary_key_unique_not_working_under_mongo_34(self): - """Relates to #1445""" + def test_primary_key_unique_not_working(self): + """Relates to #1445""" class Blog(Document): id = StringField(primary_key=True, unique=True) @@ -608,21 +606,17 @@ class IndexesTest(unittest.TestCase): with self.assertRaises(OperationFailure) as ctx_err: Blog(id='garbage').save() - try: - self.assertIn("The field 'unique' is not valid for an _id index specification", str(ctx_err.exception)) - except AssertionError: - # error is slightly different on python 3.6 - self.assertIn("The field 'background' 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): - """Relates to #1445""" - class Blog(Document): - id = StringField(primary_key=True, unique=True) - - Blog.drop_collection() - - Blog(id='garbage').save() + # One of the errors below should happen. Which one depends on the + # PyMongo version and dict order. + err_msg = str(ctx_err.exception) + self.assertTrue( + any([ + "The field 'unique' is not valid for an _id index specification" in err_msg, + "The field 'background' is not valid for an _id index specification" in err_msg, + "The field 'sparse' is not valid for an _id index specification" in err_msg, + ]) + ) def test_unique_with(self): """Ensure that unique_with constraints are applied to fields. @@ -984,7 +978,6 @@ class IndexesTest(unittest.TestCase): info['provider_ids.foo_1_provider_ids.bar_1']['key']) self.assertTrue(info['provider_ids.foo_1_provider_ids.bar_1']['sparse']) - @requires_mongodb_gte_26 def test_text_indexes(self): class Book(Document): title = DictField() diff --git a/tests/document/instance.py b/tests/document/instance.py index 5746f1fc..cec019a9 100644 --- a/tests/document/instance.py +++ b/tests/document/instance.py @@ -28,8 +28,6 @@ from mongoengine.queryset import NULLIFY, Q from mongoengine.context_managers import switch_db, query_counter from mongoengine import signals -from tests.utils import requires_mongodb_gte_26 - TEST_IMAGE_PATH = os.path.join(os.path.dirname(__file__), '../fields/mongoengine.png') @@ -850,7 +848,6 @@ class InstanceTest(MongoDBTestCase): self.assertDbEqual([dict(other_doc.to_mongo()), dict(doc.to_mongo())]) - @requires_mongodb_gte_26 def test_modify_with_positional_push(self): class Content(EmbeddedDocument): keywords = ListField(StringField()) @@ -3368,7 +3365,6 @@ class InstanceTest(MongoDBTestCase): person.update(set__height=2.0) - @requires_mongodb_gte_26 def test_push_with_position(self): """Ensure that push with position works properly for an instance.""" class BlogPost(Document): diff --git a/tests/queryset/geo.py b/tests/queryset/geo.py index 240a94ab..45e6a089 100644 --- a/tests/queryset/geo.py +++ b/tests/queryset/geo.py @@ -3,7 +3,7 @@ import unittest from mongoengine import * -from tests.utils import MongoDBTestCase, requires_mongodb_gte_3 +from tests.utils import MongoDBTestCase __all__ = ("GeoQueriesTest",) @@ -70,9 +70,6 @@ class GeoQueriesTest(MongoDBTestCase): self.assertEqual(events.count(), 1) self.assertEqual(events[0], event2) - # $minDistance was added in MongoDB v2.6, but continued being buggy - # until v3.0; skip for older versions - @requires_mongodb_gte_3 def test_near_and_min_distance(self): """Ensure the "min_distance" operator works alongside the "near" operator. @@ -243,9 +240,6 @@ class GeoQueriesTest(MongoDBTestCase): events = self.Event.objects(location__geo_within_polygon=polygon2) self.assertEqual(events.count(), 0) - # $minDistance was added in MongoDB v2.6, but continued being buggy - # until v3.0; skip for older versions - @requires_mongodb_gte_3 def test_2dsphere_near_and_min_max_distance(self): """Ensure "min_distace" and "max_distance" operators work well together with the "near" operator in a 2dsphere index. @@ -328,8 +322,6 @@ class GeoQueriesTest(MongoDBTestCase): """Make sure PointField works properly in an embedded document.""" self._test_embedded(point_field_class=PointField) - # Needs MongoDB > 2.6.4 https://jira.mongodb.org/browse/SERVER-14039 - @requires_mongodb_gte_3 def test_spherical_geospatial_operators(self): """Ensure that spherical geospatial queries are working.""" class Point(Document): diff --git a/tests/queryset/modify.py b/tests/queryset/modify.py index 4b7c3da2..3c5879ba 100644 --- a/tests/queryset/modify.py +++ b/tests/queryset/modify.py @@ -2,8 +2,6 @@ import unittest from mongoengine import connect, Document, IntField, StringField, ListField -from tests.utils import requires_mongodb_gte_26 - __all__ = ("FindAndModifyTest",) @@ -96,7 +94,6 @@ class FindAndModifyTest(unittest.TestCase): self.assertEqual(old_doc.to_mongo(), {"_id": 1}) self.assertDbEqual([{"_id": 0, "value": 0}, {"_id": 1, "value": -1}]) - @requires_mongodb_gte_26 def test_modify_with_push(self): class BlogPost(Document): tags = ListField(StringField()) diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py index 51da663a..04cfb061 100644 --- a/tests/queryset/queryset.py +++ b/tests/queryset/queryset.py @@ -17,10 +17,9 @@ 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, MONGODB_36 +from mongoengine.mongodb_support import get_mongodb_version, MONGODB_36 from mongoengine.queryset import (DoesNotExist, MultipleObjectsReturned, QuerySet, QuerySetManager, queryset_manager) -from tests.utils import requires_mongodb_gte_26 class db_ops_tracker(query_counter): @@ -32,7 +31,7 @@ class db_ops_tracker(query_counter): def get_key_compat(mongo_ver): - ORDER_BY_KEY = 'sort' if mongo_ver >= MONGODB_32 else '$orderby' + ORDER_BY_KEY = 'sort' CMD_QUERY_KEY = 'command' if mongo_ver >= MONGODB_36 else 'query' return ORDER_BY_KEY, CMD_QUERY_KEY @@ -598,7 +597,6 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(post.comments[0].by, 'joe') self.assertEqual(post.comments[0].votes.score, 4) - @requires_mongodb_gte_26 def test_update_min_max(self): class Scores(Document): high_score = IntField() @@ -616,7 +614,6 @@ class QuerySetTest(unittest.TestCase): Scores.objects(id=scores.id).update(max__high_score=500) self.assertEqual(Scores.objects.get(id=scores.id).high_score, 1000) - @requires_mongodb_gte_26 def test_update_multiple(self): class Product(Document): item = StringField() @@ -868,11 +865,7 @@ class QuerySetTest(unittest.TestCase): with query_counter() as q: 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 - else: - self.assertEqual(q, len(blogs)) # 1 entry per doc inserted + self.assertEqual(q, 1) # 1 entry containing the list of inserts self.assertEqual(Blog.objects.count(), len(blogs)) @@ -885,11 +878,7 @@ class QuerySetTest(unittest.TestCase): with query_counter() as q: self.assertEqual(q, 0) Blog.objects.insert(blogs) - - 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 + self.assertEqual(q, 2) # 1 for insert 1 for fetch Blog.drop_collection() @@ -2030,7 +2019,6 @@ class QuerySetTest(unittest.TestCase): pymongo_doc = BlogPost.objects.as_pymongo().first() self.assertNotIn('title', pymongo_doc) - @requires_mongodb_gte_26 def test_update_push_with_position(self): """Ensure that the 'push' update with position works properly. """ @@ -2555,8 +2543,8 @@ class QuerySetTest(unittest.TestCase): """Make sure adding a comment to the query gets added to the query""" MONGO_VER = self.mongodb_version _, CMD_QUERY_KEY = get_key_compat(MONGO_VER) - QUERY_KEY = 'filter' if MONGO_VER >= MONGODB_32 else '$query' - COMMENT_KEY = 'comment' if MONGO_VER >= MONGODB_32 else '$comment' + QUERY_KEY = 'filter' + COMMENT_KEY = 'comment' class User(Document): age = IntField() @@ -3370,7 +3358,6 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(Foo.objects.distinct("bar"), [bar]) - @requires_mongodb_gte_26 def test_text_indexes(self): class News(Document): title = StringField() @@ -3454,7 +3441,6 @@ class QuerySetTest(unittest.TestCase): 'brasil').order_by('$text_score').first() self.assertEqual(item.get_text_score(), max_text_score) - @requires_mongodb_gte_26 def test_distinct_handles_references_to_alias(self): register_connection('testdb', 'mongoenginetest2') @@ -4586,7 +4572,6 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(bars._cursor._Cursor__read_preference, ReadPreference.SECONDARY_PREFERRED) - @requires_mongodb_gte_26 def test_read_preference_aggregation_framework(self): class Bar(Document): txt = StringField() @@ -5354,7 +5339,6 @@ class QuerySetTest(unittest.TestCase): self.assertTrue(Person.objects._has_data(), 'Cursor has data and returned False') - @requires_mongodb_gte_26 def test_queryset_aggregation_framework(self): class Person(Document): name = StringField() @@ -5396,7 +5380,6 @@ class QuerySetTest(unittest.TestCase): {'_id': None, 'avg': 29, 'total': 2} ]) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_skip(self): class Person(Document): name = StringField() @@ -5418,7 +5401,6 @@ class QuerySetTest(unittest.TestCase): {'_id': p3.pk, 'name': "SANDRA MARA"} ]) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_limit(self): class Person(Document): name = StringField() @@ -5439,7 +5421,6 @@ class QuerySetTest(unittest.TestCase): {'_id': p1.pk, 'name': "ISABELLA LUANNA"} ]) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_sort(self): class Person(Document): name = StringField() @@ -5462,7 +5443,6 @@ class QuerySetTest(unittest.TestCase): {'_id': p2.pk, 'name': "WILSON JUNIOR"} ]) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_skip_with_limit(self): class Person(Document): name = StringField() @@ -5492,7 +5472,6 @@ class QuerySetTest(unittest.TestCase): self.assertEqual(data, list(data2)) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_sort_with_limit(self): class Person(Document): name = StringField() @@ -5534,7 +5513,6 @@ class QuerySetTest(unittest.TestCase): {'_id': p3.pk, 'name': "SANDRA MARA"}, ]) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_sort_with_skip(self): class Person(Document): name = StringField() @@ -5555,7 +5533,6 @@ class QuerySetTest(unittest.TestCase): {'_id': p2.pk, 'name': "WILSON JUNIOR"} ]) - @requires_mongodb_gte_26 def test_queryset_aggregation_with_sort_with_skip_with_limit(self): class Person(Document): name = StringField() diff --git a/tests/utils.py b/tests/utils.py index 0ebb44a4..27d5ada7 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -5,7 +5,7 @@ from nose.plugins.skip import SkipTest from mongoengine import connect from mongoengine.connection import get_db, disconnect_all -from mongoengine.mongodb_support import get_mongodb_version, MONGODB_26, MONGODB_3, MONGODB_32, MONGODB_34 +from mongoengine.mongodb_support import get_mongodb_version MONGO_TEST_DB = 'mongoenginetest' # standard name for the test database @@ -35,8 +35,20 @@ def get_as_pymongo(doc): def _decorated_with_ver_requirement(func, mongo_version_req, oper): - """Return a given function decorated with the version requirement - for a particular MongoDB version tuple. + """Return a MongoDB version requirement decorator. + + The resulting decorator will raise a SkipTest exception if the current + MongoDB version doesn't match the provided version/operator. + + For example, if you define a decorator like so: + + def requires_mongodb_gte_36(func): + return _decorated_with_ver_requirement( + func, (3.6), oper=operator.ge + ) + + Then tests decorated with @requires_mongodb_gte_36 will be skipped if + ran against MongoDB < v3.6. :param mongo_version_req: The mongodb version requirement (tuple(int, int)) :param oper: The operator to apply (e.g: operator.ge) @@ -51,31 +63,3 @@ def _decorated_with_ver_requirement(func, mongo_version_req, oper): _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, oper=operator.ge) - - -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. - """ - return _decorated_with_ver_requirement(func, MONGODB_26, oper=operator.ge) - - -def requires_mongodb_gte_3(func): - """Raise a SkipTest exception if we're working with MongoDB version - lower than v3.0. - """ - return _decorated_with_ver_requirement(func, MONGODB_3, oper=operator.ge) diff --git a/tox.ini b/tox.ini index 815d2acc..40bcea8a 100644 --- a/tox.ini +++ b/tox.ini @@ -6,7 +6,7 @@ commands = python setup.py nosetests {posargs} deps = nose - mg35: PyMongo==3.5 + mg34x: PyMongo>=3.4,<3.5 mg3x: PyMongo>=3.0,<3.7 setenv = PYTHON_EGG_CACHE = {envdir}/python-eggs