def server_process(tmpdir): import os.path from robotframework_ls._utils import kill_process_and_subprocesses from robotframework_ls.server_api.server__main__ import start_server_process log_file = str(tmpdir.join("robotframework_api_tests.log")) import robot env = { "PYTHONPATH": os.path.dirname(os.path.dirname(os.path.abspath(robot.__file__))) } language_server_api_process = start_server_process( args=["-vv", "--log-file=%s" % log_file], env=env) returncode = language_server_api_process.poll() assert returncode is None yield language_server_api_process returncode = language_server_api_process.poll() if returncode is None: kill_process_and_subprocesses(language_server_api_process.pid) if os.path.exists(log_file): print("--- %s contents:" % (log_file, )) with open(log_file, "r") as stream: print(stream.read())
def server_process(tmpdir, on_timeout, remote_fs_observer): from robocorp_ls_core.basic import kill_process_and_subprocesses from robotframework_ls.server_api.server__main__ import start_server_process log_file = str(tmpdir.join("robotframework_api_tests.log")) import robot env = { "PYTHONPATH": os.path.dirname(os.path.dirname(os.path.abspath(robot.__file__))) } language_server_api_process = start_server_process( args=[ "-vv", "--log-file=%s" % log_file, f"--remote-fs-observer-port={remote_fs_observer.port}", ], env=env, ) returncode = language_server_api_process.poll() assert returncode is None def write_on_finish(): import sys dirname = os.path.dirname(log_file) for f in os.listdir(dirname): if f.startswith("robotframework_api_tests") and f.endswith(".log"): full = os.path.join(dirname, f) sys.stderr.write("\n--- %s contents:\n" % (full, )) with open(full, "r") as stream: sys.stderr.write(stream.read()) on_timeout.add(write_on_finish) yield language_server_api_process on_timeout.remove(write_on_finish) returncode = language_server_api_process.poll() if returncode is None: kill_process_and_subprocesses(language_server_api_process.pid) write_on_finish()
def get_robotframework_api_client( self) -> Optional[IRobotFrameworkApiClient]: self._check_in_main_thread() workspace = self.workspace assert ( workspace ), "The workspace must be already set when getting the server api." server_process = self._server_process if server_process is not None: # If someone killed it, dispose of internal references # and create a new process. if not is_process_alive(server_process.pid): server_process = None self._dispose_server_process() if server_process is None: try: from robotframework_ls.options import Setup from robotframework_ls.server_api.client import RobotFrameworkApiClient from robotframework_ls.server_api.server__main__ import ( start_server_process, ) from robocorp_ls_core.jsonrpc.streams import ( JsonRpcStreamWriter, JsonRpcStreamReader, ) args = [] if Setup.options.verbose: args.append("-" + "v" * int(Setup.options.verbose)) if Setup.options.log_file: log_id = _next_id() # i.e.: use a log id in case we create more than one in the # same session. if log_id == 0: args.append("--log-file=" + Setup.options.log_file + self._log_extension) else: args.append("--log-file=" + Setup.options.log_file + (".%s" % (log_id, )) + self._log_extension) python_exe = self._get_python_executable() environ = self._get_environ() self._used_python_executable = python_exe self._used_environ = environ server_process = start_server_process(args=args, python_exe=python_exe, env=environ) self._server_process = server_process write_to = server_process.stdin read_from = server_process.stdout w = JsonRpcStreamWriter(write_to, sort_keys=True) r = JsonRpcStreamReader(read_from) api = self._robotframework_api_client = RobotFrameworkApiClient( w, r, server_process) log.debug( "Initializing api... (this pid: %s, api pid: %s).", os.getpid(), server_process.pid, ) api.initialize( process_id=os.getpid(), root_uri=workspace.root_uri, workspace_folders=list({ "uri": folder.uri, "name": folder.name } for folder in workspace.iter_folders()), ) config = self._config log.debug("Forwarding config to api...") if config is not None: api.forward( "workspace/didChangeConfiguration", {"settings": config.get_full_settings()}, ) # Open existing documents in the API. source: Optional[str] for document in workspace.iter_documents(): log.debug("Forwarding doc: %s to api...", document.uri) try: source = document.source except Exception: source = None api.forward( "textDocument/didOpen", { "textDocument": { "uri": document.uri, "version": document.version, "text": source, } }, ) except Exception as e: if server_process is None: log.exception( "Error starting robotframework server api (server_process=None)." ) else: exitcode = server_process.poll() if exitcode is not None: # Note: only read() if the process exited. log.exception( "Error starting robotframework server api. Exit code: %s Base exception: %s. Stderr: %s", exitcode, e, server_process.stderr.read(), ) else: log.exception( "Error (%s) starting robotframework server api (still running). Base exception: %s.", exitcode, e, ) self._dispose_server_process() finally: if server_process is not None: log.debug("Server api (%s) created pid: %s", self, server_process.pid) else: log.debug( "server_process == None in get_robotframework_api_client()" ) return self._robotframework_api_client