diff --git a/rsconnect/api.py b/rsconnect/api.py index 33661da8..606489d0 100644 --- a/rsconnect/api.py +++ b/rsconnect/api.py @@ -3000,7 +3000,7 @@ def delete_runtime_cache(self, language: str, version: str, image_name: str, dry print("Dry run finished") return result, None else: - (_, task) = self.client.wait_for_task(result["task_id"], connect_logger.info, raise_on_error=False) + (_, task) = self.client.wait_for_task(result["task_id"], connect_logger.info) return result, task diff --git a/tests/test_main_system_caches.py b/tests/test_main_system_caches.py index 7cc58b89..5425a208 100644 --- a/tests/test_main_system_caches.py +++ b/tests/test_main_system_caches.py @@ -117,6 +117,66 @@ def test_system_caches_delete_happy_path(self): self.assertEqual(body["version"], "1.2.3") self.assertEqual(body["image_name"], "Local") + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_system_caches_delete_task_failed(self): + """A task that finishes with a non-zero code is surfaced as exit code 1.""" + register_server_validation_uris(CONNECT_SERVER) + httpretty.register_uri( + httpretty.DELETE, + f"{CONNECT_SERVER}/__api__/v1/system/caches/runtime", + status=200, + body=json.dumps( + {"language": "Python", "version": "1.2.3", "image_name": "Local", "dry_run": False, "task_id": "abc123"} + ), + adding_headers={"Content-Type": "application/json"}, + ) + httpretty.register_uri( + httpretty.GET, + f"{CONNECT_SERVER}/__api__/v1/tasks/abc123", + body=json.dumps( + { + "id": "abc123", + "output": [], + "result": {"type": "", "data": ""}, + "finished": True, + "code": 1, + "error": "failed to delete cache", + "last": 0, + } + ), + adding_headers={"Content-Type": "application/json"}, + ) + + runner = CliRunner() + args = ["system", "caches", "delete", "--language", "Python", "--version", "1.2.3", "--image-name", "Local"] + apply_common_args(args, server=CONNECT_SERVER, key=API_KEY) + result = runner.invoke(cli, args) + + self.assertEqual(result.exit_code, 1, result.output) + self.assertRegex(result.output, "Task exited with status 1.") + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_system_caches_delete_dry_run(self): + """A dry run has no task to wait for and exits 0.""" + register_server_validation_uris(CONNECT_SERVER) + httpretty.register_uri( + httpretty.DELETE, + f"{CONNECT_SERVER}/__api__/v1/system/caches/runtime", + status=200, + body=json.dumps( + {"language": "Python", "version": "1.2.3", "image_name": "Local", "dry_run": True, "task_id": None} + ), + adding_headers={"Content-Type": "application/json"}, + ) + + runner = CliRunner() + args = ["system", "caches", "delete", "--language", "Python", "--version", "1.2.3", "--image-name", "Local"] + args.append("--dry-run") + apply_common_args(args, server=CONNECT_SERVER, key=API_KEY) + result = runner.invoke(cli, args) + + self.assertEqual(result.exit_code, 0, result.output) + def test_system_caches_delete_missing_all_flags(self): """Omitting both --language and --version yields exit code 2 (Click validation).""" runner = CliRunner()