Skip to content

Commit 00e9f87

Browse files
mihaelabalutoiuDany9966
authored andcommitted
Fix transfer show after the get_transfer optimization
The transfer payload no longer embeds executions, so `transfer show` rendered an empty `executions` section. Signed-off-by: Mihaela Balutoiu <mbalutoiu@cloudbasesolutions.com>
1 parent 5f04821 commit 00e9f87

2 files changed

Lines changed: 34 additions & 57 deletions

File tree

coriolisclient/cli/transfers.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
TRANSFER_SCENARIO_REPLICA = "replica"
3131
TRANSFER_SCENARIO_LIVE_MIGRATION = "live_migration"
3232

33+
TRANSFER_SHOW_EXECUTIONS_LIMIT = 10
34+
3335

3436
def _add_default_deployment_args_to_parser(parser):
3537
cd_group = parser.add_mutually_exclusive_group()
@@ -70,12 +72,6 @@ class TransferFormatter(formatter.EntityFormatter):
7072
def _get_sorted_list(self, obj_list):
7173
return sorted(obj_list, key=lambda o: o.created_at)
7274

73-
def _format_last_execution(self, obj):
74-
if obj.executions:
75-
execution = sorted(obj.executions, key=lambda e: e.created_at)[-1]
76-
return "%(id)s %(status)s" % execution.to_dict()
77-
return ""
78-
7975
def _get_formatted_data(self, obj):
8076
data = (obj.id,
8177
getattr(obj, "scenario", "replica"),
@@ -89,7 +85,8 @@ def _get_formatted_data(self, obj):
8985

9086
class TransferDetailFormatter(formatter.EntityFormatter):
9187

92-
def __init__(self, show_instances_data=False):
88+
def __init__(self, show_instances_data=False, executions=None):
89+
self._executions = executions
9390
self.columns = [
9491
"id",
9592
"created",
@@ -133,6 +130,9 @@ def _get_formatted_data(self, obj):
133130
storage_mappings = obj.to_dict().get("storage_mappings", {})
134131
default_storage, backend_mappings, disk_mappings = (
135132
cli_utils.parse_storage_mappings(storage_mappings))
133+
executions = (
134+
self._executions if self._executions is not None
135+
else obj.executions)
136136
data = [obj.id,
137137
obj.created_at,
138138
obj.updated_at,
@@ -158,7 +158,7 @@ def _get_formatted_data(self, obj):
158158
cli_utils.format_json_for_object_property(obj, 'user_scripts'),
159159
obj.clone_disks,
160160
obj.skip_os_morphing,
161-
self._format_executions(obj.executions)]
161+
self._format_executions(executions)]
162162

163163
if "instances-data" in self.columns:
164164
data.append(obj.info)
@@ -307,9 +307,15 @@ def get_parser(self, prog_name):
307307
return parser
308308

309309
def take_action(self, args):
310-
transfer = self.app.client_manager.coriolis.transfers.get(args.id)
310+
coriolis = self.app.client_manager.coriolis
311+
transfer = coriolis.transfers.get(args.id)
312+
executions = coriolis.transfer_executions.list(
313+
args.id,
314+
limit=TRANSFER_SHOW_EXECUTIONS_LIMIT,
315+
sort_keys=["number"], sort_dirs=["desc"])
311316
return TransferDetailFormatter(
312-
args.show_instances_data).get_formatted_entity(transfer)
317+
args.show_instances_data,
318+
executions=executions).get_formatted_entity(transfer)
313319

314320

315321
class DeleteTransfer(command.Command):

coriolisclient/tests/cli/test_transfers.py

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,44 +36,6 @@ def test_get_sorted_list(self):
3636
result
3737
)
3838

39-
def test_format_last_execution(self):
40-
obj = mock.Mock()
41-
obj.executions = None
42-
43-
result = self.transfer._format_last_execution(obj)
44-
45-
self.assertEqual(
46-
"",
47-
result
48-
)
49-
50-
execution1 = mock.Mock()
51-
execution2 = mock.Mock()
52-
execution3 = mock.Mock()
53-
execution1.created_at = "date1"
54-
execution2.created_at = "date2"
55-
execution3.created_at = "date3"
56-
execution1.to_dict.return_value = {
57-
"id": "mock_id1",
58-
"status": "mock_status1"
59-
}
60-
execution2.to_dict.return_value = {
61-
"id": "mock_id2",
62-
"status": "mock_status2"
63-
}
64-
execution3.to_dict.return_value = {
65-
"id": "mock_id3",
66-
"status": "mock_status3"
67-
}
68-
obj.executions = [execution1, execution3, execution2]
69-
70-
result = self.transfer._format_last_execution(obj)
71-
72-
self.assertEqual(
73-
"mock_id3 mock_status3",
74-
result
75-
)
76-
7739
def test_get_formatted_data(self):
7840
obj = mock.Mock()
7941
obj.id = mock.sentinel.id
@@ -362,23 +324,32 @@ def test_get_parser(self, mock_get_parser):
362324
)
363325
mock_get_parser.assert_called_once_with(mock.sentinel.prog_name)
364326

365-
@mock.patch.object(transfers.TransferDetailFormatter,
366-
'get_formatted_entity')
367-
def test_take_action(self, mock_get_formatted_entity):
327+
@mock.patch.object(transfers, 'TransferDetailFormatter')
328+
def test_take_action(self, mock_formatter_class):
368329
args = mock.Mock()
369330
args.id = mock.sentinel.id
370-
mock_transfer = mock.Mock()
371-
self.mock_app.client_manager.coriolis.transfers.get = mock_transfer
331+
args.show_instances_data = mock.sentinel.show_instances_data
332+
coriolis = self.mock_app.client_manager.coriolis
333+
mock_get = coriolis.transfers.get
334+
mock_list = coriolis.transfer_executions.list
335+
mock_formatter = mock_formatter_class.return_value
372336

373337
result = self.transfer.take_action(args)
374338

375339
self.assertEqual(
376-
mock_get_formatted_entity.return_value,
340+
mock_formatter.get_formatted_entity.return_value,
377341
result
378342
)
379-
mock_transfer.assert_called_once_with(mock.sentinel.id)
380-
mock_get_formatted_entity.assert_called_once_with(
381-
mock_transfer.return_value)
343+
mock_get.assert_called_once_with(mock.sentinel.id)
344+
mock_list.assert_called_once_with(
345+
mock.sentinel.id,
346+
limit=transfers.TRANSFER_SHOW_EXECUTIONS_LIMIT,
347+
sort_keys=["number"], sort_dirs=["desc"])
348+
mock_formatter_class.assert_called_once_with(
349+
mock.sentinel.show_instances_data,
350+
executions=mock_list.return_value)
351+
mock_formatter.get_formatted_entity.assert_called_once_with(
352+
mock_get.return_value)
382353

383354

384355
class DeleteTransferTestCase(test_base.CoriolisBaseTestCase):

0 commit comments

Comments
 (0)