================
@@ -0,0 +1,221 @@
+import gc
+import logging
+import os
+from pathlib import Path
+from typing import Any, Final, Optional, TypeVar, Union, cast
+
+from lldbsuite.test.lldbtest import Base, is_exe
+
+from .dap_types import AnyResponse, ErrorResponse, Response
+from .session_helpers import DAPTestSession
+from .utils import DebugAdapter, DebugAdapterOptions
+
+
+def strtobool(val: str) -> bool:
+ """Convert a string representation of truth to a bool following LLVM's CLI
argument parsing."""
+
+ val = val.lower()
+ if val in {"false", "0", "no", "off"}:
+ return False
+ return True
+
+
+T = TypeVar("T")
+
+
+class DAPTestCaseBase(Base):
+ """Base test case for DAP tests"""
+
+ NO_DEBUG_INFO_TESTCASE = True
+ DEFAULT_TIMEOUT: Final[float] = 500.0 if "ASAN_OPTIONS" in os.environ else
50.0
+
+ USE_DEFAULT_DEBUG_ADAPTER: bool = True
+ """Subclasses can set this to true to avoid creating a debug adapter is
will not be used."""
+
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.run_as_server: bool = strtobool(os.getenv("LLDBDAP_RUN_AS_SERVER",
"false"))
+
+ def setUp(self):
+ super().setUp()
+ self.setUpBaseLogging()
+
+ self._debug_adapter_count: int = 0
+ if self.USE_DEFAULT_DEBUG_ADAPTER:
+ self.__create_default_debug_adapter()
+
+ def setUpBaseLogging(self):
+ self.logger = logging.getLogger(f"lldb_dap.{__name__}")
+ self.logger.propagate = False
+ self.logger.setLevel(logging.DEBUG)
+
+ log_path = f"{self.getLogBasenameForCurrentTest()}-test_dap.log"
+ handler = logging.FileHandler(log_path, mode="w")
+
+ # The Log name gets quite long and becomes noise. use the last log
scope.
+ class _ShortNameFormatter(logging.Formatter):
+ def format(self, record: logging.LogRecord) -> str:
+ record.short_name = record.name.rsplit(".", 1)[-1]
+ return super().format(record)
+
+ handler.setFormatter(
+ _ShortNameFormatter(
+ "%(asctime)s.%(msecs)03d %(levelname)-5s (%(short_name)s)
%(message)s",
+ datefmt="%H:%M:%S",
+ )
+ )
+ self.logger.addHandler(handler)
+
+ def close_log():
+ self.logger.removeHandler(handler)
+ handler.close()
+
+ self.addTearDownHook(close_log)
+
+ def tearDown(self):
+ gc.collect()
+ super().tearDown()
+
+ def __create_default_debug_adapter(self):
+ self.assertFalse(hasattr(self, "adapter"), "A default adapter already
exists.")
+
+ if self.run_as_server:
+ self.adapter = self.create_server_debug_adapter(
+ DebugAdapterOptions(cwd=self.getBuildDir()),
+ connection="listen://localhost:0",
+ connection_timeout=10,
+ )
+ else:
+ self.adapter = self.create_stdio_debug_adapter(
+ DebugAdapterOptions(cwd=self.getBuildDir())
+ )
+
+ def create_session(
+ self,
+ adapter: Optional[DebugAdapter] = None,
+ disconnect_automatically: Optional[bool] = None,
+ ) -> DAPTestSession:
+ if adapter is None:
+ self.assertIsNotNone(self.adapter, "expected we already have an
adapter.")
+ adapter = self.adapter
+ self.assertTrue(adapter.is_alive, "expected adapter process is alive.")
+
+ if adapter.is_server and disconnect_automatically is not None:
----------------
da-viper wrote:
> Why isn't disconnect_automatically supported for a server?
Initially the clean up also terminates the adapter. so when I was migrating
`TestDAP_server` the test fails. because it killed the adapter. this is no
longer case so It should now work.
> The disconnect request should be independent of the server running, right?
Now. It is.
https://github.com/llvm/llvm-project/pull/203978
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits