diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c2e3f7d2b3..e056240a97 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -27,6 +27,8 @@ Fixed * Fixed schema utils to more reliably handle schemas that define nested arrays (object-array-object-array-string) as discovered in some of the ansible installer RBAC tests (see #5684). This includes a test that reproduced the error so we don't hit this again. #5685 +* Fixed eventlet monkey patching so more of the unit tests work under pytest. #5689 + Added ~~~~~ diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000000..7ca82b787d --- /dev/null +++ b/conftest.py @@ -0,0 +1,25 @@ +# Copyright 2022 The StackStorm Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def pytest_configure(config): + import sys + + sys._called_from_test = True + + +def pytest_unconfigure(config): + import sys + + del sys._called_from_test diff --git a/st2api/tests/unit/controllers/v1/test_action_views.py b/st2api/tests/unit/controllers/v1/test_action_views.py index bbc76e3760..2f6be710bf 100644 --- a/st2api/tests/unit/controllers/v1/test_action_views.py +++ b/st2api/tests/unit/controllers/v1/test_action_views.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import mock from st2common.content import utils as content_utils diff --git a/st2api/tests/unit/controllers/v1/test_executions_auth.py b/st2api/tests/unit/controllers/v1/test_executions_auth.py index 9baaf1e0f3..04392b319c 100644 --- a/st2api/tests/unit/controllers/v1/test_executions_auth.py +++ b/st2api/tests/unit/controllers/v1/test_executions_auth.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import bson import copy import datetime diff --git a/st2api/tests/unit/controllers/v1/test_rule_views.py b/st2api/tests/unit/controllers/v1/test_rule_views.py index 95839c3110..cafc1b7cf2 100644 --- a/st2api/tests/unit/controllers/v1/test_rule_views.py +++ b/st2api/tests/unit/controllers/v1/test_rule_views.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import six from st2common.models.system.common import ResourceReference diff --git a/st2api/tests/unit/controllers/v1/test_runnertypes.py b/st2api/tests/unit/controllers/v1/test_runnertypes.py index 34c243c545..2e1f47dab7 100644 --- a/st2api/tests/unit/controllers/v1/test_runnertypes.py +++ b/st2api/tests/unit/controllers/v1/test_runnertypes.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + from st2api.controllers.v1.runnertypes import RunnerTypesController from st2tests.api import FunctionalTest diff --git a/st2api/tests/unit/controllers/v1/test_traces.py b/st2api/tests/unit/controllers/v1/test_traces.py index 79bbdad6ae..9322a6b782 100644 --- a/st2api/tests/unit/controllers/v1/test_traces.py +++ b/st2api/tests/unit/controllers/v1/test_traces.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + from st2api.controllers.v1.traces import TracesController from st2tests.fixturesloader import FixturesLoader diff --git a/st2api/tests/unit/controllers/v1/test_triggertypes.py b/st2api/tests/unit/controllers/v1/test_triggertypes.py index 414fc34360..2461796e20 100644 --- a/st2api/tests/unit/controllers/v1/test_triggertypes.py +++ b/st2api/tests/unit/controllers/v1/test_triggertypes.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import six from st2api.controllers.v1.triggers import TriggerTypeController diff --git a/st2auth/tests/unit/controllers/v1/test_token.py b/st2auth/tests/unit/controllers/v1/test_token.py index cd90a6cef1..e56c7e9acb 100644 --- a/st2auth/tests/unit/controllers/v1/test_token.py +++ b/st2auth/tests/unit/controllers/v1/test_token.py @@ -13,6 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import uuid import datetime import random diff --git a/st2common/st2common/models/db/__init__.py b/st2common/st2common/models/db/__init__.py index d20afb78b2..1cecf3a247 100644 --- a/st2common/st2common/models/db/__init__.py +++ b/st2common/st2common/models/db/__init__.py @@ -36,7 +36,11 @@ # For now, we go with option 2) since it seems to be good enough of a compromise. We detect if we # are running inside tests by checking if "nose" module is present - the same logic we already use # in a couple of other places (and something which would need to be changed if we switch to pytest). -if "nose" in sys.modules.keys(): +# For pytest, we set sys._called_from_test in conftest.py +if "nose" in sys.modules.keys() or hasattr(sys, "_called_from_test"): + # pytest can load any test file first, which randomizes where the monkey_patch is needed. + # thus mongoengine might already be loaded at this point under pytest! + # In that case, we just add the monkey_patch to the top of that test file. from st2common.util.monkey_patch import monkey_patch monkey_patch() diff --git a/st2common/st2common/util/monkey_patch.py b/st2common/st2common/util/monkey_patch.py index 598e3e36ee..f187255897 100644 --- a/st2common/st2common/util/monkey_patch.py +++ b/st2common/st2common/util/monkey_patch.py @@ -91,7 +91,11 @@ def use_select_poll_workaround(nose_only=True): import eventlet # Work around to get tests to pass with eventlet >= 0.20.0 - if not nose_only or (nose_only and "nose" in sys.modules.keys()): + if not nose_only or ( + nose_only + # sys._called_from_test set in conftest.py for pytest runs + and ("nose" in sys.modules.keys() or hasattr(sys, "_called_from_test")) + ): # Add back blocking poll() to eventlet monkeypatched select original_poll = eventlet.patcher.original("select").poll select.poll = original_poll diff --git a/st2common/tests/unit/test_action_param_utils.py b/st2common/tests/unit/test_action_param_utils.py index 5eecf018dc..8949820f40 100644 --- a/st2common/tests/unit/test_action_param_utils.py +++ b/st2common/tests/unit/test_action_param_utils.py @@ -15,6 +15,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import copy import six diff --git a/st2common/tests/unit/test_db_base.py b/st2common/tests/unit/test_db_base.py index 6849643243..154fb09708 100644 --- a/st2common/tests/unit/test_db_base.py +++ b/st2common/tests/unit/test_db_base.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import mongoengine from st2common.models.db import stormbase diff --git a/st2common/tests/unit/test_db_fields.py b/st2common/tests/unit/test_db_fields.py index 4da8400a78..9abd587fb5 100644 --- a/st2common/tests/unit/test_db_fields.py +++ b/st2common/tests/unit/test_db_fields.py @@ -23,6 +23,12 @@ import unittest2 import orjson import zstandard + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import mongoengine as me from st2common.fields import ComplexDateTimeField diff --git a/st2common/tests/unit/test_param_utils.py b/st2common/tests/unit/test_param_utils.py index 77c88b1cd3..c5b1959780 100644 --- a/st2common/tests/unit/test_param_utils.py +++ b/st2common/tests/unit/test_param_utils.py @@ -16,6 +16,11 @@ from __future__ import absolute_import +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import six import mock diff --git a/st2common/tests/unit/test_purge_executions.py b/st2common/tests/unit/test_purge_executions.py index 64ee4cfa67..cb696e08ed 100644 --- a/st2common/tests/unit/test_purge_executions.py +++ b/st2common/tests/unit/test_purge_executions.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import copy from datetime import timedelta diff --git a/st2common/tests/unit/test_purge_trigger_instances.py b/st2common/tests/unit/test_purge_trigger_instances.py index 515c4040c3..8848ef5f11 100644 --- a/st2common/tests/unit/test_purge_trigger_instances.py +++ b/st2common/tests/unit/test_purge_trigger_instances.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + from datetime import timedelta from st2common import log as logging diff --git a/st2common/tests/unit/test_reference.py b/st2common/tests/unit/test_reference.py index ced486a867..b0f661ac9a 100644 --- a/st2common/tests/unit/test_reference.py +++ b/st2common/tests/unit/test_reference.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import copy import mock import mongoengine diff --git a/st2common/tests/unit/test_runners_utils.py b/st2common/tests/unit/test_runners_utils.py index bc6acfcf7e..98f8acd0ea 100644 --- a/st2common/tests/unit/test_runners_utils.py +++ b/st2common/tests/unit/test_runners_utils.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import mock from st2common.runners import utils diff --git a/st2common/tests/unit/test_tags.py b/st2common/tests/unit/test_tags.py index 6230cedea6..0a5f9f4e5b 100644 --- a/st2common/tests/unit/test_tags.py +++ b/st2common/tests/unit/test_tags.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import random import string diff --git a/st2reactor/tests/unit/test_enforce.py b/st2reactor/tests/unit/test_enforce.py index 4b282305bd..37317e610a 100644 --- a/st2reactor/tests/unit/test_enforce.py +++ b/st2reactor/tests/unit/test_enforce.py @@ -15,6 +15,11 @@ from __future__ import absolute_import +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import mock from st2common.constants import action as action_constants diff --git a/st2reactor/tests/unit/test_rule_engine.py b/st2reactor/tests/unit/test_rule_engine.py index 2f70a2a9d7..134eb62ed9 100644 --- a/st2reactor/tests/unit/test_rule_engine.py +++ b/st2reactor/tests/unit/test_rule_engine.py @@ -14,6 +14,12 @@ # limitations under the License. from __future__ import absolute_import + +# pytest: make sure monkey_patching happens before importing mongoengine +from st2common.util.monkey_patch import monkey_patch + +monkey_patch() + import mock from mongoengine import NotUniqueError