Skip to content

Commit

Permalink
feat(cli): add log message for no output in download-output command
Browse files Browse the repository at this point in the history
Signed-off-by: Gahyun Suh <gahyusuh@dev-dsk-gahyusuh-2a-387e0b51.us-west-2.amazon.com>
  • Loading branch information
Gahyun Suh committed Nov 8, 2023
1 parent bc60165 commit 0a52944
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
16 changes: 16 additions & 0 deletions src/deadline/client/cli/_groups/job_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ def _download_job_output(

output_paths_by_root = job_output_downloader.get_output_paths_by_root()

# If no output paths were found, log a message and exit.
if output_paths_by_root == {}:
click.echo(_get_no_output_message(is_json_format))
return

# Check if the asset roots came from different OS. If so, prompt users to
# select alternative root paths to download to, (regardless of the auto-accept.)
asset_roots = list(output_paths_by_root.keys())
Expand Down Expand Up @@ -403,6 +408,17 @@ def _get_start_message(
return f"Downloading output from Job {job_name!r} Step {step_id} Task {task_id}"


def _get_no_output_message(is_json_format: bool) -> str:
msg = (
"No output files to download. Please check the job status and"
" ensure that it has completed without issues."
)
if is_json_format:
return _get_json_line(JSON_MSG_TYPE_SUMMARY, msg)
else:
return msg


def _get_mismatch_os_root_warning(root: str, is_json_format: bool) -> str:
if is_json_format:
return _get_json_line(JSON_MSG_TYPE_PATH, [root])
Expand Down
4 changes: 2 additions & 2 deletions src/deadline/job_attachments/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,12 @@ def download_file(
if not s3_client:
s3_client = get_s3_client(session=session)

# The modified time in the manifest is in microseconds, but utime requires the time be expressed in seconds.
# The modified time in the manifest is in microseconds, but utime requires the time be expressed in seconds.
modified_time_override = file.mtime / 1000000 # type: ignore[attr-defined]

file_bytes = file.size

# Python will handle the path seperator '/' correctly on every platform.
# Python will handle the path separator '/' correctly on every platform.
local_file_name = Path(local_download_dir).joinpath(file.path)

s3_key = f"{cas_prefix}/{file.hash}" if cas_prefix else file.hash
Expand Down
70 changes: 67 additions & 3 deletions test/unit/deadline_client/cli/test_cli_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ def test_cli_job_download_output_stdout_with_only_required_input(
fresh_deadline_config, tmp_path: Path
):
"""
Tests whether the ouptut messages printed to stdout match expected messages
Tests whether the output messages printed to stdout match expected messages
when download-output command is executed.
"""
with patch.object(api._session, "get_deadline_endpoint_url") as session_endpoint:
Expand Down Expand Up @@ -356,12 +356,76 @@ def test_cli_job_download_output_stdout_with_only_required_input(
assert result.exit_code == 0


def test_cli_job_dowuload_output_stdout_with_json_format(
def test_cli_job_download_no_output_stdout(fresh_deadline_config, tmp_path: Path):
"""
Tests whether the output messages printed to stdout match expected messages
when executing download-output command for a job that don't have any output yet.
"""
with patch.object(api._session, "get_deadline_endpoint_url") as session_endpoint:
session_endpoint.return_value = "fake-endpoint-url"
config.set_setting("defaults.farm_id", MOCK_FARM_ID)
config.set_setting("defaults.queue_id", MOCK_QUEUE_ID)

with patch.object(api, "get_boto3_client") as boto3_client_mock, patch.object(
job_group, "OutputDownloader"
) as MockOutputDownloader, patch.object(
job_group, "_get_conflicting_filenames", return_value=[]
), patch.object(
job_group, "round", return_value=0
), patch.object(
api, "get_queue_user_boto3_session"
):
mock_download = MagicMock()
MockOutputDownloader.return_value.download_job_output = mock_download
MockOutputDownloader.return_value.get_output_paths_by_root.return_value = {}

mock_host_path_format_name = PathFormat.get_host_path_format_string()
boto3_client_mock().get_job.return_value = {
"name": "Mock Job",
"attachments": {
"manifests": [
{
"rootPath": "/root/path",
"rootPathFormat": PathFormat(mock_host_path_format_name),
"outputRelativeDirectories": ["."],
}
],
},
}
boto3_client_mock().get_queue.side_effect = [MOCK_GET_QUEUE_RESPONSE]

runner = CliRunner()
result = runner.invoke(
main,
["job", "download-output", "--job-id", MOCK_JOB_ID, "--output", "verbose"],
input="",
)

MockOutputDownloader.assert_called_once_with(
s3_settings=JobAttachmentS3Settings(**MOCK_GET_QUEUE_RESPONSE["jobAttachmentSettings"]), # type: ignore
farm_id=MOCK_FARM_ID,
queue_id=MOCK_QUEUE_ID,
job_id=MOCK_JOB_ID,
step_id=None,
task_id=None,
session=ANY,
)

assert (
"""Downloading output from Job 'Mock Job'
No output files to download. Please check the job status and ensure that it has completed without issues.
"""
in result.output
)
assert result.exit_code == 0


def test_cli_job_download_output_stdout_with_json_format(
fresh_deadline_config,
tmp_path: Path,
):
"""
Tests whether the ouptut messages printed to stdout match expected messages
Tests whether the output messages printed to stdout match expected messages
when download-output command is executed with `--output json` option.
"""
with patch.object(api._session, "get_deadline_endpoint_url") as session_endpoint:
Expand Down

0 comments on commit 0a52944

Please sign in to comment.