diff --git a/.gitignore b/.gitignore index 090159801f..dc1b6aec20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.py[cod] *.sqlite *.log +*.orig .stamp* # C extensions @@ -71,4 +72,4 @@ benchmark_histograms/ [._]*.sw[a-p]x [._]sw[a-p]x -**/build/lib/** \ No newline at end of file +**/build/lib/** diff --git a/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py b/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py index 3c609e26b5..c1aa148433 100644 --- a/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py +++ b/contrib/runners/python_runner/tests/integration/test_python_action_process_wrapper.py @@ -45,7 +45,7 @@ __all__ = ["PythonRunnerActionWrapperProcessTestCase"] # Maximum limit for the process wrapper script execution time (in seconds) -WRAPPER_PROCESS_RUN_TIME_UPPER_LIMIT = 0.31 +WRAPPER_PROCESS_RUN_TIME_UPPER_LIMIT = 0.70 ASSERTION_ERROR_MESSAGE = """ Python wrapper process script took more than %s seconds to execute (%s). This most likely means diff --git a/st2api/tests/unit/controllers/v1/test_service_registry.py b/st2api/tests/unit/controllers/v1/test_service_registry.py index d195c2361e..e9392b3279 100644 --- a/st2api/tests/unit/controllers/v1/test_service_registry.py +++ b/st2api/tests/unit/controllers/v1/test_service_registry.py @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import tooz + from st2common.service_setup import register_service_in_service_registry from st2common.util import system_info from st2common.services.coordination import get_member_id @@ -22,20 +24,26 @@ from st2tests.api import FunctionalTest -__all__ = ["ServiceyRegistryControllerTestCase"] +__all__ = ["ServiceRegistryControllerTestCase"] -class ServiceyRegistryControllerTestCase(FunctionalTest): +class ServiceRegistryControllerTestCase(FunctionalTest): coordinator = None @classmethod def setUpClass(cls): - super(ServiceyRegistryControllerTestCase, cls).setUpClass() + super(ServiceRegistryControllerTestCase, cls).setUpClass() tests_config.parse_args(coordinator_noop=True) cls.coordinator = coordination.get_coordinator(use_cache=False) + # make sure api group is deleted for test to pass + # there seems to be some dangling groups being created in the unit tests + try: + cls.coordinator.delete_group("api").get() + except tooz.coordination.GroupNotCreated: + pass # NOTE: We mock call common_setup to emulate service being registered in the service # registry during bootstrap phase @@ -47,7 +55,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - super(ServiceyRegistryControllerTestCase, cls).tearDownClass() + super(ServiceRegistryControllerTestCase, cls).tearDownClass() coordination.coordinator_teardown(cls.coordinator) diff --git a/st2client/tests/unit/test_commands.py b/st2client/tests/unit/test_commands.py index 929a327e98..e8fa417cb9 100644 --- a/st2client/tests/unit/test_commands.py +++ b/st2client/tests/unit/test_commands.py @@ -14,11 +14,13 @@ # limitations under the License. from __future__ import absolute_import + import os import mock import json import logging import argparse +import re import tempfile import unittest from collections import namedtuple @@ -490,8 +492,14 @@ def test_help_command_line_arg_works_for_supported_commands(self): self.assertIn("usage:", stdout) self.assertIn(" ".join(command), stdout) - # self.assertIn('positional arguments:', stdout) - self.assertIn("optional arguments:", stdout) + # argparse on py3.8/py3.9 has a different output to py3.10 so the check for + # optional arguments covers both formats. + assert ( + isinstance( + re.search("(optional arguments:|options:)", stdout), re.Match + ) + is True + ) # Reset stdout and stderr after each iteration self._reset_output_streams() @@ -510,8 +518,14 @@ def test_help_command_line_arg_works_for_supported_commands(self): self.assertIn("usage:", stdout) self.assertIn(" ".join(command), stdout) - # self.assertIn('positional arguments:', stdout) - self.assertIn("optional arguments:", stdout) + # argparse on py3.8/py3.9 has a different output to py3.10 so the check for + # optional arguments covers both formats. + assert ( + isinstance( + re.search("(optional arguments:|options:)", stdout), re.Match + ) + is True + ) # Verify that the actual help usage string was triggered and not the invalid # "too few arguments" which would indicate command doesn't actually correctly handle diff --git a/st2client/tests/unit/test_inquiry.py b/st2client/tests/unit/test_inquiry.py index 5ae225c79e..c8804dae47 100644 --- a/st2client/tests/unit/test_inquiry.py +++ b/st2client/tests/unit/test_inquiry.py @@ -14,6 +14,7 @@ # limitations under the License. from __future__ import absolute_import + import copy import json import mock @@ -294,6 +295,13 @@ def test_respond_invalid(self): "ERROR: 400 Client Error: Bad Request", self.stdout.getvalue().strip() ) + @mock.patch.object( + requests, + "get", + mock.MagicMock( + return_value=base.FakeResponse(json.dumps({}), 404, "NOT FOUND") + ), + ) def test_respond_nonexistent_inquiry(self): """Test responding to an inquiry that doesn't exist""" inquiry_id = "134234" diff --git a/st2common/st2common/services/coordination.py b/st2common/st2common/services/coordination.py index acd8bb0b1e..8f693f56e5 100644 --- a/st2common/st2common/services/coordination.py +++ b/st2common/st2common/services/coordination.py @@ -138,7 +138,10 @@ def leave_group(cls, group_id): @classmethod def delete_group(cls, group_id): - del cls.groups[group_id] + try: + del cls.groups[group_id] + except KeyError: + raise GroupNotCreated(group_id) return NoOpAsyncResult() @classmethod diff --git a/st2common/st2common/transport/publishers.py b/st2common/st2common/transport/publishers.py index ddf5d2f8c9..73596ed70e 100644 --- a/st2common/st2common/transport/publishers.py +++ b/st2common/st2common/transport/publishers.py @@ -43,8 +43,8 @@ class PoolPublisher(object): def __init__(self, urls=None): """ - :param urls: Connection URLs to use. If not provided it uses a default value from th - config. + :param urls: Connection URLs to use. If not provided it uses a default value from + the config. :type urls: ``list`` """ urls = urls or transport_utils.get_messaging_urls() @@ -67,7 +67,7 @@ def publish(self, payload, exchange, routing_key="", compression=None): ) def do_publish(connection, channel): - # ProducerPool ends up creating it own ConnectionPool which ends up + # ProducerPool ends up creating its own ConnectionPool which ends up # completely invalidating this ConnectionPool. Also, a ConnectionPool for # producer does not really solve any problems for us so better to create a # Producer for each publish. diff --git a/st2tests/st2tests/fixtures/packs/action_chain_tests/actions/chains/test_pause_resume_with_error.yaml b/st2tests/st2tests/fixtures/packs/action_chain_tests/actions/chains/test_pause_resume_with_error.yaml index a4d46be55e..c214aa3c30 100644 --- a/st2tests/st2tests/fixtures/packs/action_chain_tests/actions/chains/test_pause_resume_with_error.yaml +++ b/st2tests/st2tests/fixtures/packs/action_chain_tests/actions/chains/test_pause_resume_with_error.yaml @@ -3,7 +3,12 @@ chain: name: task1 ref: core.local params: - cmd: "while [ -e '{{tempfile}}' ]; do sleep 0.1; exit 1" + cmd: | + while [ -e '{{tempfile}}' ]; + do + sleep 0.1 + done + exit 1 timeout: 180 on-failure: task2 -