From 571a8ca9d15a70120149e148ef1c53b7bf00a4bd Mon Sep 17 00:00:00 2001
From: Fabio Manganiello <info@fabiomanganiello.com>
Date: Wed, 24 Feb 2021 00:23:32 +0100
Subject: [PATCH] Improvements on HTTP integration test. Plus, removed
 ApplicationStoppedEvent - it's unreliable and it could be delivered when the
 bus has already been stopped

---
 platypush/__init__.py                  | 18 ++++--------
 platypush/message/event/application.py |  9 ------
 tests/context.py                       |  8 ++----
 tests/test_event_parse.py              |  4 +--
 tests/test_http.py                     | 39 ++++++++++++--------------
 5 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/platypush/__init__.py b/platypush/__init__.py
index ade16fa74..32cfc5af8 100644
--- a/platypush/__init__.py
+++ b/platypush/__init__.py
@@ -17,7 +17,7 @@ from .cron.scheduler import CronScheduler
 from .event.processor import EventProcessor
 from .logger import Logger
 from .message.event import Event
-from .message.event.application import ApplicationStartedEvent, ApplicationStoppedEvent
+from .message.event.application import ApplicationStartedEvent
 from .message.request import Request
 from .message.response import Response
 from .utils import set_thread_name
@@ -75,6 +75,8 @@ class Daemon:
         Config.init(self.config_file)
         logging.basicConfig(**Config.get('logging'))
 
+        redis_conf = Config.get('backend.redis') or {}
+        self.bus = RedisBus(on_message=self.on_message(), **redis_conf.get('redis_args', {}))
         self.no_capture_stdout = no_capture_stdout
         self.no_capture_stderr = no_capture_stderr
         self.event_processor = EventProcessor()
@@ -145,8 +147,6 @@ class Daemon:
 
     def stop_app(self):
         """ Stops the backends and the bus """
-        self.bus.post(ApplicationStoppedEvent())
-
         for backend in self.backends.values():
             backend.stop()
 
@@ -154,7 +154,7 @@ class Daemon:
         if self.cron_scheduler:
             self.cron_scheduler.stop()
 
-    def start(self):
+    def run(self):
         """ Start the daemon """
         if not self.no_capture_stdout:
             sys.stdout = Logger(logger.info)
@@ -162,12 +162,7 @@ class Daemon:
             sys.stderr = Logger(logger.warning)
 
         set_thread_name('platypush')
-
-        print('---- Starting platypush v.{}'.format(__version__))
-
-        redis_conf = Config.get('backend.redis') or {}
-        self.bus = RedisBus(on_message=self.on_message(),
-                            **redis_conf.get('redis_args', {}))
+        logger.info('---- Starting platypush v.{}'.format(__version__))
 
         # Initialize the backends and link them to the bus
         self.backends = register_backends(bus=self.bus, global_scope=True)
@@ -198,9 +193,8 @@ def main():
     """
     Platypush daemon main
     """
-
     app = Daemon.build_from_cmdline(sys.argv[1:])
-    app.start()
+    app.run()
 
 
 # vim:sw=4:ts=4:et:
diff --git a/platypush/message/event/application.py b/platypush/message/event/application.py
index 40adbc7d3..ae92a1253 100644
--- a/platypush/message/event/application.py
+++ b/platypush/message/event/application.py
@@ -10,14 +10,5 @@ class ApplicationStartedEvent(Event):
         super().__init__(*args, **kwargs)
 
 
-class ApplicationStoppedEvent(Event):
-    """
-    Event triggered when the application stops
-    """
-
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-
-
 # vim:sw=4:ts=4:et:
 
diff --git a/tests/context.py b/tests/context.py
index 313cb438f..1e3236b4d 100644
--- a/tests/context.py
+++ b/tests/context.py
@@ -1,20 +1,18 @@
 import os
 import sys
 
+from platypush.config import Config
+
 testdir = os.path.dirname(__file__)
 sys.path.insert(0, os.path.abspath(os.path.join(testdir, '..')))
 config_file = os.path.join(testdir, 'etc', 'config.yaml')
 
-from platypush.config import Config
 Config.init(config_file)
 
-import platypush
 
-
-class TestTimeoutException(RuntimeError):
+class TimeoutException(RuntimeError):
     def __init__(self, msg):
         self.msg = msg
 
 
 # vim:sw=4:ts=4:et:
-
diff --git a/tests/test_event_parse.py b/tests/test_event_parse.py
index e4bf2f627..b645ea995 100644
--- a/tests/test_event_parse.py
+++ b/tests/test_event_parse.py
@@ -1,10 +1,9 @@
-from .context import platypush
-
 import unittest
 
 from platypush.event.hook import EventCondition
 from platypush.message.event.ping import PingEvent
 
+
 class TestEventParse(unittest.TestCase):
     def setUp(self):
         self.condition = EventCondition.build({
@@ -30,4 +29,3 @@ if __name__ == '__main__':
     unittest.main()
 
 # vim:sw=4:ts=4:et:
-
diff --git a/tests/test_http.py b/tests/test_http.py
index a3d5bb80a..a3fce8224 100644
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -1,6 +1,6 @@
 import os
 
-from .context import config_file, TestTimeoutException
+from .context import config_file, TimeoutException
 
 import logging
 import requests
@@ -8,7 +8,7 @@ import sys
 import time
 import unittest
 
-from threading import Thread
+from threading import Thread, Event
 
 from platypush import Daemon
 from platypush.config import Config
@@ -22,7 +22,7 @@ class TestHttp(unittest.TestCase):
         Runs a remote command over HTTP via shell.exec plugin and gets the output """
 
     timeout = 10
-    sleep_secs = 10
+    sleep_secs = 5
     db_file = '/tmp/platypush-tests.db'
     test_user = 'platypush'
     test_pass = 'test'
@@ -33,6 +33,7 @@ class TestHttp(unittest.TestCase):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         self.app = None
+        self._app_started = Event()
 
     def setUp(self):
         logging.basicConfig(level=logging.INFO, stream=sys.stdout)
@@ -68,26 +69,24 @@ class TestHttp(unittest.TestCase):
 
         # A request with the wrong user/pass should fail.
         response = self.send_request(auth=('wrong', 'wrong'))
-        self.assertEqual(self.expected_login_redirect, response.url,
-                         'A request with wrong credentials should fail')
+        self.assertEqual(self.expected_login_redirect, response.url, 'A request with wrong credentials should fail')
 
     def start_daemon(self):
-        def _f():
-            self.app = Daemon(config_file=config_file)
-            self.app.start()
+        self.app = Daemon(config_file=config_file)
+        Thread(target=lambda: self.app.run()).start()
 
-        Thread(target=_f).start()
+    def stop_daemon(self):
+        if self.app:
+            self.app.stop_app()
 
     @staticmethod
     def on_timeout(msg):
-        def _f(): raise TestTimeoutException(msg)
+        def _f(): raise TimeoutException(msg)
 
         return _f
 
     def send_request(self, **kwargs):
-        set_timeout(seconds=self.timeout,
-                    on_timeout=self.on_timeout('Receiver response timed out'))
-
+        set_timeout(seconds=self.timeout, on_timeout=self.on_timeout('Receiver response timed out'))
         response = requests.post(
             '{}/execute'.format(self.base_url),
             json={
@@ -102,9 +101,7 @@ class TestHttp(unittest.TestCase):
         return response
 
     def register_user(self):
-        set_timeout(seconds=self.timeout,
-                    on_timeout=self.on_timeout('User registration response timed out'))
-
+        set_timeout(seconds=self.timeout, on_timeout=self.on_timeout('User registration response timed out'))
         response = requests.post('{base_url}/register?redirect={base_url}/'.format(base_url=self.base_url), data={
             'username': self.test_user,
             'password': self.test_pass,
@@ -119,11 +116,11 @@ class TestHttp(unittest.TestCase):
         return Message.build(response.json())
 
     def tearDown(self):
-        if self.app:
-            self.app.stop_app()
-
-        if os.path.isfile(self.db_file):
-            os.unlink(self.db_file)
+        try:
+            self.stop_daemon()
+        finally:
+            if os.path.isfile(self.db_file):
+                os.unlink(self.db_file)
 
 
 if __name__ == '__main__':