From: Kienan Stewart Date: Wed, 21 Feb 2024 13:57:19 +0000 (-0500) Subject: tests: Add mechanism to start relayd in python testing environment X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=45ce5eede99b4bd47067cd235629291540182fb8;p=lttng-tools.git tests: Add mechanism to start relayd in python testing environment Change-Id: I787528c4d281d1047d1ab119bde86c95decb9cca Signed-off-by: Kienan Stewart Signed-off-by: Jérémie Galarneau --- diff --git a/tests/utils/lttngtest/environment.py b/tests/utils/lttngtest/environment.py index 60c42f51c..e51f5eb66 100644 --- a/tests/utils/lttngtest/environment.py +++ b/tests/utils/lttngtest/environment.py @@ -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: diff --git a/tests/utils/lttngtest/lttng.py b/tests/utils/lttngtest/lttng.py index 24b95b0a7..3598cc940 100644 --- a/tests/utils/lttngtest/lttng.py +++ b/tests/utils/lttngtest/lttng.py @@ -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) diff --git a/tests/utils/lttngtest/lttngctl.py b/tests/utils/lttngtest/lttngctl.py index c62e74f47..5b937dc8a 100644 --- a/tests/utils/lttngtest/lttngctl.py +++ b/tests/utils/lttngtest/lttngctl.py @@ -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