This is an automated email from the ASF dual-hosted git repository.

jdanek pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git

commit e253b1daad0a1c020a0ad8c213db5525ab72707a
Author: Jiri DanÄ›k <[email protected]>
AuthorDate: Thu Mar 10 18:31:57 2022 +0100

    DISPATCH-1689 Wait for startup log line to ensure router is fully started 
in tests (#140)
---
 src/server.c         |  2 +-
 tests/system_test.py | 55 +++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/src/server.c b/src/server.c
index 7729e293..807fe783 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1512,7 +1512,7 @@ void qd_server_run(qd_dispatch_t *qd)
     assert(qd_server->container); // Server can't run without a container
     qd_log(qd_server->log_source,
            QD_LOG_NOTICE, "Operational, %d Threads Running (process ID %ld)",
-           qd_server->thread_count, (long)getpid());
+           qd_server->thread_count, (long)getpid()); // Log message is matched 
in system_tests
 
     const uintmax_t ram_size = qd_platform_memory_size();
     const uint64_t  vm_size = qd_router_memory_usage();
diff --git a/tests/system_test.py b/tests/system_test.py
index 34afa255..a77c1b1f 100755
--- a/tests/system_test.py
+++ b/tests/system_test.py
@@ -28,36 +28,34 @@ Features:
 - Sundry other tools.
 """
 
-import logging
-from typing import Callable, List, Optional, Tuple
-
 import errno
-import sys
-import time
-
-import __main__
+import json
+import logging
 import os
+import pathlib
+import queue as Queue
 import random
 import re
 import shutil
 import socket
 import subprocess
+import sys
+import time
+import unittest
+import uuid
 from copy import copy
 from datetime import datetime
 from subprocess import PIPE, STDOUT
-
-import queue as Queue
-from threading import Thread
 from threading import Event
-import json
-import uuid
+from threading import Thread
+from typing import Callable, TextIO, List, Optional, Tuple
 
-import unittest
+import __main__
 
 import proton
 import proton.utils
-from proton import Message
 from proton import Delivery
+from proton import Message
 from proton.handlers import MessagingHandler
 from proton.reactor import AtLeastOnce, Container
 from proton.reactor import AtMostOnce
@@ -671,12 +669,40 @@ class Qdrouterd(Process):
             assert retry(lambda: self.is_connected(port=c['port'], 
host=self.get_host(c.get('protocolFamily'))),
                          **retry_kwargs), "Port not connected %s" % c['port']
 
+    def wait_startup_message(self, **retry_kwargs):
+        """Wait for router startup message to be printed into logfile
+
+        This ensures that the router installs its signal handlers, avoiding
+        a router failure with return code -15 upon premature SIGTERM 
(DISPATCH-1689)
+
+        e.g. 2022-03-03 19:08:13.608655 +0100 SERVER (notice) Operational, 4 
Threads Running (process ID 2190110)
+        """
+        def _is_startup_line_present(f: TextIO) -> bool:
+            for line in f:
+                m = re.search(r'SERVER \(notice\) Operational, (\d+) Threads 
Running \(process ID (\d+)\)', line)
+                if m:
+                    return True
+            return False
+
+        logfile_path = self.logfile_path
+        # system_tests_log_level_update filters SERVER module logs to a 
separate file
+        server_log = [l for l in self.config if (l[0] == 'log' and 
l[1]['module'] == 'SERVER')]
+        if server_log:
+            logfile_path = os.path.join(self.outdir, 
server_log[0][1].get('outputFile'))
+
+        assert retry(lambda: pathlib.Path(logfile_path).is_file(), 
**retry_kwargs), \
+            f"Router logfile {logfile_path} does not exist or is not a file"
+        with open(logfile_path, 'rt') as router_log:
+            assert retry(lambda: _is_startup_line_present(router_log), 
**retry_kwargs),\
+                "Router startup line not present in router log"
+
     def wait_ready(self, **retry_kwargs):
         """Wait for ports and connectors to be ready"""
         if not self._wait_ready:
             self._wait_ready = True
             self.wait_ports(**retry_kwargs)
             self.wait_connectors(**retry_kwargs)
+            self.wait_startup_message(**retry_kwargs)
         return self
 
     def is_router_connected(self, router_id, **retry_kwargs):
@@ -704,6 +730,7 @@ class Qdrouterd(Process):
 
     @property
     def logfile_path(self):
+        """Path to a DEFAULT logfile"""
         return os.path.join(self.outdir, self.logfile)
 
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to