tests: Add mechanism to start relayd in python testing environment
authorKienan Stewart <kstewart@efficios.com>
Wed, 21 Feb 2024 13:57:19 +0000 (08:57 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 1 Mar 2024 19:30:19 +0000 (14:30 -0500)
Change-Id: I787528c4d281d1047d1ab119bde86c95decb9cca
Signed-off-by: Kienan Stewart <kstewart@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
tests/utils/lttngtest/environment.py
tests/utils/lttngtest/lttng.py
tests/utils/lttngtest/lttngctl.py

index 60c42f51cb472bb89b3aa1953c9a4a0ba65e3007..e51f5eb66da533cc36c6dde3ec2d8e235c7636fd 100644 (file)
@@ -375,6 +375,7 @@ class _Environment(logger._Logger):
         self,
         with_sessiond,  # type: bool
         log=None,  # type: Optional[Callable[[str], None]]
+        with_relayd=False,  # type: bool
     ):
         super().__init__(log)
         signal.signal(signal.SIGTERM, self._handle_termination_signal)
@@ -389,6 +390,11 @@ class _Environment(logger._Logger):
             "lttng_test_env_home"
         )  # type: Optional[TemporaryDirectory]
 
+        self._relayd = (
+            self._launch_lttng_relayd() if with_relayd else None
+        )  # type: Optional[subprocess.Popen[bytes]]
+        self._relayd_output_consumer = None
+
         self._sessiond = (
             self._launch_lttng_sessiond() if with_sessiond else None
         )  # type: Optional[subprocess.Popen[bytes]]
@@ -405,6 +411,21 @@ class _Environment(logger._Logger):
         # type: () -> pathlib.Path
         return self._project_root / "src" / "bin" / "lttng" / "lttng"
 
+    @property
+    def lttng_relayd_control_port(self):
+        # type: () -> int
+        return 5400
+
+    @property
+    def lttng_relayd_data_port(self):
+        # type: () -> int
+        return 5401
+
+    @property
+    def lttng_relayd_live_port(self):
+        # type: () -> int
+        return 5402
+
     def create_temporary_directory(self, prefix=None):
         # type: (Optional[str]) -> pathlib.Path
         # Simply return a path that is contained within LTTNG_HOME; it will
@@ -440,6 +461,53 @@ class _Environment(logger._Logger):
 
         return unpacked_vars
 
+    def _launch_lttng_relayd(self):
+        # type: () -> Optional[subprocess.Popen]
+        relayd_path = (
+            self._project_root / "src" / "bin" / "lttng-relayd" / "lttng-relayd"
+        )
+        if os.environ.get("LTTNG_TEST_NO_RELAYD", "0") == "1":
+            # Run without a relay daemon; the user may be running one
+            # under gdb, for example.
+            return None
+
+        relayd_env_vars = os.environ.get("LTTNG_RELAYD_ENV_VARS")
+        relayd_env = os.environ.copy()
+        if relayd_env_vars:
+            self._log("Additional lttng-relayd environment variables:")
+            for name, value in self._unpack_env_vars(relayd_env_vars):
+                self._log("{}={}".format(name, value))
+                relayd_env[name] = value
+
+        assert self._lttng_home is not None
+        relayd_env["LTTNG_HOME"] = str(self._lttng_home.path)
+        self._log(
+            "Launching relayd with LTTNG_HOME='${}'".format(str(self._lttng_home.path))
+        )
+        process = subprocess.Popen(
+            [
+                str(relayd_path),
+                "-C",
+                "tcp://0.0.0.0:{}".format(self.lttng_relayd_control_port),
+                "-D",
+                "tcp://0.0.0.0:{}".format(self.lttng_relayd_data_port),
+                "-L",
+                "tcp://localhost:{}".format(self.lttng_relayd_live_port),
+            ],
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT,
+            env=relayd_env,
+        )
+
+        if self._logging_function:
+            self._relayd_output_consumer = ProcessOutputConsumer(
+                process, "lttng-relayd", self._logging_function
+            )
+            self._relayd_output_consumer.daemon = True
+            self._relayd_output_consumer.start()
+
+        return process
+
     def _launch_lttng_sessiond(self):
         # type: () -> Optional[subprocess.Popen]
         is_64bits_host = sys.maxsize > 2**32
@@ -577,6 +645,15 @@ class _Environment(logger._Logger):
             self._log("Session daemon killed")
             self._sessiond = None
 
+        if self._relayd and self._relayd.poll() is None:
+            self._relayd.terminate()
+            self._relayd.wait()
+            if self._relayd_output_consumer:
+                self._relayd_output_consumer.join()
+                self._relayd_output_consumer = None
+            self._log("Relayd killed")
+            self._relayd = None
+
         self._lttng_home = None
 
     def __del__(self):
@@ -584,9 +661,9 @@ class _Environment(logger._Logger):
 
 
 @contextlib.contextmanager
-def test_environment(with_sessiond, log=None):
-    # type: (bool, Optional[Callable[[str], None]]) -> Iterator[_Environment]
-    env = _Environment(with_sessiond, log)
+def test_environment(with_sessiond, log=None, with_relayd=False):
+    # type: (bool, Optional[Callable[[str], None]], bool) -> Iterator[_Environment]
+    env = _Environment(with_sessiond, log, with_relayd)
     try:
         yield env
     finally:
index 24b95b0a7158222d3b12f361afe1a1bc8f8fb500..3598cc940ba5bf3c686d314aa5d80d9fbd5c4273 100644 (file)
@@ -672,20 +672,24 @@ class LTTngClient(logger._Logger, lttngctl.Controller):
         else:
             return out.decode("utf-8")
 
-    def create_session(self, name=None, output=None):
-        # type: (Optional[str], Optional[lttngctl.SessionOutputLocation]) -> lttngctl.Session
+    def create_session(self, name=None, output=None, live=False):
+        # type: (Optional[str], Optional[lttngctl.SessionOutputLocation], bool) -> lttngctl.Session
         name = name if name else lttngctl.Session._generate_name()
 
         if isinstance(output, lttngctl.LocalSessionOutputLocation):
             output_option = "--output '{output_path}'".format(output_path=output.path)
+        elif isinstance(output, lttngctl.NetworkSessionOutputLocation):
+            output_option = "--set-url '{}'".format(output.url)
         elif output is None:
             output_option = "--no-output"
         else:
             raise TypeError("LTTngClient only supports local or no output")
 
         self._run_cmd(
-            "create '{session_name}' {output_option}".format(
-                session_name=name, output_option=output_option
+            "create '{session_name}' {output_option} {live_option}".format(
+                session_name=name,
+                output_option=output_option,
+                live_option="--live" if live else "",
             )
         )
         return _Session(self, name, output)
index c62e74f47b3747028e270ac0af1578966b48f8b0..5b937dc8acfd8cecc885fdb47af322f75236c91e 100644 (file)
@@ -432,6 +432,17 @@ class LocalSessionOutputLocation(SessionOutputLocation):
         return self._path
 
 
+class NetworkSessionOutputLocation(SessionOutputLocation):
+    def __init__(self, set_url):
+        # type (str)
+        self._set_url = set_url
+
+    @property
+    def url(self):
+        # type: () -> str
+        return self._set_url
+
+
 class ProcessAttributeTracker(abc.ABC):
     """
     Process attribute tracker used to filter before the evaluation of event
This page took 0.028801 seconds and 4 git commands to generate.