From 5184a24d0f05727a9777a921ac5a739b5731cc3f Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Wed, 6 May 2026 16:49:50 +0300 Subject: [PATCH 01/13] update --- src/fabric_cli/commands/jobs/fab_jobs_run.py | 3 ++- src/fabric_cli/utils/fab_cmd_job_utils.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/fabric_cli/commands/jobs/fab_jobs_run.py b/src/fabric_cli/commands/jobs/fab_jobs_run.py index 9569ede78..9142a664d 100644 --- a/src/fabric_cli/commands/jobs/fab_jobs_run.py +++ b/src/fabric_cli/commands/jobs/fab_jobs_run.py @@ -54,11 +54,12 @@ def exec_command(args: Namespace, item: Item) -> None: fab_ui.print_output_format( args, message=f"Job instance '{args.instance_id}' cancelled (async)", + data={"id": args.instance_id}, ) else: fab_ui.print_output_format( - args, message=f"Job instance '{job_instance_id}' created" + args, message=f"Job instance '{job_instance_id}' created", data={"id": job_instance_id} ) fab_ui.print_grey( f"→ To see status run 'job run-status {item.path} --id {job_instance_id}'" diff --git a/src/fabric_cli/utils/fab_cmd_job_utils.py b/src/fabric_cli/utils/fab_cmd_job_utils.py index 1e537cd30..07e860a17 100644 --- a/src/fabric_cli/utils/fab_cmd_job_utils.py +++ b/src/fabric_cli/utils/fab_cmd_job_utils.py @@ -8,6 +8,7 @@ from typing import Any, Optional from requests.structures import CaseInsensitiveDict + from fabric_cli.client import fab_api_jobs as jobs_api from fabric_cli.client.fab_api_types import ApiResponse from fabric_cli.core import fab_constant, fab_logger @@ -15,8 +16,8 @@ from fabric_cli.core.fab_types import FabricJobType from fabric_cli.core.hiearchy.fab_hiearchy import Item from fabric_cli.errors import ErrorMessages -from fabric_cli.utils.fab_http_polling_utils import get_polling_interval from fabric_cli.utils import fab_ui +from fabric_cli.utils.fab_http_polling_utils import get_polling_interval def add_item_props_to_args(args: Namespace, context: Item) -> None: @@ -94,7 +95,7 @@ def wait_for_job_completion( fab_ui.print_progress(f"Job instance status: {status}") if status == "Completed": fab_ui.print_output_format( - args, message=f"Job instance '{job_ins_id}' completed" + args, message=f"Job instance '{job_ins_id}' completed", data={"id": job_ins_id} ) else: fab_logger.log_warning( From 6a06afda7d4ab3d5172fdb034cd7cac8a06dbd20 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Wed, 6 May 2026 17:06:15 +0300 Subject: [PATCH 02/13] add change --- .changes/unreleased/optimization-20260506-170108.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/optimization-20260506-170108.yaml diff --git a/.changes/unreleased/optimization-20260506-170108.yaml b/.changes/unreleased/optimization-20260506-170108.yaml new file mode 100644 index 000000000..f20093bec --- /dev/null +++ b/.changes/unreleased/optimization-20260506-170108.yaml @@ -0,0 +1,6 @@ +kind: optimization +body: Return the job instance ID as a structured field in the JSON output of ``job run`` and ``job start`` commands +time: 2026-05-06T17:01:08.6543512+03:00 +custom: + Author: shirasassoon + AuthorLink: https://github.com/shirasassoon From 3bd174a1090a89d96c4b7d0bb888462090e0466a Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Wed, 6 May 2026 18:38:14 +0300 Subject: [PATCH 03/13] fix Co-authored-by: Copilot --- src/fabric_cli/commands/jobs/fab_jobs_run.py | 8 ++++++-- src/fabric_cli/utils/fab_cmd_job_utils.py | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/fabric_cli/commands/jobs/fab_jobs_run.py b/src/fabric_cli/commands/jobs/fab_jobs_run.py index 9142a664d..5074ece71 100644 --- a/src/fabric_cli/commands/jobs/fab_jobs_run.py +++ b/src/fabric_cli/commands/jobs/fab_jobs_run.py @@ -51,15 +51,19 @@ def exec_command(args: Namespace, item: Item) -> None: args.instance_id = job_instance_id response = jobs_api.cancel_item_job_instance(args) if response.status_code == 202: + resolved_format = getattr(args, "output_format", None) or config.get_config(con.FAB_OUTPUT_FORMAT) + job_id_data = {"id": args.instance_id} if resolved_format == "json" else None fab_ui.print_output_format( args, message=f"Job instance '{args.instance_id}' cancelled (async)", - data={"id": args.instance_id}, + data=job_id_data, ) else: + resolved_format = getattr(args, "output_format", None) or config.get_config(con.FAB_OUTPUT_FORMAT) + job_id_data = {"id": job_instance_id} if resolved_format == "json" else None fab_ui.print_output_format( - args, message=f"Job instance '{job_instance_id}' created", data={"id": job_instance_id} + args, message=f"Job instance '{job_instance_id}' created", data=job_id_data ) fab_ui.print_grey( f"→ To see status run 'job run-status {item.path} --id {job_instance_id}'" diff --git a/src/fabric_cli/utils/fab_cmd_job_utils.py b/src/fabric_cli/utils/fab_cmd_job_utils.py index 07e860a17..4ee2e1f8d 100644 --- a/src/fabric_cli/utils/fab_cmd_job_utils.py +++ b/src/fabric_cli/utils/fab_cmd_job_utils.py @@ -11,7 +11,7 @@ from fabric_cli.client import fab_api_jobs as jobs_api from fabric_cli.client.fab_api_types import ApiResponse -from fabric_cli.core import fab_constant, fab_logger +from fabric_cli.core import fab_constant, fab_logger, fab_state_config from fabric_cli.core.fab_exceptions import FabricCLIError from fabric_cli.core.fab_types import FabricJobType from fabric_cli.core.hiearchy.fab_hiearchy import Item @@ -94,8 +94,11 @@ def wait_for_job_completion( if status in ["Completed", "Cancelled", "Deduped"]: fab_ui.print_progress(f"Job instance status: {status}") if status == "Completed": + # Determine data based on output format + resolved_format = getattr(args, "output_format", None) or fab_state_config.get_config(fab_constant.FAB_OUTPUT_FORMAT) + job_id_data = {"id": job_ins_id} if resolved_format == "json" else None fab_ui.print_output_format( - args, message=f"Job instance '{job_ins_id}' completed", data={"id": job_ins_id} + args, message=f"Job instance '{job_ins_id}' completed", data=job_id_data ) else: fab_logger.log_warning( From 457c423613b6a5e8f9175db35455bf0194ef2941 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Thu, 7 May 2026 15:29:48 +0300 Subject: [PATCH 04/13] fix --- src/fabric_cli/commands/jobs/fab_jobs_run.py | 9 +++------ src/fabric_cli/utils/fab_cmd_job_utils.py | 8 ++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/fabric_cli/commands/jobs/fab_jobs_run.py b/src/fabric_cli/commands/jobs/fab_jobs_run.py index 5074ece71..b45908f0d 100644 --- a/src/fabric_cli/commands/jobs/fab_jobs_run.py +++ b/src/fabric_cli/commands/jobs/fab_jobs_run.py @@ -51,19 +51,16 @@ def exec_command(args: Namespace, item: Item) -> None: args.instance_id = job_instance_id response = jobs_api.cancel_item_job_instance(args) if response.status_code == 202: - resolved_format = getattr(args, "output_format", None) or config.get_config(con.FAB_OUTPUT_FORMAT) - job_id_data = {"id": args.instance_id} if resolved_format == "json" else None fab_ui.print_output_format( args, message=f"Job instance '{args.instance_id}' cancelled (async)", - data=job_id_data, + data={"id": args.instance_id}, + show_key_value_list=True, ) else: - resolved_format = getattr(args, "output_format", None) or config.get_config(con.FAB_OUTPUT_FORMAT) - job_id_data = {"id": job_instance_id} if resolved_format == "json" else None fab_ui.print_output_format( - args, message=f"Job instance '{job_instance_id}' created", data=job_id_data + args, message=f"Job instance '{job_instance_id}' created", data={"id": job_instance_id}, show_key_value_list=True ) fab_ui.print_grey( f"→ To see status run 'job run-status {item.path} --id {job_instance_id}'" diff --git a/src/fabric_cli/utils/fab_cmd_job_utils.py b/src/fabric_cli/utils/fab_cmd_job_utils.py index 4ee2e1f8d..7cb3b41c9 100644 --- a/src/fabric_cli/utils/fab_cmd_job_utils.py +++ b/src/fabric_cli/utils/fab_cmd_job_utils.py @@ -94,11 +94,11 @@ def wait_for_job_completion( if status in ["Completed", "Cancelled", "Deduped"]: fab_ui.print_progress(f"Job instance status: {status}") if status == "Completed": - # Determine data based on output format - resolved_format = getattr(args, "output_format", None) or fab_state_config.get_config(fab_constant.FAB_OUTPUT_FORMAT) - job_id_data = {"id": job_ins_id} if resolved_format == "json" else None fab_ui.print_output_format( - args, message=f"Job instance '{job_ins_id}' completed", data=job_id_data + args, + message=f"Job instance '{job_ins_id}' completed", + data={"id": job_ins_id}, + show_key_value_list=True, ) else: fab_logger.log_warning( From d2bf40c8296be1ba4792692106ca44071edba201 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Thu, 7 May 2026 16:42:06 +0300 Subject: [PATCH 05/13] add line --- src/fabric_cli/commands/jobs/fab_jobs_run.py | 2 ++ src/fabric_cli/utils/fab_cmd_job_utils.py | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fabric_cli/commands/jobs/fab_jobs_run.py b/src/fabric_cli/commands/jobs/fab_jobs_run.py index b45908f0d..acb64a1f1 100644 --- a/src/fabric_cli/commands/jobs/fab_jobs_run.py +++ b/src/fabric_cli/commands/jobs/fab_jobs_run.py @@ -51,6 +51,7 @@ def exec_command(args: Namespace, item: Item) -> None: args.instance_id = job_instance_id response = jobs_api.cancel_item_job_instance(args) if response.status_code == 202: + fab_ui.print_grey("") fab_ui.print_output_format( args, message=f"Job instance '{args.instance_id}' cancelled (async)", @@ -59,6 +60,7 @@ def exec_command(args: Namespace, item: Item) -> None: ) else: + fab_ui.print_grey("") fab_ui.print_output_format( args, message=f"Job instance '{job_instance_id}' created", data={"id": job_instance_id}, show_key_value_list=True ) diff --git a/src/fabric_cli/utils/fab_cmd_job_utils.py b/src/fabric_cli/utils/fab_cmd_job_utils.py index 7cb3b41c9..6498a3bbf 100644 --- a/src/fabric_cli/utils/fab_cmd_job_utils.py +++ b/src/fabric_cli/utils/fab_cmd_job_utils.py @@ -93,10 +93,11 @@ def wait_for_job_completion( # Available statuses are: NotStarted, InProgress, Completed, Deduped, Failed, Cancelled if status in ["Completed", "Cancelled", "Deduped"]: fab_ui.print_progress(f"Job instance status: {status}") + fab_ui.print_grey("") if status == "Completed": fab_ui.print_output_format( - args, - message=f"Job instance '{job_ins_id}' completed", + args, + message=f"Job instance '{job_ins_id}' completed", data={"id": job_ins_id}, show_key_value_list=True, ) From 49b34399d4703493d9de32ca8ef0d719745990b1 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Tue, 12 May 2026 13:46:05 +0300 Subject: [PATCH 06/13] fix tests --- tests/test_commands/test_jobs.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_commands/test_jobs.py b/tests/test_commands/test_jobs.py index 8a05cea39..3a59dab45 100644 --- a/tests/test_commands/test_jobs.py +++ b/tests/test_commands/test_jobs.py @@ -60,7 +60,7 @@ def test_run_job_notebook(self, item_factory, cli_executor, mock_questionary_pri # All the calls in between are NotStarted or InProgress status # Assert that the last call to the mock was the completition message - assert calls[-1].args[0].split()[4] == "Completed" + assert calls[-3].args[0].split()[4] == "Completed" job_run_status(notebook.full_path, job_instance_id) @@ -193,7 +193,7 @@ def test_start_job_notebook_and_cancel( # Assert that the second call to the mock was to run the Notebook regex = r"→ To see status run 'job run-status (.+) --id (.+)'" - matches = re.match(regex, calls[1].args[0]) + matches = re.match(regex, calls[3].args[0]) assert matches job_instance_id = matches.group(2) @@ -216,7 +216,7 @@ def test_start_job_notebook_and_cancel( # Assert that the last call to the mock was the completition message calls = mock_questionary_print.call_args_list - assert calls[-1].args[0].split()[4] == "Cancelled" + assert calls[-2].args[0].split()[4] == "Cancelled" # Sleep to avoid rely => No notebook execution state found in database for the runId ... time.sleep(2) @@ -507,7 +507,7 @@ def test_run_spark_job(self, item_factory, cli_executor, mock_questionary_print) # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-1].args[0] == "∟ Job instance status: Completed" + assert calls[-3].args[0] == "∟ Job instance status: Completed" def test_run_pipeline(self, item_factory, cli_executor, mock_questionary_print, tmp_path): # Setup @@ -564,7 +564,7 @@ def test_run_pipeline(self, item_factory, cli_executor, mock_questionary_print, # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-1].args[0] == "∟ Job instance status: Completed" + assert calls[-3].args[0] == "∟ Job instance status: Completed" def test_run_param_job(self, item_factory, cli_executor, mock_questionary_print, tmp_path): # Setup @@ -607,7 +607,7 @@ def test_run_param_job(self, item_factory, cli_executor, mock_questionary_print, # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-1].args[0] == "∟ Job instance status: Completed" + assert calls[-3].args[0] == "∟ Job instance status: Completed" # Configure and run the pipeline @@ -653,7 +653,7 @@ def test_run_param_job(self, item_factory, cli_executor, mock_questionary_print, # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-1].args[0] == "∟ Job instance status: Completed" + assert calls[-3].args[0] == "∟ Job instance status: Completed" def test_run_invalid_param_types_failure( self, @@ -809,7 +809,7 @@ def test_run_table_maintenance( calls = mock_questionary_print.call_args_list # Assert that the last call to the mock was the completition message - assert calls[-1].args[0].split()[4] == "Completed" + assert calls[-3].args[0].split()[4] == "Completed" # Reset the mock to avoid the previous calls mock_questionary_print.reset_mock() maintenance_job_input = { @@ -825,7 +825,7 @@ def test_run_table_maintenance( ) calls = mock_questionary_print.call_args_list - assert calls[-1].args[0] == "∟ Job instance status: Completed" + assert calls[-3].args[0] == "∟ Job instance status: Completed" def test_run_schedule_rm_invalid_param_types_failure( self, From 930dec5fae38b60388d625782501e7dcd1e1378e Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Tue, 12 May 2026 13:55:05 +0300 Subject: [PATCH 07/13] fixes --- src/fabric_cli/commands/jobs/fab_jobs_run.py | 5 ++++- src/fabric_cli/utils/fab_cmd_job_utils.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fabric_cli/commands/jobs/fab_jobs_run.py b/src/fabric_cli/commands/jobs/fab_jobs_run.py index acb64a1f1..25e9ac830 100644 --- a/src/fabric_cli/commands/jobs/fab_jobs_run.py +++ b/src/fabric_cli/commands/jobs/fab_jobs_run.py @@ -62,7 +62,10 @@ def exec_command(args: Namespace, item: Item) -> None: else: fab_ui.print_grey("") fab_ui.print_output_format( - args, message=f"Job instance '{job_instance_id}' created", data={"id": job_instance_id}, show_key_value_list=True + args, + message=f"Job instance '{job_instance_id}' created", + data={"id": job_instance_id}, + show_key_value_list=True, ) fab_ui.print_grey( f"→ To see status run 'job run-status {item.path} --id {job_instance_id}'" diff --git a/src/fabric_cli/utils/fab_cmd_job_utils.py b/src/fabric_cli/utils/fab_cmd_job_utils.py index 6498a3bbf..c53666495 100644 --- a/src/fabric_cli/utils/fab_cmd_job_utils.py +++ b/src/fabric_cli/utils/fab_cmd_job_utils.py @@ -11,7 +11,7 @@ from fabric_cli.client import fab_api_jobs as jobs_api from fabric_cli.client.fab_api_types import ApiResponse -from fabric_cli.core import fab_constant, fab_logger, fab_state_config +from fabric_cli.core import fab_constant, fab_logger from fabric_cli.core.fab_exceptions import FabricCLIError from fabric_cli.core.fab_types import FabricJobType from fabric_cli.core.hiearchy.fab_hiearchy import Item From 8327328d6b9795bd18b98e66c8c23898154c3152 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Tue, 12 May 2026 14:09:19 +0300 Subject: [PATCH 08/13] add tests --- tests/test_commands/test_jobs.py | 143 +++++++++++++++++++++ tests/test_utils/test_fab_cmd_job_utils.py | 42 +++++- 2 files changed, 180 insertions(+), 5 deletions(-) diff --git a/tests/test_commands/test_jobs.py b/tests/test_commands/test_jobs.py index 3a59dab45..052bc1f18 100644 --- a/tests/test_commands/test_jobs.py +++ b/tests/test_commands/test_jobs.py @@ -993,6 +993,149 @@ def test_job_run_failure_with_timeout_exits_with_code_1_success(self, item_facto warning_message = mock_print_warning.call_args[0][0] assert "timed out" in warning_message + # region JSON output contract tests + + def test_job_run_json_output_contains_instance_id( + self, item_factory, mock_questionary_print, mock_fab_set_state_config + ): + """Validate that job run in JSON mode outputs result.data with the job instance id.""" + # Setup + mock_fab_set_state_config(constant.FAB_OUTPUT_FORMAT, "json") + nb_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "data/sample_items/example.Notebook", + ) + notebook = item_factory(ItemType.NOTEBOOK, content_path=nb_path) + mock_questionary_print.reset_mock() + + # Execute command + job_run(notebook.full_path) + + # Extract the instance id from the creation message + calls = mock_questionary_print.call_args_list + created_instance_id = None + for call in calls: + match = re.match(r"\u221f Job instance '(.*)' created", call.args[0]) + if match: + created_instance_id = match.group(1) + break + assert created_instance_id is not None, "Expected job instance creation message" + + # Find the JSON output call (print_output_format in json mode outputs a JSON string) + json_output = None + for call in calls: + try: + parsed = json.loads(call.args[0]) + if parsed.get("status") == "Success" and "result" in parsed: + json_output = parsed + break + except (json.JSONDecodeError, TypeError, IndexError): + continue + + assert json_output is not None, "Expected JSON output from job run" + assert json_output["status"] == "Success" + assert json_output["command"] == "job run" + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) == 1 + assert "id" in json_output["result"]["data"][0] + instance_id = json_output["result"]["data"][0]["id"] + assert instance_id == created_instance_id + assert json_output["result"]["message"] is not None + assert "completed" in json_output["result"]["message"] + + def test_job_start_json_output_contains_instance_id( + self, item_factory, mock_questionary_print, mock_fab_set_state_config + ): + """Validate that job start in JSON mode outputs result.data with the job instance id.""" + # Setup + mock_fab_set_state_config(constant.FAB_OUTPUT_FORMAT, "json") + nb_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "data/sample_items/example_wait.Notebook", + ) + notebook = item_factory(ItemType.NOTEBOOK, content_path=nb_path) + mock_questionary_print.reset_mock() + + # Execute command + job_start(notebook.full_path) + + # Find the JSON output call + calls = mock_questionary_print.call_args_list + json_output = None + for call in calls: + try: + parsed = json.loads(call.args[0]) + if parsed.get("status") == "Success" and "result" in parsed: + json_output = parsed + break + except (json.JSONDecodeError, TypeError, IndexError): + continue + + assert json_output is not None, "Expected JSON output from job start" + assert json_output["status"] == "Success" + assert json_output["command"] == "job" + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) == 1 + assert "id" in json_output["result"]["data"][0] + instance_id = json_output["result"]["data"][0]["id"] + assert isinstance(instance_id, str) and len(instance_id) > 0 + assert json_output["result"]["message"] is not None + assert "created" in json_output["result"]["message"] + + # Cross-reference: the status hint message should reference the same instance id + status_hint = None + for call in calls: + match = re.match(r"\u2192 To see status run 'job run-status (.+) --id (.+)'", call.args[0]) + if match: + status_hint = match.group(2) + break + assert status_hint == instance_id + + def test_job_run_timeout_cancelled_json_output_contains_instance_id( + self, item_factory, mock_questionary_print, mock_fab_set_state_config, mock_print_warning + ): + """Validate that job run timeout-cancelled path in JSON mode outputs result.data with the job instance id.""" + # Setup + mock_fab_set_state_config(constant.FAB_OUTPUT_FORMAT, "json") + mock_fab_set_state_config(constant.FAB_JOB_CANCEL_ONTIMEOUT, "true") + nb_path = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + "data/sample_items/example_wait.Notebook", + ) + notebook = item_factory(ItemType.NOTEBOOK, content_path=nb_path) + mock_questionary_print.reset_mock() + + # Execute command with short timeout to trigger cancellation + job_run(notebook.full_path, timeout=1) + + # Verify timeout warning was printed + mock_print_warning.assert_called() + assert "timed out" in mock_print_warning.call_args[0][0] + + # Find the JSON output call for the cancellation + calls = mock_questionary_print.call_args_list + json_output = None + for call in calls: + try: + parsed = json.loads(call.args[0]) + if parsed.get("status") == "Success" and "result" in parsed: + json_output = parsed + break + except (json.JSONDecodeError, TypeError, IndexError): + continue + + assert json_output is not None, "Expected JSON output from timeout-cancelled job run" + assert json_output["status"] == "Success" + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) == 1 + assert "id" in json_output["result"]["data"][0] + instance_id = json_output["result"]["data"][0]["id"] + assert isinstance(instance_id, str) and len(instance_id) > 0 + assert json_output["result"]["message"] is not None + assert "cancelled" in json_output["result"]["message"] + + # endregion + # region Helper Methods def job_run(path, params=None, config=None, input=None, timeout=None): diff --git a/tests/test_utils/test_fab_cmd_job_utils.py b/tests/test_utils/test_fab_cmd_job_utils.py index 1e04bbb89..e2f6e5ba7 100644 --- a/tests/test_utils/test_fab_cmd_job_utils.py +++ b/tests/test_utils/test_fab_cmd_job_utils.py @@ -2,17 +2,18 @@ # Licensed under the MIT License. import json -import pytest -from unittest.mock import Mock, patch from argparse import Namespace +from unittest.mock import Mock, patch + +import pytest +from fabric_cli.core import fab_constant +from fabric_cli.core.fab_exceptions import FabricCLIError from fabric_cli.utils.fab_cmd_job_utils import ( - wait_for_job_completion, validate_timeout_polling_interval, + wait_for_job_completion, ) from fabric_cli.utils.fab_http_polling_utils import DEFAULT_POLLING_INTERVAL -from fabric_cli.core.fab_exceptions import FabricCLIError -from fabric_cli.core import fab_constant @pytest.fixture @@ -58,6 +59,37 @@ def test_wait_for_job_completion_immediate_success(mock_sleep, mock_api, mock_ge mock_get_polling_interval.assert_called_once_with({}, None) +@patch('questionary.print') +@patch('fabric_cli.utils.fab_cmd_job_utils.get_polling_interval') +@patch('fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance') +@patch('fabric_cli.utils.fab_cmd_job_utils.time.sleep') +def test_wait_for_job_completion_json_output_contains_instance_id(mock_sleep, mock_api, mock_get_polling_interval, mock_print, default_job_args, mock_job_response): + """Verify that when status is Completed, JSON output includes result.data[0].id equal to the job instance id.""" + mock_get_polling_interval.return_value = DEFAULT_POLLING_INTERVAL + mock_api.return_value = create_mock_response(status="Completed") + + job_instance_id = "abc12345-def6-7890-abcd-ef1234567890" + wait_for_job_completion(default_job_args, job_instance_id, mock_job_response, custom_polling_interval=None) + + # Find the JSON output call + json_output = None + for call in mock_print.call_args_list: + try: + parsed = json.loads(call.args[0]) + if parsed.get("status") == "Success" and "result" in parsed: + json_output = parsed + break + except (json.JSONDecodeError, TypeError, IndexError): + continue + + assert json_output is not None, "Expected JSON output from wait_for_job_completion" + assert json_output["status"] == "Success" + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) == 1 + assert json_output["result"]["data"][0]["id"] == job_instance_id + assert "completed" in json_output["result"]["message"] + + @patch('fabric_cli.utils.fab_cmd_job_utils.get_polling_interval') @patch('fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance') @patch('fabric_cli.utils.fab_cmd_job_utils.time.sleep') From e9d86c3d62c5fd84a15451be9dae521185da95d6 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Tue, 12 May 2026 14:49:33 +0300 Subject: [PATCH 09/13] fix --- ..._run_json_output_contains_instance_id.yaml | 809 ++++++++++++ ...lled_json_output_contains_instance_id.yaml | 812 ++++++++++++ ...tart_json_output_contains_instance_id.yaml | 1116 +++++++++++++++++ tests/test_utils/test_fab_cmd_job_utils.py | 111 ++ 4 files changed, 2848 insertions(+) create mode 100644 tests/test_commands/recordings/test_commands/test_jobs/test_job_run_json_output_contains_instance_id.yaml create mode 100644 tests/test_commands/recordings/test_commands/test_jobs/test_job_run_timeout_cancelled_json_output_contains_instance_id.yaml create mode 100644 tests/test_commands/recordings/test_commands/test_jobs/test_job_start_json_output_contains_instance_id.yaml diff --git a/tests/test_commands/recordings/test_commands/test_jobs/test_job_run_json_output_contains_instance_id.yaml b/tests/test_commands/recordings/test_commands/test_jobs/test_job_run_json_output_contains_instance_id.yaml new file mode 100644 index 000000000..9fbbb4749 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_jobs/test_job_run_json_output_contains_instance_id.yaml @@ -0,0 +1,809 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:32 GMT + Pragma: + - no-cache + RequestId: + - 13601b44-6273-41e5-9977-af7a001bf666 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:32 GMT + Pragma: + - no-cache + RequestId: + - d1ac9787-8af0-45be-b8c4-bb0b90e548d9 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:32 GMT + Pragma: + - no-cache + RequestId: + - a670d7bb-a604-4b6b-ad8b-d71a93a3e573 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: '{"type": "Notebook", "folderId": null, "displayName": "fabcli000001", "definition": {"format": "ipynb", "parts": [{"path": ".platform", "payload": "ewogICAgIiRzY2hlbWEiOiAiaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9qc29uLXNjaGVtYXMvZmFicmljL2dpdEludGVncmF0aW9uL3BsYXRmb3JtUHJvcGVydGllcy8yLjAuMC9zY2hlbWEuanNvbiIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgInR5cGUiOiAiTm90ZWJvb2siLAogICAgICAgICJkaXNwbGF5TmFtZSI6ICJleGFtcGxlIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ3JlYXRlZCBieSBmYWIiCiAgICB9LAogICAgImNvbmZpZyI6IHsKICAgICAgICAidmVyc2lvbiI6ICIyLjAiLAogICAgICAgICJsb2dpY2FsSWQiOiAiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIgogICAgfQp9", "payloadType": "InlineBase64"}, {"path": "notebook-content.ipynb", "payload": "ewogICAgImNlbGxzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImNlbGxfdHlwZSI6ICJjb2RlIiwKICAgICAgICAgICAgImV4ZWN1dGlvbl9jb3VudCI6IG51bGwsCiAgICAgICAgICAgICJtZXRhZGF0YSI6IHsKICAgICAgICAgICAgICAgICJtaWNyb3NvZnQiOiB7CiAgICAgICAgICAgICAgICAgICAgImxhbmd1YWdlIjogInB5dGhvbiIsCiAgICAgICAgICAgICAgICAgICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm91dHB1dHMiOiBbXSwKICAgICAgICAgICAgInNvdXJjZSI6IFsKICAgICAgICAgICAgICAgICIjIFdlbGNvbWUgdG8geW91ciBuZXcgbm90ZWJvb2tcbiIsCiAgICAgICAgICAgICAgICAiIyBUeXBlIGhlcmUgaW4gdGhlIGNlbGwgZWRpdG9yIHRvIGFkZCBjb2RlIVxuIiwKICAgICAgICAgICAgICAgICJmcm9tIHRpbWUgaW1wb3J0IHNsZWVwXG4iLAogICAgICAgICAgICAgICAgInNsZWVwKDEwKSIKICAgICAgICAgICAgXQogICAgICAgIH0KICAgIF0sCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgImRlcGVuZGVuY2llcyI6IHt9LAogICAgICAgICJrZXJuZWxfaW5mbyI6IHsKICAgICAgICAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgogICAgICAgIH0sCiAgICAgICAgImtlcm5lbHNwZWMiOiB7CiAgICAgICAgICAgICJkaXNwbGF5X25hbWUiOiAic3luYXBzZV9weXNwYXJrIiwKICAgICAgICAgICAgIm5hbWUiOiAic3luYXBzZV9weXNwYXJrIgogICAgICAgIH0sCiAgICAgICAgImxhbmd1YWdlX2luZm8iOiB7CiAgICAgICAgICAgICJuYW1lIjogInB5dGhvbiIKICAgICAgICB9LAogICAgICAgICJtaWNyb3NvZnQiOiB7CiAgICAgICAgICAgICJsYW5ndWFnZSI6ICJweXRob24iLAogICAgICAgICAgICAibGFuZ3VhZ2VfZ3JvdXAiOiAic3luYXBzZV9weXNwYXJrIiwKICAgICAgICAgICAgIm1zX3NwZWxsX2NoZWNrIjogewogICAgICAgICAgICAgICAgIm1zX3NwZWxsX2NoZWNrX2xhbmd1YWdlIjogImVuIgogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAibnRlcmFjdCI6IHsKICAgICAgICAgICAgInZlcnNpb24iOiAibnRlcmFjdC1mcm9udC1lbmRAMS4wLjAiCiAgICAgICAgfSwKICAgICAgICAic3BhcmtfY29tcHV0ZSI6IHsKICAgICAgICAgICAgImNvbXB1dGVfaWQiOiAiL3RyaWRlbnQvZGVmYXVsdCIsCiAgICAgICAgICAgICJzZXNzaW9uX29wdGlvbnMiOiB7CiAgICAgICAgICAgICAgICAiY29uZiI6IHsKICAgICAgICAgICAgICAgICAgICAic3Bhcmsuc3luYXBzZS5uYnMuc2Vzc2lvbi50aW1lb3V0IjogIjEyMDAwMDAiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9LAogICAgIm5iZm9ybWF0IjogNCwKICAgICJuYmZvcm1hdF9taW5vciI6IDUKfQ==", "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2682' + + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:34 GMT + ETag: + - '""' + Location: + - https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a8c6807b-736e-460c-acd9-195b8586360d + Pragma: + - no-cache + RequestId: + - e6f3b6c8-3601-491e-bea0-fb331714def4 + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + x-ms-operation-id: + - a8c6807b-736e-460c-acd9-195b8586360d + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a8c6807b-736e-460c-acd9-195b8586360d + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2025-09-07T14:56:34.1647048", + "lastUpdatedTimeUtc": "2025-09-07T14:56:36.4928524", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '131' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:55 GMT + Location: + - https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a8c6807b-736e-460c-acd9-195b8586360d/result + Pragma: + - no-cache + RequestId: + - 4dd8aa7a-f9d5-4876-86cd-929b448eedc8 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - a8c6807b-736e-460c-acd9-195b8586360d + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a8c6807b-736e-460c-acd9-195b8586360d/result + response: + body: + string: '{"id": "3bd81cc5-a045-46e4-b4df-42394dc06697", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 07 Sep 2025 14:56:55 GMT + Pragma: + - no-cache + RequestId: + - b1fa1572-d6d7-4986-853b-d73c613d0794 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:55 GMT + Pragma: + - no-cache + RequestId: + - f3b9ff51-1a74-4a78-81c1-38b1ad3e5220 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "3bd81cc5-a045-46e4-b4df-42394dc06697", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '179' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:56:55 GMT + Pragma: + - no-cache + RequestId: + - 1eb8d38f-6177-482d-8712-ba3161a1e0c4 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/3bd81cc5-a045-46e4-b4df-42394dc06697/jobs/instances?jobType=RunNotebook + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:56:55 GMT + Location: + - https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/3bd81cc5-a045-46e4-b4df-42394dc06697/jobs/instances/24691602-11f0-44f7-a256-7f1be7959e66 + Pragma: + - no-cache + RequestId: + - 47c0b726-5725-4f58-95b7-e32b014ae85e + Retry-After: + - '60' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/3bd81cc5-a045-46e4-b4df-42394dc06697/jobs/instances/24691602-11f0-44f7-a256-7f1be7959e66 + response: + body: + string: '{"id": "24691602-11f0-44f7-a256-7f1be7959e66", "itemId": "3bd81cc5-a045-46e4-b4df-42394dc06697", + "jobType": "RunNotebook", "invokeType": "Manual", "status": "Completed", "failureReason": + null, "rootActivityId": "47c0b726-5725-4f58-95b7-e32b014ae85e", "startTimeUtc": + "2025-09-07T14:56:59.1116003", "endTimeUtc": "2025-09-07T14:57:24.05005"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '248' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:56 GMT + Pragma: + - no-cache + RequestId: + - 006d4011-cbba-4edf-8085-eb31d4d9a1e1 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:56 GMT + Pragma: + - no-cache + RequestId: + - 6ee8d303-0afa-42dd-b46c-e38c5e974b77 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "3bd81cc5-a045-46e4-b4df-42394dc06697", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '179' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:56 GMT + Pragma: + - no-cache + RequestId: + - 1182857d-556a-4197-b9fd-f9fcf6cbe95c + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/3bd81cc5-a045-46e4-b4df-42394dc06697/jobs/instances/24691602-11f0-44f7-a256-7f1be7959e66 + response: + body: + string: '{"id": "24691602-11f0-44f7-a256-7f1be7959e66", "itemId": "3bd81cc5-a045-46e4-b4df-42394dc06697", + "jobType": "RunNotebook", "invokeType": "Manual", "status": "Completed", "failureReason": + null, "rootActivityId": "47c0b726-5725-4f58-95b7-e32b014ae85e", "startTimeUtc": + "2025-09-07T14:56:59.1116003", "endTimeUtc": "2025-09-07T14:57:24.05005"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '248' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:56 GMT + Pragma: + - no-cache + RequestId: + - ef5448fe-3c2c-4587-b37f-5298e7d91229 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:57 GMT + Pragma: + - no-cache + RequestId: + - 7ba3806c-4cf3-4c6d-ae51-5fe4d745387a + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "3bd81cc5-a045-46e4-b4df-42394dc06697", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '179' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:56 GMT + Pragma: + - no-cache + RequestId: + - 0d83c163-586f-4d5c-a66d-fd837fcb66f9 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/3bd81cc5-a045-46e4-b4df-42394dc06697 + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:57:56 GMT + Pragma: + - no-cache + RequestId: + - e3b7ee30-f17b-43d5-aa6c-200bf02191cc + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_jobs/test_job_run_timeout_cancelled_json_output_contains_instance_id.yaml b/tests/test_commands/recordings/test_commands/test_jobs/test_job_run_timeout_cancelled_json_output_contains_instance_id.yaml new file mode 100644 index 000000000..822804cd7 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_jobs/test_job_run_timeout_cancelled_json_output_contains_instance_id.yaml @@ -0,0 +1,812 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:57 GMT + Pragma: + - no-cache + RequestId: + - 044546f4-07c9-4d19-89ec-bedc86cf2aed + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:58 GMT + Pragma: + - no-cache + RequestId: + - db0d6c4c-e829-49ff-920b-3c9110c79b4d + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:57 GMT + Pragma: + - no-cache + RequestId: + - e711f244-8470-4ad9-a565-ba7d5600a6a3 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: '{"type": "Notebook", "folderId": null, "displayName": "fabcli000001", "definition": {"format": "ipynb", "parts": [{"path": ".platform", "payload": "ewogICAgIiRzY2hlbWEiOiAiaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9qc29uLXNjaGVtYXMvZmFicmljL2dpdEludGVncmF0aW9uL3BsYXRmb3JtUHJvcGVydGllcy8yLjAuMC9zY2hlbWEuanNvbiIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgInR5cGUiOiAiTm90ZWJvb2siLAogICAgICAgICJkaXNwbGF5TmFtZSI6ICJleGFtcGxlIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ3JlYXRlZCBieSBmYWIiCiAgICB9LAogICAgImNvbmZpZyI6IHsKICAgICAgICAidmVyc2lvbiI6ICIyLjAiLAogICAgICAgICJsb2dpY2FsSWQiOiAiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIgogICAgfQp9", "payloadType": "InlineBase64"}, {"path": "notebook-content.ipynb", "payload": "ewogICAgImNlbGxzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImNlbGxfdHlwZSI6ICJjb2RlIiwKICAgICAgICAgICAgImV4ZWN1dGlvbl9jb3VudCI6IG51bGwsCiAgICAgICAgICAgICJtZXRhZGF0YSI6IHsKICAgICAgICAgICAgICAgICJtaWNyb3NvZnQiOiB7CiAgICAgICAgICAgICAgICAgICAgImxhbmd1YWdlIjogInB5dGhvbiIsCiAgICAgICAgICAgICAgICAgICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm91dHB1dHMiOiBbXSwKICAgICAgICAgICAgInNvdXJjZSI6IFsKICAgICAgICAgICAgICAgICIjIFdlbGNvbWUgdG8geW91ciBuZXcgbm90ZWJvb2tcbiIsCiAgICAgICAgICAgICAgICAiIyBUeXBlIGhlcmUgaW4gdGhlIGNlbGwgZWRpdG9yIHRvIGFkZCBjb2RlIVxuIiwKICAgICAgICAgICAgICAgICJmcm9tIHRpbWUgaW1wb3J0IHNsZWVwXG4iLAogICAgICAgICAgICAgICAgInNsZWVwKDEyMCkiCiAgICAgICAgICAgIF0KICAgICAgICB9CiAgICBdLAogICAgIm1ldGFkYXRhIjogewogICAgICAgICJkZXBlbmRlbmNpZXMiOiB7fSwKICAgICAgICAia2VybmVsX2luZm8iOiB7CiAgICAgICAgICAgICJuYW1lIjogInN5bmFwc2VfcHlzcGFyayIKICAgICAgICB9LAogICAgICAgICJsYW5ndWFnZV9pbmZvIjogewogICAgICAgICAgICAibmFtZSI6ICJweXRob24iCiAgICAgICAgfSwKICAgICAgICAibWljcm9zb2Z0IjogewogICAgICAgICAgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKICAgICAgICAgICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIsCiAgICAgICAgICAgICJtc19zcGVsbF9jaGVjayI6IHsKICAgICAgICAgICAgICAgICJtc19zcGVsbF9jaGVja19sYW5ndWFnZSI6ICJlbiIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm50ZXJhY3QiOiB7CiAgICAgICAgICAgICJ2ZXJzaW9uIjogIm50ZXJhY3QtZnJvbnQtZW5kQDEuMC4wIgogICAgICAgIH0sCiAgICAgICAgInNwYXJrX2NvbXB1dGUiOiB7CiAgICAgICAgICAgICJjb21wdXRlX2lkIjogIi90cmlkZW50L2RlZmF1bHQiLAogICAgICAgICAgICAic2Vzc2lvbl9vcHRpb25zIjogewogICAgICAgICAgICAgICAgImNvbmYiOiB7CiAgICAgICAgICAgICAgICAgICAgInNwYXJrLnN5bmFwc2UubmJzLnNlc3Npb24udGltZW91dCI6ICIxMjAwMDAwIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKICAgICJuYmZvcm1hdCI6IDQsCiAgICAibmJmb3JtYXRfbWlub3IiOiA1Cn0K", "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2522' + + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:57:59 GMT + ETag: + - '""' + Location: + - https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a3b300ac-ad76-4f70-a6b2-244d7f63726e + Pragma: + - no-cache + RequestId: + - 6e594146-ad90-4e35-86d5-798d119184be + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + x-ms-operation-id: + - a3b300ac-ad76-4f70-a6b2-244d7f63726e + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a3b300ac-ad76-4f70-a6b2-244d7f63726e + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2025-09-07T14:57:58.7140027", + "lastUpdatedTimeUtc": "2025-09-07T14:57:59.9017879", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '130' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:18 GMT + Location: + - https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a3b300ac-ad76-4f70-a6b2-244d7f63726e/result + Pragma: + - no-cache + RequestId: + - 2d85b77a-e411-416b-8633-cfc648813688 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - a3b300ac-ad76-4f70-a6b2-244d7f63726e + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/a3b300ac-ad76-4f70-a6b2-244d7f63726e/result + response: + body: + string: '{"id": "ecbc6807-4832-45e8-8d22-d5ed9d75c96a", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 07 Sep 2025 14:58:19 GMT + Pragma: + - no-cache + RequestId: + - 1980fefa-3f49-4b61-8426-ba1c0805d314 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:19 GMT + Pragma: + - no-cache + RequestId: + - 86623ab4-2df5-4463-8ad1-9f6121413511 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "ecbc6807-4832-45e8-8d22-d5ed9d75c96a", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '179' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:19 GMT + Pragma: + - no-cache + RequestId: + - 6575cd92-6835-4444-927d-1d1adce82ed0 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/ecbc6807-4832-45e8-8d22-d5ed9d75c96a/jobs/instances?jobType=RunNotebook + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:58:19 GMT + Location: + - https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/ecbc6807-4832-45e8-8d22-d5ed9d75c96a/jobs/instances/ce44f4e0-93df-49da-8735-6acb4096d218 + Pragma: + - no-cache + RequestId: + - c185c6ff-751e-410e-a287-4583ab99d662 + Retry-After: + - '60' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/ecbc6807-4832-45e8-8d22-d5ed9d75c96a/jobs/instances/ce44f4e0-93df-49da-8735-6acb4096d218/cancel + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:58:30 GMT + Location: + - https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/ecbc6807-4832-45e8-8d22-d5ed9d75c96a/jobs/instances/ce44f4e0-93df-49da-8735-6acb4096d218 + Pragma: + - no-cache + RequestId: + - 53621569-02fe-4f86-a10d-b74b67284d15 + Retry-After: + - '60' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:30 GMT + Pragma: + - no-cache + RequestId: + - 53d7b2ed-05e0-49e4-adf6-c9f717c47932 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "ecbc6807-4832-45e8-8d22-d5ed9d75c96a", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '179' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:30 GMT + Pragma: + - no-cache + RequestId: + - 4dce4224-0166-49c0-aa7f-b7f61c521701 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/ecbc6807-4832-45e8-8d22-d5ed9d75c96a/jobs/instances/ce44f4e0-93df-49da-8735-6acb4096d218 + response: + body: + string: '{"id": "ce44f4e0-93df-49da-8735-6acb4096d218", "itemId": "ecbc6807-4832-45e8-8d22-d5ed9d75c96a", + "jobType": "RunNotebook", "invokeType": "Manual", "status": "Cancelled", "failureReason": + null, "rootActivityId": "c185c6ff-751e-410e-a287-4583ab99d662", "startTimeUtc": + "2025-09-07T14:58:22.311953", "endTimeUtc": null}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '240' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:30 GMT + Pragma: + - no-cache + RequestId: + - 9b410403-4e32-490e-916d-909ac9aeb7a2 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:30 GMT + Pragma: + - no-cache + RequestId: + - a9cd720e-6f5e-425a-864b-2bf2aa59d53b + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "ecbc6807-4832-45e8-8d22-d5ed9d75c96a", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '179' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:31 GMT + Pragma: + - no-cache + RequestId: + - fa2fb01f-0c0e-4e43-9c3d-0ef19c87ebf4 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/ecbc6807-4832-45e8-8d22-d5ed9d75c96a + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:58:31 GMT + Pragma: + - no-cache + RequestId: + - 66f500b2-b9b7-4eee-9788-8531192648f8 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_commands/recordings/test_commands/test_jobs/test_job_start_json_output_contains_instance_id.yaml b/tests/test_commands/recordings/test_commands/test_jobs/test_job_start_json_output_contains_instance_id.yaml new file mode 100644 index 000000000..ab7a82721 --- /dev/null +++ b/tests/test_commands/recordings/test_commands/test_jobs/test_job_start_json_output_contains_instance_id.yaml @@ -0,0 +1,1116 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:55 GMT + Pragma: + - no-cache + RequestId: + - db612799-9321-43ce-81ef-ecc769755287 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:56 GMT + Pragma: + - no-cache + RequestId: + - d0cb3f1b-8432-4a36-893e-2e6c9f9b3101 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": []}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '32' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:55 GMT + Pragma: + - no-cache + RequestId: + - 2fe44174-ea7e-46b2-b978-2968fec5fa85 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: '{"type": "Notebook", "folderId": null, "displayName": "fabcli000001", "definition": {"format": "ipynb", "parts": [{"path": ".platform", "payload": "ewogICAgIiRzY2hlbWEiOiAiaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9qc29uLXNjaGVtYXMvZmFicmljL2dpdEludGVncmF0aW9uL3BsYXRmb3JtUHJvcGVydGllcy8yLjAuMC9zY2hlbWEuanNvbiIsCiAgICAibWV0YWRhdGEiOiB7CiAgICAgICAgInR5cGUiOiAiTm90ZWJvb2siLAogICAgICAgICJkaXNwbGF5TmFtZSI6ICJleGFtcGxlIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ3JlYXRlZCBieSBmYWIiCiAgICB9LAogICAgImNvbmZpZyI6IHsKICAgICAgICAidmVyc2lvbiI6ICIyLjAiLAogICAgICAgICJsb2dpY2FsSWQiOiAiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIgogICAgfQp9", "payloadType": "InlineBase64"}, {"path": "notebook-content.ipynb", "payload": "ewogICAgImNlbGxzIjogWwogICAgICAgIHsKICAgICAgICAgICAgImNlbGxfdHlwZSI6ICJjb2RlIiwKICAgICAgICAgICAgImV4ZWN1dGlvbl9jb3VudCI6IG51bGwsCiAgICAgICAgICAgICJtZXRhZGF0YSI6IHsKICAgICAgICAgICAgICAgICJtaWNyb3NvZnQiOiB7CiAgICAgICAgICAgICAgICAgICAgImxhbmd1YWdlIjogInB5dGhvbiIsCiAgICAgICAgICAgICAgICAgICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgIm91dHB1dHMiOiBbXSwKICAgICAgICAgICAgInNvdXJjZSI6IFsKICAgICAgICAgICAgICAgICIjIFdlbGNvbWUgdG8geW91ciBuZXcgbm90ZWJvb2tcbiIsCiAgICAgICAgICAgICAgICAiIyBUeXBlIGhlcmUgaW4gdGhlIGNlbGwgZWRpdG9yIHRvIGFkZCBjb2RlIVxuIiwKICAgICAgICAgICAgICAgICJmcm9tIHRpbWUgaW1wb3J0IHNsZWVwXG4iLAogICAgICAgICAgICAgICAgInNsZWVwKDEyMCkiCiAgICAgICAgICAgIF0KICAgICAgICB9CiAgICBdLAogICAgIm1ldGFkYXRhIjogewogICAgICAgICJkZXBlbmRlbmNpZXMiOiB7fSwKICAgICAgICAia2VybmVsX2luZm8iOiB7CiAgICAgICAgICAgICJuYW1lIjogInN5bmFwc2VfcHlzcGFyayIKICAgICAgICB9LAogICAgICAgICJsYW5ndWFnZV9pbmZvIjogewogICAgICAgICAgICAibmFtZSI6ICJweXRob24iCiAgICAgICAgfSwKICAgICAgICAibWljcm9zb2Z0IjogewogICAgICAgICAgICAibGFuZ3VhZ2UiOiAicHl0aG9uIiwKICAgICAgICAgICAgImxhbmd1YWdlX2dyb3VwIjogInN5bmFwc2VfcHlzcGFyayIsCiAgICAgICAgICAgICJtc19zcGVsbF9jaGVjayI6IHsKICAgICAgICAgICAgICAgICJtc19zcGVsbF9jaGVja19sYW5ndWFnZSI6ICJlbiIKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgIm50ZXJhY3QiOiB7CiAgICAgICAgICAgICJ2ZXJzaW9uIjogIm50ZXJhY3QtZnJvbnQtZW5kQDEuMC4wIgogICAgICAgIH0sCiAgICAgICAgInNwYXJrX2NvbXB1dGUiOiB7CiAgICAgICAgICAgICJjb21wdXRlX2lkIjogIi90cmlkZW50L2RlZmF1bHQiLAogICAgICAgICAgICAic2Vzc2lvbl9vcHRpb25zIjogewogICAgICAgICAgICAgICAgImNvbmYiOiB7CiAgICAgICAgICAgICAgICAgICAgInNwYXJrLnN5bmFwc2UubmJzLnNlc3Npb24udGltZW91dCI6ICIxMjAwMDAwIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSwKICAgICJuYmZvcm1hdCI6IDQsCiAgICAibmJmb3JtYXRfbWlub3IiOiA1Cn0K", "payloadType": "InlineBase64"}]}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '2522' + + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: 'null' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After,ETag,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '24' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:58:56 GMT + ETag: + - '""' + Location: + - https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/d4a2afbf-cde8-4bc1-8f5c-6a2f48da9b09 + Pragma: + - no-cache + RequestId: + - f2f807bf-8174-4073-a98d-208d54774c62 + Retry-After: + - '20' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + x-ms-operation-id: + - d4a2afbf-cde8-4bc1-8f5c-6a2f48da9b09 + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/d4a2afbf-cde8-4bc1-8f5c-6a2f48da9b09 + response: + body: + string: '{"status": "Succeeded", "createdTimeUtc": "2025-09-07T14:58:56.6587179", + "lastUpdatedTimeUtc": "2025-09-07T14:58:58.3462171", "percentComplete": 100, + "error": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,x-ms-operation-id + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '132' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:16 GMT + Location: + - https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/d4a2afbf-cde8-4bc1-8f5c-6a2f48da9b09/result + Pragma: + - no-cache + RequestId: + - 6b9c2f85-ec19-426f-a970-f11e01ed3056 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + x-ms-operation-id: + - d4a2afbf-cde8-4bc1-8f5c-6a2f48da9b09 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://wabi-west-europe-redirect.analysis.windows.net/v1/operations/d4a2afbf-cde8-4bc1-8f5c-6a2f48da9b09/result + response: + body: + string: '{"id": "090aeedc-1c66-4e70-bebe-01df1101fcf0", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Type: + - application/json + Date: + - Sun, 07 Sep 2025 14:59:17 GMT + Pragma: + - no-cache + RequestId: + - aeeb7017-9519-42cc-8821-ea1600016da8 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:17 GMT + Pragma: + - no-cache + RequestId: + - 1e23360e-b2ef-4e14-a415-65b5721402c3 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "090aeedc-1c66-4e70-bebe-01df1101fcf0", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '178' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:17 GMT + Pragma: + - no-cache + RequestId: + - ec3b0202-d8ec-44f7-835a-dda4d1e81a63 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances?jobType=RunNotebook + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:59:17 GMT + Location: + - https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances/eee19fd8-f4ec-462f-b5aa-457de958e5f0 + Pragma: + - no-cache + RequestId: + - d6b0e7ce-06c1-4fae-bed5-0f59e3d79b2d + Retry-After: + - '60' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:18 GMT + Pragma: + - no-cache + RequestId: + - e9370368-14f5-480a-a6f3-7b3071dc9ffb + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "090aeedc-1c66-4e70-bebe-01df1101fcf0", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '178' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:18 GMT + Pragma: + - no-cache + RequestId: + - 1d011472-baa5-4ba5-9691-f1244477163e + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances/eee19fd8-f4ec-462f-b5aa-457de958e5f0 + response: + body: + string: '{"id": "eee19fd8-f4ec-462f-b5aa-457de958e5f0", "itemId": "090aeedc-1c66-4e70-bebe-01df1101fcf0", + "jobType": "RunNotebook", "invokeType": "Manual", "status": "NotStarted", + "failureReason": null, "rootActivityId": "d6b0e7ce-06c1-4fae-bed5-0f59e3d79b2d", + "startTimeUtc": "2025-09-07T14:59:18.14", "endTimeUtc": null}' + headers: + Access-Control-Expose-Headers: + - RequestId,Retry-After + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '234' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:18 GMT + Pragma: + - no-cache + RequestId: + - c3d33c56-069f-43e6-9ab9-0f1194e50305 + Retry-After: + - '29' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:19 GMT + Pragma: + - no-cache + RequestId: + - bd4dfd16-8bcd-496b-ace4-28c565ba6487 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "090aeedc-1c66-4e70-bebe-01df1101fcf0", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '178' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 14:59:19 GMT + Pragma: + - no-cache + RequestId: + - ad9c39fb-49cb-42db-b6a8-b0ac7d041cbd + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: POST + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances/eee19fd8-f4ec-462f-b5aa-457de958e5f0/cancel + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId,Location,Retry-After + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 14:59:20 GMT + Location: + - https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances/eee19fd8-f4ec-462f-b5aa-457de958e5f0 + Pragma: + - no-cache + RequestId: + - 1ccc9a95-13cd-4643-b745-1101294e94ce + Retry-After: + - '60' + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 202 + message: Accepted +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances/eee19fd8-f4ec-462f-b5aa-457de958e5f0 + response: + body: + string: '{"id": "eee19fd8-f4ec-462f-b5aa-457de958e5f0", "itemId": "090aeedc-1c66-4e70-bebe-01df1101fcf0", + "jobType": "RunNotebook", "invokeType": "Manual", "status": "Cancelled", "failureReason": + null, "rootActivityId": "d6b0e7ce-06c1-4fae-bed5-0f59e3d79b2d", "startTimeUtc": + "2025-09-07T14:59:18.14", "endTimeUtc": "2025-09-07T15:00:00.41"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '242' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 15:00:20 GMT + Pragma: + - no-cache + RequestId: + - cc5b5eba-d1e3-4fb6-a213-fe7e0abbb8b1 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 15:00:22 GMT + Pragma: + - no-cache + RequestId: + - c65757cf-9aae-47db-a208-b26f61f9794a + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "090aeedc-1c66-4e70-bebe-01df1101fcf0", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '178' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 15:00:22 GMT + Pragma: + - no-cache + RequestId: + - 0b933749-7543-4af6-a68a-43525a43abf3 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0/jobs/instances/eee19fd8-f4ec-462f-b5aa-457de958e5f0 + response: + body: + string: '{"id": "eee19fd8-f4ec-462f-b5aa-457de958e5f0", "itemId": "090aeedc-1c66-4e70-bebe-01df1101fcf0", + "jobType": "RunNotebook", "invokeType": "Manual", "status": "Cancelled", "failureReason": + null, "rootActivityId": "d6b0e7ce-06c1-4fae-bed5-0f59e3d79b2d", "startTimeUtc": + "2025-09-07T14:59:18.14", "endTimeUtc": "2025-09-07T15:00:00.41"}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '242' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 15:00:22 GMT + Pragma: + - no-cache + RequestId: + - 3a110ffc-c4c0-46bf-9f35-dfb8515f9c0e + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces + response: + body: + string: '{"value": [{"id": "94da8ea5-0bd6-4a9e-b717-5fdb482f4c71", "displayName": + "My workspace", "description": "", "type": "Personal"}, {"id": "ab04aa79-51eb-45b8-8fa6-c96d985f33e7", + "displayName": "fabriccli_WorkspacePerTestclass_000001", "type": "Workspace", "capacityId": "00000000-0000-0000-0000-000000000004"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '498' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 15:00:22 GMT + Pragma: + - no-cache + RequestId: + - c9ba1efc-ef3e-41cf-9789-b37942d86733 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: GET + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items + response: + body: + string: '{"value": [{"id": "090aeedc-1c66-4e70-bebe-01df1101fcf0", "type": "Notebook", + "displayName": "fabcli000001", "workspaceId": + "ab04aa79-51eb-45b8-8fa6-c96d985f33e7"}]}' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '178' + Content-Type: + - application/json; charset=utf-8 + Date: + - Sun, 07 Sep 2025 15:00:23 GMT + Pragma: + - no-cache + RequestId: + - 984274db-7f0f-4cb0-9d9b-dd0ebf006a4e + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + Content-Type: + - application/json + User-Agent: + - ms-fabric-cli-test/1.1.0.rc2 + method: DELETE + uri: https://api.fabric.microsoft.com/v1/workspaces/ab04aa79-51eb-45b8-8fa6-c96d985f33e7/items/090aeedc-1c66-4e70-bebe-01df1101fcf0 + response: + body: + string: '' + headers: + Access-Control-Expose-Headers: + - RequestId + Cache-Control: + - no-store, must-revalidate, no-cache + Content-Encoding: + - gzip + Content-Length: + - '0' + Content-Type: + - application/octet-stream + Date: + - Sun, 07 Sep 2025 15:00:24 GMT + Pragma: + - no-cache + RequestId: + - 2cdb6d88-acb9-46e2-8027-6123b946b1ac + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - deny + home-cluster-uri: + - https://wabi-west-europe-redirect.analysis.windows.net/ + request-redirected: + - 'true' + status: + code: 200 + message: OK +version: 1 diff --git a/tests/test_utils/test_fab_cmd_job_utils.py b/tests/test_utils/test_fab_cmd_job_utils.py index e2f6e5ba7..b4b5fffb6 100644 --- a/tests/test_utils/test_fab_cmd_job_utils.py +++ b/tests/test_utils/test_fab_cmd_job_utils.py @@ -215,5 +215,116 @@ def test_validate_timeout_polling_interval_none_values_success(): validate_timeout_polling_interval(args) + +# region JSON output contract tests + + +@patch('questionary.print') +@patch('fabric_cli.commands.jobs.fab_jobs_run.jobs_api.run_on_demand_item_job') +def test_job_start_json_output_contains_instance_id(mock_run_job, mock_print): + """Verify that job start (no wait) in JSON mode outputs result.data[0].id with the job instance id.""" + from fabric_cli.commands.jobs.fab_jobs_run import exec_command + + job_instance_id = "abc12345-def6-7890-abcd-ef1234567890" + mock_response = Mock() + mock_response.status_code = 202 + mock_response.headers = {"Location": f"https://api.fabric.microsoft.com/v1/workspaces/ws1/items/item1/jobs/instances/{job_instance_id}"} + mock_run_job.return_value = (mock_response, job_instance_id) + + args = Namespace( + command="job", + command_path="job start", + wait=False, + configuration=None, + output_format="json", + ) + item = Mock() + item.path = "/ws.Workspace/nb.Notebook" + + exec_command(args, item) + + # Find the JSON output call + json_output = None + for call in mock_print.call_args_list: + try: + parsed = json.loads(call.args[0]) + if parsed.get("status") == "Success" and "result" in parsed: + json_output = parsed + break + except (json.JSONDecodeError, TypeError, IndexError): + continue + + assert json_output is not None, "Expected JSON output from job start" + assert json_output["status"] == "Success" + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) == 1 + assert json_output["result"]["data"][0]["id"] == job_instance_id + assert "created" in json_output["result"]["message"] + + +@patch('questionary.print') +@patch('fabric_cli.commands.jobs.fab_jobs_run.jobs_api.cancel_item_job_instance') +@patch('fabric_cli.commands.jobs.fab_jobs_run.config.get_config') +@patch('fabric_cli.commands.jobs.fab_jobs_run.utils_job.wait_for_job_completion') +@patch('fabric_cli.commands.jobs.fab_jobs_run.jobs_api.run_on_demand_item_job') +def test_job_run_timeout_cancelled_json_output_contains_instance_id( + mock_run_job, mock_wait, mock_get_config, mock_cancel, mock_print +): + """Verify that timeout-cancelled path in JSON mode outputs result.data[0].id with the job instance id.""" + from fabric_cli.commands.jobs.fab_jobs_run import exec_command + + job_instance_id = "abc12345-def6-7890-abcd-ef1234567890" + mock_response = Mock() + mock_response.status_code = 202 + mock_response.headers = {} + mock_run_job.return_value = (mock_response, job_instance_id) + + # Simulate timeout + mock_wait.side_effect = TimeoutError(f"Job instance '{job_instance_id}' timed out after 1 seconds") + + # Configure cancel-on-timeout to true + mock_get_config.return_value = "true" + + # Cancel returns 202 + mock_cancel_response = Mock() + mock_cancel_response.status_code = 202 + mock_cancel.return_value = mock_cancel_response + + args = Namespace( + command="job", + command_path="job run", + wait=True, + timeout=1, + configuration=None, + output_format="json", + polling_interval=None, + ) + item = Mock() + item.path = "/ws.Workspace/nb.Notebook" + + exec_command(args, item) + + # Find the JSON output call for cancellation + json_output = None + for call in mock_print.call_args_list: + try: + parsed = json.loads(call.args[0]) + if parsed.get("status") == "Success" and "result" in parsed: + json_output = parsed + break + except (json.JSONDecodeError, TypeError, IndexError): + continue + + assert json_output is not None, "Expected JSON output from timeout-cancelled job run" + assert json_output["status"] == "Success" + assert "data" in json_output["result"] + assert len(json_output["result"]["data"]) == 1 + assert json_output["result"]["data"][0]["id"] == job_instance_id + assert "cancelled" in json_output["result"]["message"] + + +# endregion + + if __name__ == "__main__": pytest.main([__file__]) \ No newline at end of file From 3b12594d62effbdc590c8a1b00e7d8284fa96611 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Tue, 12 May 2026 15:03:22 +0300 Subject: [PATCH 10/13] feedback --- src/fabric_cli/commands/jobs/fab_jobs_run.py | 6 +- tests/test_commands/test_jobs.py | 63 ++++++++++++-------- tests/test_utils/test_fab_cmd_job_utils.py | 7 ++- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/fabric_cli/commands/jobs/fab_jobs_run.py b/src/fabric_cli/commands/jobs/fab_jobs_run.py index 25e9ac830..9791ab483 100644 --- a/src/fabric_cli/commands/jobs/fab_jobs_run.py +++ b/src/fabric_cli/commands/jobs/fab_jobs_run.py @@ -62,9 +62,9 @@ def exec_command(args: Namespace, item: Item) -> None: else: fab_ui.print_grey("") fab_ui.print_output_format( - args, - message=f"Job instance '{job_instance_id}' created", - data={"id": job_instance_id}, + args, + message=f"Job instance '{job_instance_id}' created", + data={"id": job_instance_id}, show_key_value_list=True, ) fab_ui.print_grey( diff --git a/tests/test_commands/test_jobs.py b/tests/test_commands/test_jobs.py index 052bc1f18..9b4d5cb75 100644 --- a/tests/test_commands/test_jobs.py +++ b/tests/test_commands/test_jobs.py @@ -29,6 +29,21 @@ from fabric_cli.utils import fab_storage as utils_storage +def _find_print_call(calls, substring): + """Return the first call arg string containing the given substring, or None.""" + return next((c.args[0] for c in calls if c.args and substring in c.args[0]), None) + + +def _find_print_call_match(calls, pattern): + """Return the first regex match from call args matching pattern, or None.""" + for call in calls: + if call.args: + m = re.match(pattern, call.args[0]) + if m: + return m + return None + + class TestJobs: # region JOB RUN def test_run_job_notebook(self, item_factory, cli_executor, mock_questionary_print): @@ -49,18 +64,18 @@ def test_run_job_notebook(self, item_factory, cli_executor, mock_questionary_pri # Assert that the first call to the mock was to create the Notebook assert calls[0].args[0] == f"Importing '{nb_path}' → '{notebook.full_path}'..." - # Assert that the second call to the mock was to run the Notebook + # Assert that a call to the mock was to run the Notebook regex = r"∟ Job instance '(.*)' created" - matches = re.match(regex, calls[2].args[0]) + matches = _find_print_call_match(calls, regex) assert matches job_instance_id = matches.group(1) - assert calls[3].args[0] == "∟ Timeout: no timeout specified" + assert _find_print_call(calls, "∟ Timeout: no timeout specified") # All the calls in between are NotStarted or InProgress status - # Assert that the last call to the mock was the completition message - assert calls[-3].args[0].split()[4] == "Completed" + # Assert that the completion message was printed + assert _find_print_call(calls, "∟ Job instance status: Completed") job_run_status(notebook.full_path, job_instance_id) @@ -91,13 +106,13 @@ def test_run_job_notebook_timeout( # Assert that the first call to the mock was to create the Notebook assert calls[0].args[0] == f"Importing '{nb_path}' → '{notebook.full_path}'..." - # Assert that the second call to the mock was to run the Notebook + # Assert that a call to the mock was to run the Notebook regex = r"∟ Job instance '(.*)' created" - matches = re.match(regex, calls[2].args[0]) + matches = _find_print_call_match(calls, regex) assert matches job_instance_id = matches.group(1) - assert calls[3].args[0] == "∟ Timeout: 10 seconds" + assert _find_print_call(calls, "∟ Timeout: 10 seconds") # All the calls in between are NotStarted or Running status @@ -141,13 +156,13 @@ def test_run_job_notebook_timeout_zero_sec( # Assert that the first call to the mock was to create the Notebook assert calls[0].args[0] == f"Importing '{nb_path}' → '{notebook.full_path}'..." - # Assert that the second call to the mock was to run the Notebook + # Assert that a call to the mock was to run the Notebook regex = r"∟ Job instance '(.*)' created" - matches = re.match(regex, calls[2].args[0]) + matches = _find_print_call_match(calls, regex) assert matches job_instance_id = matches.group(1) - assert calls[3].args[0] == "∟ Timeout: 0 seconds" + assert _find_print_call(calls, "∟ Timeout: 0 seconds") # All the calls in between are NotStarted or InProgress status @@ -191,9 +206,9 @@ def test_start_job_notebook_and_cancel( # Assert that the first call to the mock was to create the Notebook assert calls[0].args[0] == f"Importing '{nb_path}' → '{notebook.full_path}'..." - # Assert that the second call to the mock was to run the Notebook + # Assert that a call to the mock was to show the status hint regex = r"→ To see status run 'job run-status (.+) --id (.+)'" - matches = re.match(regex, calls[3].args[0]) + matches = _find_print_call_match(calls, regex) assert matches job_instance_id = matches.group(2) @@ -214,9 +229,9 @@ def test_start_job_notebook_and_cancel( f"job run-cancel {notebook.full_path} --id {job_instance_id} --wait" ) - # Assert that the last call to the mock was the completition message + # Assert that the cancelled status message was printed calls = mock_questionary_print.call_args_list - assert calls[-2].args[0].split()[4] == "Cancelled" + assert _find_print_call(calls, "∟ Job instance status: Cancelled") # Sleep to avoid rely => No notebook execution state found in database for the runId ... time.sleep(2) @@ -507,7 +522,7 @@ def test_run_spark_job(self, item_factory, cli_executor, mock_questionary_print) # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-3].args[0] == "∟ Job instance status: Completed" + assert _find_print_call(calls, "∟ Job instance status: Completed") def test_run_pipeline(self, item_factory, cli_executor, mock_questionary_print, tmp_path): # Setup @@ -564,7 +579,7 @@ def test_run_pipeline(self, item_factory, cli_executor, mock_questionary_print, # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-3].args[0] == "∟ Job instance status: Completed" + assert _find_print_call(calls, "∟ Job instance status: Completed") def test_run_param_job(self, item_factory, cli_executor, mock_questionary_print, tmp_path): # Setup @@ -607,7 +622,7 @@ def test_run_param_job(self, item_factory, cli_executor, mock_questionary_print, # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-3].args[0] == "∟ Job instance status: Completed" + assert _find_print_call(calls, "∟ Job instance status: Completed") # Configure and run the pipeline @@ -653,7 +668,7 @@ def test_run_param_job(self, item_factory, cli_executor, mock_questionary_print, # Assert calls = mock_questionary_print.call_args_list mock_questionary_print.assert_called() - assert calls[-3].args[0] == "∟ Job instance status: Completed" + assert _find_print_call(calls, "∟ Job instance status: Completed") def test_run_invalid_param_types_failure( self, @@ -808,8 +823,8 @@ def test_run_table_maintenance( # Extract the arguments passed to the mock calls = mock_questionary_print.call_args_list - # Assert that the last call to the mock was the completition message - assert calls[-3].args[0].split()[4] == "Completed" + # Assert that the completion message was printed + assert _find_print_call(calls, "∟ Job instance status: Completed") # Reset the mock to avoid the previous calls mock_questionary_print.reset_mock() maintenance_job_input = { @@ -825,7 +840,7 @@ def test_run_table_maintenance( ) calls = mock_questionary_print.call_args_list - assert calls[-3].args[0] == "∟ Job instance status: Completed" + assert _find_print_call(calls, "∟ Job instance status: Completed") def test_run_schedule_rm_invalid_param_types_failure( self, @@ -1015,7 +1030,7 @@ def test_job_run_json_output_contains_instance_id( calls = mock_questionary_print.call_args_list created_instance_id = None for call in calls: - match = re.match(r"\u221f Job instance '(.*)' created", call.args[0]) + match = re.match("∟ Job instance '(.*)' created", call.args[0]) if match: created_instance_id = match.group(1) break @@ -1085,7 +1100,7 @@ def test_job_start_json_output_contains_instance_id( # Cross-reference: the status hint message should reference the same instance id status_hint = None for call in calls: - match = re.match(r"\u2192 To see status run 'job run-status (.+) --id (.+)'", call.args[0]) + match = re.match("→ To see status run 'job run-status (.+) --id (.+)'", call.args[0]) if match: status_hint = match.group(2) break diff --git a/tests/test_utils/test_fab_cmd_job_utils.py b/tests/test_utils/test_fab_cmd_job_utils.py index b4b5fffb6..1f6c3bca2 100644 --- a/tests/test_utils/test_fab_cmd_job_utils.py +++ b/tests/test_utils/test_fab_cmd_job_utils.py @@ -63,7 +63,12 @@ def test_wait_for_job_completion_immediate_success(mock_sleep, mock_api, mock_ge @patch('fabric_cli.utils.fab_cmd_job_utils.get_polling_interval') @patch('fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance') @patch('fabric_cli.utils.fab_cmd_job_utils.time.sleep') -def test_wait_for_job_completion_json_output_contains_instance_id(mock_sleep, mock_api, mock_get_polling_interval, mock_print, default_job_args, mock_job_response): +def test_wait_for_job_completion_json_output_contains_instance_id( + mock_sleep, + mock_api, + mock_get_polling_interval, + mock_print, default_job_args, + mock_job_response): """Verify that when status is Completed, JSON output includes result.data[0].id equal to the job instance id.""" mock_get_polling_interval.return_value = DEFAULT_POLLING_INTERVAL mock_api.return_value = create_mock_response(status="Completed") From b8787a1edfbf7e4aa607ade7f6b9eaaa2be0533f Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Tue, 12 May 2026 15:06:17 +0300 Subject: [PATCH 11/13] update changelog --- ...zation-20260506-170108.yaml => added-20260512-150558.yaml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename .changes/unreleased/{optimization-20260506-170108.yaml => added-20260512-150558.yaml} (76%) diff --git a/.changes/unreleased/optimization-20260506-170108.yaml b/.changes/unreleased/added-20260512-150558.yaml similarity index 76% rename from .changes/unreleased/optimization-20260506-170108.yaml rename to .changes/unreleased/added-20260512-150558.yaml index f20093bec..b3e8c0848 100644 --- a/.changes/unreleased/optimization-20260506-170108.yaml +++ b/.changes/unreleased/added-20260512-150558.yaml @@ -1,6 +1,6 @@ -kind: optimization +kind: added body: Return the job instance ID as a structured field in the JSON output of ``job run`` and ``job start`` commands -time: 2026-05-06T17:01:08.6543512+03:00 +time: 2026-05-12T15:05:58.3242491+03:00 custom: Author: shirasassoon AuthorLink: https://github.com/shirasassoon From eff694ec59438f97291070e9e03c377e64da9069 Mon Sep 17 00:00:00 2001 From: shirasassoon <66449905+shirasassoon@users.noreply.github.com> Date: Wed, 13 May 2026 15:06:32 +0300 Subject: [PATCH 12/13] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/test_utils/test_fab_cmd_job_utils.py | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/test_utils/test_fab_cmd_job_utils.py b/tests/test_utils/test_fab_cmd_job_utils.py index 1f6c3bca2..8aa058604 100644 --- a/tests/test_utils/test_fab_cmd_job_utils.py +++ b/tests/test_utils/test_fab_cmd_job_utils.py @@ -59,22 +59,29 @@ def test_wait_for_job_completion_immediate_success(mock_sleep, mock_api, mock_ge mock_get_polling_interval.assert_called_once_with({}, None) -@patch('questionary.print') -@patch('fabric_cli.utils.fab_cmd_job_utils.get_polling_interval') -@patch('fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance') -@patch('fabric_cli.utils.fab_cmd_job_utils.time.sleep') +@patch("questionary.print") +@patch("fabric_cli.utils.fab_cmd_job_utils.get_polling_interval") +@patch("fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance") +@patch("fabric_cli.utils.fab_cmd_job_utils.time.sleep") def test_wait_for_job_completion_json_output_contains_instance_id( mock_sleep, mock_api, mock_get_polling_interval, - mock_print, default_job_args, - mock_job_response): - """Verify that when status is Completed, JSON output includes result.data[0].id equal to the job instance id.""" + mock_print, + default_job_args, + mock_job_response, +): + """Verify that Completed status includes the job instance id in JSON output.""" mock_get_polling_interval.return_value = DEFAULT_POLLING_INTERVAL mock_api.return_value = create_mock_response(status="Completed") job_instance_id = "abc12345-def6-7890-abcd-ef1234567890" - wait_for_job_completion(default_job_args, job_instance_id, mock_job_response, custom_polling_interval=None) + wait_for_job_completion( + default_job_args, + job_instance_id, + mock_job_response, + custom_polling_interval=None, + ) # Find the JSON output call json_output = None From 2b10dbb8c392e147936eeb9608fdc6d22c187f62 Mon Sep 17 00:00:00 2001 From: Shira Sassoon Date: Thu, 14 May 2026 14:04:30 +0300 Subject: [PATCH 13/13] revert --- tests/test_utils/test_fab_cmd_job_utils.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/test_utils/test_fab_cmd_job_utils.py b/tests/test_utils/test_fab_cmd_job_utils.py index 8aa058604..cd7f17db8 100644 --- a/tests/test_utils/test_fab_cmd_job_utils.py +++ b/tests/test_utils/test_fab_cmd_job_utils.py @@ -59,10 +59,10 @@ def test_wait_for_job_completion_immediate_success(mock_sleep, mock_api, mock_ge mock_get_polling_interval.assert_called_once_with({}, None) -@patch("questionary.print") -@patch("fabric_cli.utils.fab_cmd_job_utils.get_polling_interval") -@patch("fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance") -@patch("fabric_cli.utils.fab_cmd_job_utils.time.sleep") +@patch('questionary.print') +@patch('fabric_cli.utils.fab_cmd_job_utils.get_polling_interval') +@patch('fabric_cli.utils.fab_cmd_job_utils.jobs_api.get_item_job_instance') +@patch('fabric_cli.utils.fab_cmd_job_utils.time.sleep') def test_wait_for_job_completion_json_output_contains_instance_id( mock_sleep, mock_api, @@ -70,18 +70,13 @@ def test_wait_for_job_completion_json_output_contains_instance_id( mock_print, default_job_args, mock_job_response, -): + ): """Verify that Completed status includes the job instance id in JSON output.""" mock_get_polling_interval.return_value = DEFAULT_POLLING_INTERVAL mock_api.return_value = create_mock_response(status="Completed") job_instance_id = "abc12345-def6-7890-abcd-ef1234567890" - wait_for_job_completion( - default_job_args, - job_instance_id, - mock_job_response, - custom_polling_interval=None, - ) + wait_for_job_completion(default_job_args, job_instance_id, mock_job_response, custom_polling_interval=None) # Find the JSON output call json_output = None