diff --git a/src/qlever/commands/add_text_index.py b/src/qlever/commands/add_text_index.py index 6735c722..df250287 100644 --- a/src/qlever/commands/add_text_index.py +++ b/src/qlever/commands/add_text_index.py @@ -80,10 +80,8 @@ def execute(self, args) -> bool: if args.show: return True - # When running natively, check if the binary exists and works. - if args.system == "native": - if not binary_exists(args.index_binary, "index-binary"): - return False + if not binary_exists(args.index_binary, "index-binary", args): + return False # Check if text index files already exist. existing_text_index_files = get_existing_index_files( diff --git a/src/qlever/commands/index.py b/src/qlever/commands/index.py index 26829659..44b3ea78 100644 --- a/src/qlever/commands/index.py +++ b/src/qlever/commands/index.py @@ -273,10 +273,8 @@ def execute(self, args) -> bool: if args.show: return True - # When running natively, check if the binary exists and works. - if args.system == "native": - if not binary_exists(args.index_binary, "index-binary"): - return False + if not binary_exists(args.index_binary, "index-binary", args): + return False # Check if all of the input files exist. for pattern in shlex.split(args.input_files): diff --git a/src/qlever/commands/start.py b/src/qlever/commands/start.py index 67944c01..f55abe6d 100644 --- a/src/qlever/commands/start.py +++ b/src/qlever/commands/start.py @@ -218,10 +218,8 @@ def execute(self, args) -> bool: SettingsCommand().execute(args) return True - # When running natively, check if the binary exists and works. - if args.system == "native": - if not binary_exists(args.server_binary, "server-binary"): - return False + if not binary_exists(args.server_binary, "server-binary", args): + return False # Check if a QLever server is already running on this port. if is_qlever_server_alive(args.endpoint_url): diff --git a/src/qlever/util.py b/src/qlever/util.py index 76c2d08a..c2d19f1d 100644 --- a/src/qlever/util.py +++ b/src/qlever/util.py @@ -311,29 +311,44 @@ def stop_process_with_regex(cmdline_regex: str) -> list[bool] | None: return stop_process_results -def binary_exists(binary: str, cmd_arg: str) -> bool: +def binary_exists(binary: str, cmd_arg: str, args) -> bool: """ When a command is run natively, check if the binary exists on the system """ + from qlever.containerize import Containerize + is_containerized = args.system in Containerize.supported_systems() + cmd = f"{binary} --help" + if is_containerized: + cmd = Containerize().containerize_command( + cmd, + args.system, + "run --rm", + args.image, + "qlever.check-binary", + volumes=[("$(pwd)", "/index")], + working_directory="/index", + ) + try: - run_command(f"{binary} --help") + run_command(cmd) return True except Exception as e: - log.error( - f'Running "{binary}" failed, ' - f"set `--{cmd_arg}` to a different binary or " - f"set `--system to a container system`" - ) - log.info("") - log.info(f"The error message was: {e}") - if binary == "qlever-index" or binary == "qlever-server": - log.info("") - log.warning( + if is_containerized and (binary == "qlever-index" or binary == "qlever-server"): + log.error( + f'Running "{binary}" failed. ' f"This might be because you are using a newer version of " f"the `qlever` command-line tool together with an older " f"Docker image; in that case update with " f"`docker pull adfreiburg/qlever` " ) + else: + log.error( + f'Running "{binary}" failed, ' + f"set `--{cmd_arg}` to a different binary or " + f"set `--system to a container system`" + ) + log.info("") + log.info(f"The error message was: {e}") return False diff --git a/test/qlever/commands/test_start_execute.py b/test/qlever/commands/test_start_execute.py index 10a209a3..c5e23505 100644 --- a/test/qlever/commands/test_start_execute.py +++ b/test/qlever/commands/test_start_execute.py @@ -125,11 +125,12 @@ def test_check_binary_success(mock_run_cmd): # Setup args args = MagicMock() args.server_binary = "/test/path/server_binary" + args.system = "native" # mock run_cmd as successful mock_run_cmd.return_value = "Command works" # Execute the function - result = qlever.util.binary_exists(args.server_binary, "server-binary") + result = qlever.util.binary_exists(args.server_binary, "server-binary", args) # check if run_cmd was called once with mock_run_cmd.assert_called_once_with(f"{args.server_binary} --help") assert result @@ -143,12 +144,13 @@ def test_check_binary_exception(mock_log, mock_run_cmd): # Setup args args = MagicMock() args.server_binary = "false_binary" + args.system = "native" # Simulate an exception when run_command is called mock_run_cmd.side_effect = Exception("Mocked command failure") # Execute the function - result = qlever.util.binary_exists(args.server_binary, "server-binary") + result = qlever.util.binary_exists(args.server_binary, "server-binary", args) # check if run_cmd was called once with mock_run_cmd.assert_called_once_with(f"{args.server_binary} --help") @@ -571,8 +573,10 @@ def test_execute_server_with_warmup( @patch("qlever.commands.start.Containerize.supported_systems") @patch("qlever.commands.start.wrap_command_in_container") @patch("qlever.commands.start.construct_command") + @patch("qlever.commands.start.binary_exists") def test_execute_containerize_and_description( self, + mock_binary_exists, mock_construct_cl, mock_run_containerize, mock_containerize, @@ -621,6 +625,8 @@ def test_execute_containerize_and_description( # Mock Containerize mock_containerize.return_value = ["test1", "test2"] + mock_binary_exists.return_value = True + # Instantiate the StartCommand sc = StartCommand()