From 4bd4036d4ccfba955a256fa88936045c8164e9b2 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:16:28 -0500 Subject: [PATCH 01/34] rename host/port environment variables --- ptero_petri/implementation/petri/webhooks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ptero_petri/implementation/petri/webhooks.py b/ptero_petri/implementation/petri/webhooks.py index c16c5fd..4f458ac 100644 --- a/ptero_petri/implementation/petri/webhooks.py +++ b/ptero_petri/implementation/petri/webhooks.py @@ -33,8 +33,8 @@ def _request_body(response_links, data): def _url(net_key, place_idx, color, color_group_idx): - host = os.environ.get('PETRI_HOST', 'localhost') - port = int(os.environ.get('PETRI_PORT', '5000')) + host = os.environ.get('PTERO_PETRI_HOST', 'localhost') + port = int(os.environ.get('PTERO_PETRI_PORT', '5000')) return "http://%s:%d/v1/nets/%s/places/%d/tokens?color=%d&color_group=%d" % ( host, port, net_key, place_idx, color, color_group_idx) From 551f615e743d91447c648fb237733dafc6042c19 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:32:57 -0500 Subject: [PATCH 02/34] flush redis in setUp --- tests/implementation/redishelpers/redistest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/implementation/redishelpers/redistest.py b/tests/implementation/redishelpers/redistest.py index 6646d32..83288a6 100644 --- a/tests/implementation/redishelpers/redistest.py +++ b/tests/implementation/redishelpers/redistest.py @@ -21,6 +21,9 @@ def setUpClass(cls): cls._wait_for_connection() + def setUp(self): + self.conn.flushall() + def tearDown(self): self.conn.flushall() From 9dc15998ff8468bc7f39de0d57e5e1ad061697a2 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:33:28 -0500 Subject: [PATCH 03/34] spin up devserver in tests/__init__.py --- tests/__init__.py | 115 ++++++++++++++++++++++++++++ tests/api/v1/generator/base_case.py | 30 +------- tests/api/v1/generator/func.py | 1 - tox.ini | 2 + 4 files changed, 119 insertions(+), 29 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..55a06d9 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,115 @@ +import errno +import os +import psutil +import signal +import subprocess +import sys +import time + + +NUM_WORKERS = 4 + + +instance = None + + +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: + raise + + +def wait_time(): + if os.environ.get('TRAVIS'): + return 15 + else: + return 2 + + +def procfile_path(): + return os.path.join(os.path.dirname(__file__), + 'scripts', 'Procfile') + + +def service_command_line(): + return [os.path.join(os.getcwd(), 'devserver'), + '--max-run-time', '120', + '--port', os.environ['PTERO_PETRI_PORT'], + '--logdir', 'var/log', + '--cover'] + +#def service_command_line(): +# return ['honcho', '-f', procfile_path(), 'start', '-c', +# 'worker=%s' % NUM_WORKERS] + + +def setUp(): + global instance + + logdir = 'var/log' + mkdir_p(logdir) + outlog = open(os.path.join(logdir, 'honcho.out'), 'w') + errlog = open(os.path.join(logdir, 'honcho.err'), 'w') + + if not os.environ.get('SKIP_PROCFILE'): + instance = subprocess.Popen(service_command_line(), + shell=False, stdout=outlog, stderr=errlog) + time.sleep(wait_time()) + if instance.poll() is not None: + raise RuntimeError("honcho instance terminated prematurely") + + +def travis_ci_cleanup(): + grandchildren = get_grandchildren() + descendents = get_descendents() + + if not signal_processes(grandchildren, signal.SIGINT): + return + + time.sleep(1) + if not signal_processes(descendents, signal.SIGINT): + return + + time.sleep(3) + signal_processes(descendents, signal.SIGKILL) + + +def signal_processes(processes, sig): + signaled_someone = False + for p in processes: + try: + p.send_signal(sig) + signaled_someone = True + except psutil.NoSuchProcess: + pass + + return signaled_someone + + +def get_grandchildren(): + children = psutil.Process(instance.pid).get_children(recursive=False) + grandchildren = [] + for child in children: + grandchildren.extend(child.get_children(recursive=False)) + return grandchildren + + +def get_descendents(): + return psutil.Process(instance.pid).get_children(recursive=True) + + +# NOTE If this doesn't run then honcho will be orphaned... +def tearDown(): + if not os.environ.get('SKIP_PROCFILE'): + if os.environ.get('TRAVIS'): + travis_ci_cleanup() + + ec = instance.poll() + if ec is None: + instance.send_signal(signal.SIGINT) + else: + sys.stderr.write('Unexpected exit of services: code = (%s)\n' % ec) diff --git a/tests/api/v1/generator/base_case.py b/tests/api/v1/generator/base_case.py index 96a30c9..cad0089 100644 --- a/tests/api/v1/generator/base_case.py +++ b/tests/api/v1/generator/base_case.py @@ -27,9 +27,9 @@ def validate_json(text): class TestCaseMixin(object): __metaclass__ = abc.ABCMeta - @abc.abstractproperty + @property def api_port(self): - pass + return int(os.environ['PTERO_PETRI_PORT']) @abc.abstractproperty def callback_port(self): @@ -58,13 +58,11 @@ def setUp(self): super(TestCaseMixin, self).setUp() self._clear_memoized_data() - self._start_devserver() self._start_callback_receipt_webserver() def tearDown(self): super(TestCaseMixin, self).tearDown() self._stop_callback_receipt_webserver() - self._stop_devserver() def _submit_net(self): @@ -191,23 +189,6 @@ def _clear_memoized_data(self): self._expected_callbacks = None - def _start_devserver(self): - cmd = [ - self._devserver_path, - '--max-run-time', str(self._max_wait_time), - '--port', str(self.api_port), - '--logdir', str(self._logdir), - '--cover', - ] - if int(os.environ.get('PTERO_TEST_WEBSERVER_DEBUG', 0)) == 1: - cmd.append('--debug') - - self._devserver = subprocess.Popen(cmd, close_fds=True) - self._wait_for_devserver() - - def _wait_for_devserver(self): - time.sleep(5) - def _start_callback_receipt_webserver(self): self._callback_webserver = subprocess.Popen( [self._callback_webserver_path, @@ -220,17 +201,10 @@ def _start_callback_receipt_webserver(self): def _stop_callback_receipt_webserver(self): _stop_subprocess(self._callback_webserver) - def _stop_devserver(self): - _stop_subprocess(self._devserver) - @property def _callback_webserver_path(self): return os.path.join(os.path.dirname(__file__), 'callback_webserver.py') - @property - def _devserver_path(self): - return os.path.join(self._repository_root_path, 'devserver') - @property def _logdir(self): return os.path.join(self._repository_root_path, 'logs', self.test_name) diff --git a/tests/api/v1/generator/func.py b/tests/api/v1/generator/func.py index a856d4d..e71fab5 100644 --- a/tests/api/v1/generator/func.py +++ b/tests/api/v1/generator/func.py @@ -25,7 +25,6 @@ def _create_and_attach_test_case(target_module, test_case_directory, def _create_test_case(test_case_directory, test_case_name): class_dict = { - 'api_port': _get_available_port(), 'callback_port': _get_available_port(), 'directory': os.path.join(test_case_directory, test_case_name), 'test_name': test_case_name, diff --git a/tox.ini b/tox.ini index 504a656..516b639 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,8 @@ setenv = PTERO_PETRI_AMQP_CONNECTION_ATTEMPTS=40 PTERO_PETRI_AMQP_PREFETCH_COUNT=10 PTERO_PETRI_AMQP_HEARTBEAT_INTERVAL=600 + PTERO_PETRI_HOST=localhost + PTERO_PETRI_PORT=6000 commands = coverage combine coverage erase From 7cc587fb6c848ae7ff4076c6188776511a833ca1 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:37:20 -0500 Subject: [PATCH 04/34] replace devserver with Procfile for tests --- tests/__init__.py | 10 +--------- tests/scripts/Procfile | 2 ++ 2 files changed, 3 insertions(+), 9 deletions(-) create mode 100644 tests/scripts/Procfile diff --git a/tests/__init__.py b/tests/__init__.py index 55a06d9..fddcfc5 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -36,15 +36,7 @@ def procfile_path(): def service_command_line(): - return [os.path.join(os.getcwd(), 'devserver'), - '--max-run-time', '120', - '--port', os.environ['PTERO_PETRI_PORT'], - '--logdir', 'var/log', - '--cover'] - -#def service_command_line(): -# return ['honcho', '-f', procfile_path(), 'start', '-c', -# 'worker=%s' % NUM_WORKERS] + return ['honcho', '-f', procfile_path(), 'start'] def setUp(): diff --git a/tests/scripts/Procfile b/tests/scripts/Procfile new file mode 100644 index 0000000..82ee8c7 --- /dev/null +++ b/tests/scripts/Procfile @@ -0,0 +1,2 @@ +web: coverage run ptero_petri/api/wsgi.py --port $PTERO_PETRI_PORT +orchestrator: coverage run ptero_petri/implementation/orchestrator/main.py From 629cee6850d2604cdb8dfc16834a2851c9a30ab9 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:39:05 -0500 Subject: [PATCH 05/34] replace /logs with /var in .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 37ff64c..ae235bc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ /.tox /AUTHORS /ChangeLog -/logs /build +/var From e4f66a4ee055b967fb3f3887df8ffeb711a0dd7c Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:44:39 -0500 Subject: [PATCH 06/34] move .env to env/development --- .env => env/development | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .env => env/development (100%) diff --git a/.env b/env/development similarity index 100% rename from .env rename to env/development From 18b28389473908359bf48f03f090994e37dd7098 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:44:49 -0500 Subject: [PATCH 07/34] add localhost and port to env/development --- env/development | 2 ++ 1 file changed, 2 insertions(+) diff --git a/env/development b/env/development index 939045e..c845e2a 100644 --- a/env/development +++ b/env/development @@ -7,3 +7,5 @@ PTERO_PETRI_AMQP_PREFETCH_COUNT=10 PTERO_PETRI_AMQP_HEARTBEAT_INTERVAL=600 PTERO_PETRI_REDIS_HOST=localhost PTERO_PETRI_REDIS_PORT=6379 +PTERO_PETRI_HOST=localhost +PTERO_PETRI_PORT=6000 From 33cc789b99d59238824486262f2d721735923ecb Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 09:45:30 -0500 Subject: [PATCH 08/34] fix base Procfile orchestrator command --- Procfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Procfile b/Procfile index 85d5a81..ae8622e 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ web: gunicorn ptero_petri.api.wsgi:app -orchestrator: ptero orchestrator +orchestrator: petri-orchestrator From 0ad98c973eed93a33280246e88d0c1a4939de60d Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 10:02:01 -0500 Subject: [PATCH 09/34] fetch backend redis configuration from environment --- ptero_petri/implementation/factory.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ptero_petri/implementation/factory.py b/ptero_petri/implementation/factory.py index b8ce4ed..6fc13a4 100644 --- a/ptero_petri/implementation/factory.py +++ b/ptero_petri/implementation/factory.py @@ -1,5 +1,6 @@ from . import backend import redis +import os __all__ = ['Factory'] @@ -21,4 +22,9 @@ def _initialize(self): # Lazy initialize to be pre-fork friendly. if not self._initialized: self._initialized = True - self._redis = redis.Redis() + self._redis = self._create_redis_connection() + + def _create_redis_connection(self): + return redis.Redis( + host=os.environ.get('PTERO_PETRI_REDIS_HOST', 'localhost'), + port=int(os.environ.get('PTERO_PETRI_REDIS_PORT', '6379'))) From 4f19c0aeccf6b225e41e2d12a9f8a7c85caa5357 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 10:02:23 -0500 Subject: [PATCH 10/34] testing: use Procfile to run redis-server --- tests/scripts/Procfile | 1 + tox.ini | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tests/scripts/Procfile b/tests/scripts/Procfile index 82ee8c7..566a0ca 100644 --- a/tests/scripts/Procfile +++ b/tests/scripts/Procfile @@ -1,2 +1,3 @@ web: coverage run ptero_petri/api/wsgi.py --port $PTERO_PETRI_PORT orchestrator: coverage run ptero_petri/implementation/orchestrator/main.py +redis: redis-server --port $PTERO_PETRI_REDIS_PORT diff --git a/tox.ini b/tox.ini index 516b639..9be83f3 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,8 @@ setenv = PTERO_PETRI_AMQP_CONNECTION_ATTEMPTS=40 PTERO_PETRI_AMQP_PREFETCH_COUNT=10 PTERO_PETRI_AMQP_HEARTBEAT_INTERVAL=600 + PTERO_PETRI_REDIS_PORT=6998 + PTERO_PETRI_REDIS_HOST=localhost PTERO_PETRI_HOST=localhost PTERO_PETRI_PORT=6000 commands = From c88d055e1bc17ae116dc3bcaf6048ed67ec1bb13 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:11:11 -0500 Subject: [PATCH 11/34] use injector to configure redis in web process --- ptero_petri/implementation/factory.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ptero_petri/implementation/factory.py b/ptero_petri/implementation/factory.py index 6fc13a4..0be350c 100644 --- a/ptero_petri/implementation/factory.py +++ b/ptero_petri/implementation/factory.py @@ -1,4 +1,6 @@ from . import backend +from .configuration.inject.initialize import initialize_injector +from . import interfaces import redis import os @@ -8,6 +10,7 @@ class Factory(object): def __init__(self): self._initialized = False + self._injector = None self._redis = None def create_backend(self): @@ -22,9 +25,5 @@ def _initialize(self): # Lazy initialize to be pre-fork friendly. if not self._initialized: self._initialized = True - self._redis = self._create_redis_connection() - - def _create_redis_connection(self): - return redis.Redis( - host=os.environ.get('PTERO_PETRI_REDIS_HOST', 'localhost'), - port=int(os.environ.get('PTERO_PETRI_REDIS_PORT', '6379'))) + self._injector = initialize_injector() + self._redis = self._injector.get(interfaces.IStorage) From dd24a46128e940d9db8b8d6c3ce3ac111de45abc Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:14:19 -0500 Subject: [PATCH 12/34] add amqp_parameters argument to Backend --- ptero_petri/implementation/backend.py | 3 ++- ptero_petri/implementation/factory.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ptero_petri/implementation/backend.py b/ptero_petri/implementation/backend.py index 3de054e..b0f4d26 100644 --- a/ptero_petri/implementation/backend.py +++ b/ptero_petri/implementation/backend.py @@ -11,8 +11,9 @@ class Backend(object): - def __init__(self, redis_connection): + def __init__(self, redis_connection, amqp_parameters): self.redis_connection = redis_connection + self.amqp_parameters = amqp_parameters def create_net(self, net_data): translator = Translator(net_data) diff --git a/ptero_petri/implementation/factory.py b/ptero_petri/implementation/factory.py index 0be350c..a438d2c 100644 --- a/ptero_petri/implementation/factory.py +++ b/ptero_petri/implementation/factory.py @@ -1,6 +1,7 @@ from . import backend -from .configuration.inject.initialize import initialize_injector from . import interfaces +from .brokers.amqp.connection_manager import ConnectionParams +from .configuration.inject.initialize import initialize_injector import redis import os @@ -12,10 +13,12 @@ def __init__(self): self._initialized = False self._injector = None self._redis = None + self._connection_parameters = None def create_backend(self): self._initialize() - return backend.Backend(redis_connection=self._redis) + return backend.Backend(redis_connection=self._redis, + amqp_parameters=self._connection_parameters) def purge(self): self._initialize() @@ -27,3 +30,4 @@ def _initialize(self): self._initialized = True self._injector = initialize_injector() self._redis = self._injector.get(interfaces.IStorage) + self._connection_parameters = self._injector.get(ConnectionParams) From f6252b7883fd84ef888c6cc5124eec975b33671f Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:19:47 -0500 Subject: [PATCH 13/34] use broker connection parameters in web backend --- ptero_petri/implementation/backend.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ptero_petri/implementation/backend.py b/ptero_petri/implementation/backend.py index b0f4d26..f7a4fda 100644 --- a/ptero_petri/implementation/backend.py +++ b/ptero_petri/implementation/backend.py @@ -63,9 +63,17 @@ def cleanup(self): def _send_message(self, exchange, routing_key, body): - connection = pika.BlockingConnection() + connection = pika.BlockingConnection(self._pika_connection_params()) channel = connection.channel() channel.confirm_delivery() channel.basic_publish(exchange=exchange, routing_key=routing_key, body=body, properties=pika.BasicProperties(content_type='application/json', delivery_mode=1)) + + def _pika_connection_params(self): + credentials = pika.PlainCredentials('guest', 'guest') + return pika.ConnectionParameters( + self.amqp_parameters.hostname, + self.amqp_parameters.port, + self.amqp_parameters.virtual_host, + credentials) From f222b2d1081e30f15c28bc25ef1d3a9c20aaeefe Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:28:13 -0500 Subject: [PATCH 14/34] start rabbitmq in Procfile --- tests/__init__.py | 2 +- tests/scripts/Procfile | 1 + tox.ini | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index fddcfc5..a8e6dad 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -27,7 +27,7 @@ def wait_time(): if os.environ.get('TRAVIS'): return 15 else: - return 2 + return 3 def procfile_path(): diff --git a/tests/scripts/Procfile b/tests/scripts/Procfile index 566a0ca..f9ae02c 100644 --- a/tests/scripts/Procfile +++ b/tests/scripts/Procfile @@ -1,3 +1,4 @@ web: coverage run ptero_petri/api/wsgi.py --port $PTERO_PETRI_PORT orchestrator: coverage run ptero_petri/implementation/orchestrator/main.py redis: redis-server --port $PTERO_PETRI_REDIS_PORT +rabbit: RABBITMQ_NODE_PORT=$PTERO_PETRI_AMQP_PORT RABBITMQ_NODENAME=ptero-petri-rabbitmq RABBITMQ_LOG_BASE=$PWD/var/log RABBITMQ_MNESIA_BASE=$PWD/var/rabbitmq-data rabbitmq-server diff --git a/tox.ini b/tox.ini index 9be83f3..4a579f3 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ setenv = PTERO_PETRI_AMQP_HOST=localhost PTERO_PETRI_AMQP_PORT=5672 PTERO_PETRI_AMQP_VHOST=/ - PTERO_PETRI_AMQP_RETRY_DELAY=30 + PTERO_PETRI_AMQP_RETRY_DELAY=1 PTERO_PETRI_AMQP_CONNECTION_ATTEMPTS=40 PTERO_PETRI_AMQP_PREFETCH_COUNT=10 PTERO_PETRI_AMQP_HEARTBEAT_INTERVAL=600 From 401f694ed473093de0f14d7c67dc5b5246ddf6cb Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:51:43 -0500 Subject: [PATCH 15/34] travis-ci: disable default rabbitmq & redis --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6fbf76e..0af6ef9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,6 @@ python: "2.7" install: pip install tox -services: - - rabbitmq - - redis - script: - tox From 4c91047da3262c2b30751686015ac0999b9375a5 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:52:23 -0500 Subject: [PATCH 16/34] add honcho as a test requirement --- test-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test-requirements.txt b/test-requirements.txt index a3a58b9..b9e5000 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,5 @@ fakeredis +honcho mock nose >= 1.3.0 nose-cov From 98adc6296bc55c03d33d953a00847bcbe1898ac2 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 14:53:08 -0500 Subject: [PATCH 17/34] fix test coverage measurement of web process --- .coveragerc | 1 - tests/scripts/Procfile | 2 +- tests/scripts/sigterm_wrapper | 38 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100755 tests/scripts/sigterm_wrapper diff --git a/.coveragerc b/.coveragerc index 3e4d0f7..ea0863c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,4 @@ [run] -omit = ptero_petri/api/wsgi.py branch = True parallel = True source = ptero_petri diff --git a/tests/scripts/Procfile b/tests/scripts/Procfile index f9ae02c..41c5fbc 100644 --- a/tests/scripts/Procfile +++ b/tests/scripts/Procfile @@ -1,4 +1,4 @@ -web: coverage run ptero_petri/api/wsgi.py --port $PTERO_PETRI_PORT +web: tests/scripts/sigterm_wrapper coverage run ptero_petri/api/wsgi.py --port $PTERO_PETRI_PORT orchestrator: coverage run ptero_petri/implementation/orchestrator/main.py redis: redis-server --port $PTERO_PETRI_REDIS_PORT rabbit: RABBITMQ_NODE_PORT=$PTERO_PETRI_AMQP_PORT RABBITMQ_NODENAME=ptero-petri-rabbitmq RABBITMQ_LOG_BASE=$PWD/var/log RABBITMQ_MNESIA_BASE=$PWD/var/rabbitmq-data rabbitmq-server diff --git a/tests/scripts/sigterm_wrapper b/tests/scripts/sigterm_wrapper new file mode 100755 index 0000000..f14a770 --- /dev/null +++ b/tests/scripts/sigterm_wrapper @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import os +import signal +import subprocess +import sys +import time + + +def command_line(): + return sys.argv[1:] + + +LOOP_PERIOD = 0.05 + +sys.stderr.write('Converting SIGTERM to SIGINT for %s\n' % command_line()) +child_process = subprocess.Popen(command_line()) + + +def term_handler(signum, frame): + sys.stderr.write('Sending SIGINT to wrapped coverage process') + child_process.send_signal(signal.SIGINT) + + def kill_child(signum, frame): + if child_process.poll() is None: + child_process.kill() + + signal.signal(signal.SIGALRM, kill_child) + signal.alarm(10) + +signal.signal(signal.SIGINT, term_handler) +signal.signal(signal.SIGTERM, term_handler) + + +while True: + time.sleep(LOOP_PERIOD) + if child_process.poll() is not None: + break From 8460c93cb87411c414069d353e1206589f4af360 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 15:09:28 -0500 Subject: [PATCH 18/34] travis-ci: catch exception when honcho exits early --- tests/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/__init__.py b/tests/__init__.py index a8e6dad..b8592cb 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -98,7 +98,10 @@ def get_descendents(): def tearDown(): if not os.environ.get('SKIP_PROCFILE'): if os.environ.get('TRAVIS'): - travis_ci_cleanup() + try: + travis_ci_cleanup() + except psutil.NoSuchProcess: + pass ec = instance.poll() if ec is None: From 3d4c1349d52ae00969a484cee7ceab63515643ad Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Tue, 10 Jun 2014 15:14:57 -0500 Subject: [PATCH 19/34] travis-ci: capture honcho descendents earlier --- tests/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index b8592cb..d9a9111 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -11,6 +11,8 @@ instance = None +grandchildren = [] +descendents = [] def mkdir_p(path): @@ -41,6 +43,8 @@ def service_command_line(): def setUp(): global instance + global grandchildren + global descendents logdir = 'var/log' mkdir_p(logdir) @@ -53,12 +57,12 @@ def setUp(): time.sleep(wait_time()) if instance.poll() is not None: raise RuntimeError("honcho instance terminated prematurely") + grandchildren = get_grandchildren() + descendents = get_descendents() -def travis_ci_cleanup(): - grandchildren = get_grandchildren() - descendents = get_descendents() +def travis_ci_cleanup(): if not signal_processes(grandchildren, signal.SIGINT): return From 7eb8926cea9335dcff5aa4347af405e96a526788 Mon Sep 17 00:00:00 2001 From: Ian Ferguson Date: Tue, 10 Jun 2014 16:30:46 -0500 Subject: [PATCH 20/34] Pull in changes from fork's tests/__init__.py --- tests/__init__.py | 69 +++++++++++++++++------------------------------ tox.ini | 3 +++ 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index d9a9111..3f175b5 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -2,7 +2,6 @@ import os import psutil import signal -import subprocess import sys import time @@ -11,8 +10,7 @@ instance = None -grandchildren = [] -descendents = [] +descendents = {} def mkdir_p(path): @@ -31,11 +29,11 @@ def wait_time(): else: return 3 +def this_dir(): + return os.path.dirname(__file__) def procfile_path(): - return os.path.join(os.path.dirname(__file__), - 'scripts', 'Procfile') - + return os.path.join(this_dir(), 'scripts', 'Procfile') def service_command_line(): return ['honcho', '-f', procfile_path(), 'start'] @@ -43,8 +41,6 @@ def service_command_line(): def setUp(): global instance - global grandchildren - global descendents logdir = 'var/log' mkdir_p(logdir) @@ -52,27 +48,13 @@ def setUp(): errlog = open(os.path.join(logdir, 'honcho.err'), 'w') if not os.environ.get('SKIP_PROCFILE'): - instance = subprocess.Popen(service_command_line(), + instance = psutil.Popen(service_command_line(), shell=False, stdout=outlog, stderr=errlog) time.sleep(wait_time()) if instance.poll() is not None: raise RuntimeError("honcho instance terminated prematurely") - grandchildren = get_grandchildren() - descendents = get_descendents() - - - -def travis_ci_cleanup(): - if not signal_processes(grandchildren, signal.SIGINT): - return - - time.sleep(1) - if not signal_processes(descendents, signal.SIGINT): - return - - time.sleep(3) - signal_processes(descendents, signal.SIGKILL) - + else: + descendents = get_descendents() def signal_processes(processes, sig): signaled_someone = False @@ -85,30 +67,29 @@ def signal_processes(processes, sig): return signaled_someone +def get_descendents(): + processes = psutil.Process(instance.pid).get_children(recursive=True) + return dict([(x.pid, x) for x in processes]) -def get_grandchildren(): - children = psutil.Process(instance.pid).get_children(recursive=False) - grandchildren = [] - for child in children: - grandchildren.extend(child.get_children(recursive=False)) - return grandchildren +def cleanup(): + ec = instance.poll() + if ec is None: + descendents.update(get_descendents()) + instance.wait(timeout=2) -def get_descendents(): - return psutil.Process(instance.pid).get_children(recursive=True) + if not signal_processes(descendents, signal.SIGINT): + return + + time.sleep(3) + signal_processes(descendents, signal.SIGKILL) + + instance.send_signal(signal.SIGINT) + else: + sys.stderr.write('Unexpected exit of services: code = (%s)\n' % ec) # NOTE If this doesn't run then honcho will be orphaned... def tearDown(): if not os.environ.get('SKIP_PROCFILE'): - if os.environ.get('TRAVIS'): - try: - travis_ci_cleanup() - except psutil.NoSuchProcess: - pass - - ec = instance.poll() - if ec is None: - instance.send_signal(signal.SIGINT) - else: - sys.stderr.write('Unexpected exit of services: code = (%s)\n' % ec) + cleanup() diff --git a/tox.ini b/tox.ini index 4a579f3..631ddd5 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,8 @@ minversion = 1.6 envlist = py27 [testenv] +whitelist_externals = + rm setenv = PYTHONPATH=. PTERO_PETRI_AMQP_HOST=localhost @@ -17,6 +19,7 @@ setenv = PTERO_PETRI_HOST=localhost PTERO_PETRI_PORT=6000 commands = + rm -rf {toxinidir}/var coverage combine coverage erase coverage run {envbindir}/nosetests {posargs} From 9e47e992e3d6bbf8d8cf30837bfd204bcff7f23c Mon Sep 17 00:00:00 2001 From: David Morton Date: Tue, 10 Jun 2014 19:58:55 -0500 Subject: [PATCH 21/34] bugfix: wrap wait in try/except (wait throws exception after timeout) --- tests/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/__init__.py b/tests/__init__.py index 3f175b5..4c1a426 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -76,7 +76,10 @@ def cleanup(): if ec is None: descendents.update(get_descendents()) - instance.wait(timeout=2) + try: + instance.wait(timeout=2) + except psutil.TimeoutExpired: + pass if not signal_processes(descendents, signal.SIGINT): return From 77c37816f60386c0ffa4742e4b1ede5705097f9e Mon Sep 17 00:00:00 2001 From: David Morton Date: Tue, 10 Jun 2014 19:59:27 -0500 Subject: [PATCH 22/34] bugfix: descendents is now a dictionary --- tests/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 4c1a426..fac0787 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -81,11 +81,11 @@ def cleanup(): except psutil.TimeoutExpired: pass - if not signal_processes(descendents, signal.SIGINT): + if not signal_processes(descendents.values(), signal.SIGINT): return time.sleep(3) - signal_processes(descendents, signal.SIGKILL) + signal_processes(descendents.values(), signal.SIGKILL) instance.send_signal(signal.SIGINT) else: From 70c861d70449eb2d796f6696017c58714152505b Mon Sep 17 00:00:00 2001 From: David Morton Date: Tue, 10 Jun 2014 21:53:14 -0500 Subject: [PATCH 23/34] bugfix: don't let exit_process kill our children We were only mocking the os._exit portion of this function and left the kill all our children portion which killed honcho. --- .../implementation/brokers/amqp/test_connection_manager.py | 7 ++++--- .../brokers/amqp/test_publisher_confirm_manager.py | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/implementation/brokers/amqp/test_connection_manager.py b/tests/implementation/brokers/amqp/test_connection_manager.py index df5b81a..9a2e54f 100644 --- a/tests/implementation/brokers/amqp/test_connection_manager.py +++ b/tests/implementation/brokers/amqp/test_connection_manager.py @@ -19,6 +19,7 @@ prefetch_count=1, heartbeat_interval=600, ) +exit_process_path = 'ptero_petri.implementation.brokers.amqp.connection_manager.exit_process' class ConnectionManagerTests(unittest.TestCase): def setUp(self): @@ -167,7 +168,7 @@ def test_private_on_connectTCP_failed(self): # reached reconnect limit self.cm._connection_attempts = 3 fake_exit = mock.Mock() - with mock.patch('os._exit', new=fake_exit): + with mock.patch(exit_process_path, new=fake_exit): self.cm._on_connectTCP_failed(reason) self.assertEquals(self.cm.state, DISCONNECTED) fake_exit.assert_called_once_with(EXECUTE_SERVICE_UNAVAILABLE) @@ -177,7 +178,7 @@ def test_private_on_pika_connection_closed(self): self.cm.state = CONNECTING fake_exit = mock.Mock() - with mock.patch('os._exit', new=fake_exit): + with mock.patch(exit_process_path, new=fake_exit): self.cm._on_pika_connection_closed(None, reply_code='test_code', reply_text='test_text') @@ -225,7 +226,7 @@ def call_now(time, fn, *args, **kwargs): # reached retry limit fake_exit = mock.Mock() - with mock.patch('os._exit', new=fake_exit): + with mock.patch(exit_process_path, new=fake_exit): errback = mock.Mock() error = RuntimeError('bad') diff --git a/tests/implementation/brokers/amqp/test_publisher_confirm_manager.py b/tests/implementation/brokers/amqp/test_publisher_confirm_manager.py index ecb2b67..11a5b14 100644 --- a/tests/implementation/brokers/amqp/test_publisher_confirm_manager.py +++ b/tests/implementation/brokers/amqp/test_publisher_confirm_manager.py @@ -10,6 +10,8 @@ from ptero_petri.implementation.brokers.amqp.publisher_confirm_manager import PublisherConfirmManager from ptero_petri.implementation import exit_codes +exit_process_path = 'ptero_petri.implementation.brokers.amqp.publisher_confirm_manager.exit_process' + class TestPublisherConfirmManager(unittest.TestCase): def setUp(self): channel = mock.Mock() @@ -57,7 +59,7 @@ def test_private_on_publisher_confirm_nack(self): method_frame.method.multiple = multiple fake_exit = mock.Mock() - with mock.patch('os._exit', new=fake_exit): + with mock.patch(exit_process_path, new=fake_exit): self.pcm._on_publisher_confirm_nack(method_frame) fake_exit.assert_called_once_with(exit_codes.EXECUTE_SYSTEM_FAILURE) From 049ef1cd0eeb534b31edb9bb634944607917dd5f Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:21:21 -0500 Subject: [PATCH 24/34] travis-ci: stop using dash --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0af6ef9..07030bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,8 @@ python: "2.7" install: pip install tox +before_script: sudo update-alternatives --install /bin/sh sh /bin/bash 100 + script: - tox From 7b2055f535f19aa7503154d684bdca1ad8c3581a Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:37:01 -0500 Subject: [PATCH 25/34] exit_process no longer attempts to signal children --- ptero_petri/implementation/util/exit.py | 33 ++----------------- .../implementation/util/signal_handlers.py | 6 ++-- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/ptero_petri/implementation/util/exit.py b/ptero_petri/implementation/util/exit.py index 113ccd7..00b198c 100644 --- a/ptero_petri/implementation/util/exit.py +++ b/ptero_petri/implementation/util/exit.py @@ -1,40 +1,11 @@ import logging import os -import psutil -import signal -import time LOG = logging.getLogger(__name__) -_SIGNAL_TIMEOUT = 10 +def exit_process(exit_code): + LOG.info('Exitting process.') - -def exit_process(exit_code, child_signals=[signal.SIGINT, signal.SIGTERM]): - LOG.info('Exitting process: signalling children.') - - for signum in child_signals: - _signal_child_processes(signum, timeout=_SIGNAL_TIMEOUT) - - _signal_child_processes(signal.SIGKILL, recursive=True, - timeout=_SIGNAL_TIMEOUT) - - LOG.info('Children killed, exiting with code %d', exit_code) os._exit(exit_code) - - -def _signal_child_processes(signum, recursive=False, timeout=_SIGNAL_TIMEOUT): - for child in psutil.Process(os.getpid()).get_children(recursive=recursive): - child.send_signal(signum) - - _wait_children(timeout, recursive=recursive) - - -def _wait_children(timeout, recursive=False): - final_time = time.time() + timeout - for child in psutil.Process(os.getpid()).get_children(recursive=recursive): - try: - child.wait(max(0, final_time - time.time())) - except psutil.TimeoutExpired: - break diff --git a/ptero_petri/implementation/util/signal_handlers.py b/ptero_petri/implementation/util/signal_handlers.py index 36b13f6..562f3d6 100644 --- a/ptero_petri/implementation/util/signal_handlers.py +++ b/ptero_petri/implementation/util/signal_handlers.py @@ -8,11 +8,11 @@ def setup_standard_signal_handlers(): - setup_exit_handler(signal.SIGTERM, [signal.SIGTERM, signal.SIGALRM]) + setup_exit_handler(signal.SIGTERM) -def setup_exit_handler(signum, child_signals): +def setup_exit_handler(signum): def _handler(signum, frame): LOG.critical('Received signal %d: %s', signum, frame) - exit_process(exit_codes.UNKNOWN_ERROR, child_signals=child_signals) + exit_process(exit_codes.UNKNOWN_ERROR) signal.signal(signum, _handler) From 5260f876ffda085b2a54fd9d1be4462c823a0f81 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:37:16 -0500 Subject: [PATCH 26/34] send SIGIN to honcho first --- tests/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index fac0787..b7ee4b7 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -77,6 +77,7 @@ def cleanup(): descendents.update(get_descendents()) try: + instance.send_signal(signal.SIGINT) instance.wait(timeout=2) except psutil.TimeoutExpired: pass @@ -86,8 +87,6 @@ def cleanup(): time.sleep(3) signal_processes(descendents.values(), signal.SIGKILL) - - instance.send_signal(signal.SIGINT) else: sys.stderr.write('Unexpected exit of services: code = (%s)\n' % ec) From 07c397fc147dc4e6c48dc00f36fff265df881887 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:43:26 -0500 Subject: [PATCH 27/34] make descendents a local variable --- tests/__init__.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index b7ee4b7..bd8ad40 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -10,7 +10,6 @@ instance = None -descendents = {} def mkdir_p(path): @@ -53,8 +52,6 @@ def setUp(): time.sleep(wait_time()) if instance.poll() is not None: raise RuntimeError("honcho instance terminated prematurely") - else: - descendents = get_descendents() def signal_processes(processes, sig): signaled_someone = False @@ -68,13 +65,12 @@ def signal_processes(processes, sig): return signaled_someone def get_descendents(): - processes = psutil.Process(instance.pid).get_children(recursive=True) - return dict([(x.pid, x) for x in processes]) + return psutil.Process(instance.pid).get_children(recursive=True) def cleanup(): ec = instance.poll() if ec is None: - descendents.update(get_descendents()) + descendents = get_descendents() try: instance.send_signal(signal.SIGINT) @@ -82,11 +78,11 @@ def cleanup(): except psutil.TimeoutExpired: pass - if not signal_processes(descendents.values(), signal.SIGINT): + if not signal_processes(descendents, signal.SIGINT): return time.sleep(3) - signal_processes(descendents.values(), signal.SIGKILL) + signal_processes(descendents, signal.SIGKILL) else: sys.stderr.write('Unexpected exit of services: code = (%s)\n' % ec) From a687a690f21724e1d78a63aed0ff3ed9ccb3080e Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:44:04 -0500 Subject: [PATCH 28/34] move send_signal outside of try block --- tests/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/__init__.py b/tests/__init__.py index bd8ad40..594e398 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -72,8 +72,8 @@ def cleanup(): if ec is None: descendents = get_descendents() + instance.send_signal(signal.SIGINT) try: - instance.send_signal(signal.SIGINT) instance.wait(timeout=2) except psutil.TimeoutExpired: pass From 91f3c6cde08269ba12c40f3c6c6bb7d35dc99e41 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:44:52 -0500 Subject: [PATCH 29/34] assume that honcho hasn't died It should be OK for tests to fail if honcho mysteriously disappears. The previous case of honcho disappearing was because a unit test was sending signals to all children. In that case, running the tests in a different order would have caused them to fail anyway. --- tests/__init__.py | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 594e398..8bb0526 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -68,23 +68,19 @@ def get_descendents(): return psutil.Process(instance.pid).get_children(recursive=True) def cleanup(): - ec = instance.poll() - if ec is None: - descendents = get_descendents() + descendents = get_descendents() - instance.send_signal(signal.SIGINT) - try: - instance.wait(timeout=2) - except psutil.TimeoutExpired: - pass + instance.send_signal(signal.SIGINT) + try: + instance.wait(timeout=2) + except psutil.TimeoutExpired: + pass - if not signal_processes(descendents, signal.SIGINT): - return + if not signal_processes(descendents, signal.SIGINT): + return - time.sleep(3) - signal_processes(descendents, signal.SIGKILL) - else: - sys.stderr.write('Unexpected exit of services: code = (%s)\n' % ec) + time.sleep(3) + signal_processes(descendents, signal.SIGKILL) # NOTE If this doesn't run then honcho will be orphaned... From 0a939afa32f92baeb04c5e266538a9ef5bbab659 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:50:49 -0500 Subject: [PATCH 30/34] test with multiple orchestrators --- tests/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 8bb0526..5b0f239 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -6,7 +6,7 @@ import time -NUM_WORKERS = 4 +NUM_ORCHESTRATORS = 2 instance = None @@ -35,7 +35,8 @@ def procfile_path(): return os.path.join(this_dir(), 'scripts', 'Procfile') def service_command_line(): - return ['honcho', '-f', procfile_path(), 'start'] + return ['honcho', '-f', procfile_path(), 'start', + '-c', 'orchestrator=%d' % NUM_ORCHESTRATORS] def setUp(): From 5485cb606ac3ce2adbd7214457e3a70236550ef2 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 08:57:35 -0500 Subject: [PATCH 31/34] travis-ci: print logs to screen --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 07030bf..046f66c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,3 +11,7 @@ script: after_success: - pip install coveralls - coveralls + +after_script: + - ps -efl > var/log/ps.out + - bash -c 'for f in var/log/*; do echo; echo "============================================"; echo $f; echo "============================================"; cat $f; done' From 629859aa7ca01da22da58224fe2c5f9ca03c98f2 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 10:31:06 -0500 Subject: [PATCH 32/34] wait for callback server to start up in tests --- tests/api/v1/generator/base_case.py | 13 ++++++++++++- tests/api/v1/generator/callback_webserver.py | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/api/v1/generator/base_case.py b/tests/api/v1/generator/base_case.py index cad0089..a380ed7 100644 --- a/tests/api/v1/generator/base_case.py +++ b/tests/api/v1/generator/base_case.py @@ -1,3 +1,4 @@ +from ptero_petri.implementation.petri.webhooks import _retry as retry import abc import collections import errno @@ -157,7 +158,7 @@ def _assemble_callback_url(self, callback_name, request_data): return urlparse.urlunparse(( 'http', 'localhost:%d' % self.callback_port, - '/' + callback_name, + '/callbacks/' + callback_name, '', urllib.urlencode(request_data), '', @@ -197,6 +198,16 @@ def _start_callback_receipt_webserver(self): '--port', str(self.callback_port), ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + self._wait_for_callback_webserver() + + def _wait_for_callback_webserver(self): + response = retry(requests.get, self._callback_ping_url()) + if response.status_code != 200: + raise RuntimeError('Failed to spin up callback webserver: %s' + % response.text) + + def _callback_ping_url(self): + return 'http://localhost:%d/ping' % self.callback_port def _stop_callback_receipt_webserver(self): _stop_subprocess(self._callback_webserver) diff --git a/tests/api/v1/generator/callback_webserver.py b/tests/api/v1/generator/callback_webserver.py index 7e46c64..b519aa5 100755 --- a/tests/api/v1/generator/callback_webserver.py +++ b/tests/api/v1/generator/callback_webserver.py @@ -26,7 +26,12 @@ def parse_arguments(): app = Flask(__name__) -@app.route('/', methods=['PUT']) +@app.route('/ping', methods=['GET']) +def ping(): + return 'PONG' + + +@app.route('/callbacks/', methods=['PUT']) def log_request(callback_name): try: print callback_name From 17d0c4ed4038080e5cac00e6ea9341e5c96ef142 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 11:00:28 -0500 Subject: [PATCH 33/34] increase wait time for honcho to exit --- tests/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/__init__.py b/tests/__init__.py index 5b0f239..d40eefb 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -73,7 +73,7 @@ def cleanup(): instance.send_signal(signal.SIGINT) try: - instance.wait(timeout=2) + instance.wait(timeout=10) except psutil.TimeoutExpired: pass From 4d701d69955ca64a0d782656dac05bf5849257ab Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Wed, 11 Jun 2014 11:02:00 -0500 Subject: [PATCH 34/34] simplify sigterm wrapper --- tests/scripts/sigterm_wrapper | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/scripts/sigterm_wrapper b/tests/scripts/sigterm_wrapper index f14a770..6f53c4f 100755 --- a/tests/scripts/sigterm_wrapper +++ b/tests/scripts/sigterm_wrapper @@ -21,14 +21,8 @@ def term_handler(signum, frame): sys.stderr.write('Sending SIGINT to wrapped coverage process') child_process.send_signal(signal.SIGINT) - def kill_child(signum, frame): - if child_process.poll() is None: - child_process.kill() + sys.exit(1) - signal.signal(signal.SIGALRM, kill_child) - signal.alarm(10) - -signal.signal(signal.SIGINT, term_handler) signal.signal(signal.SIGTERM, term_handler)