Fuel UI
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_fuyaql.py 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. # Copyright 2016 Mirantis, Inc.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. from __future__ import print_function
  15. import mock
  16. from nailgun import consts
  17. from nailgun.fuyaql import fuyaql
  18. from nailgun.test import base
  19. @mock.patch('nailgun.fuyaql.fuyaql.objects')
  20. class TestFuyaqlController(base.BaseUnitTest):
  21. def setUp(self):
  22. self.controller = fuyaql.FuYaqlController()
  23. self.new_context = {
  24. 1: {
  25. 'uid': 1,
  26. 'roles': ['primary-controller'],
  27. 'debug': 'false',
  28. 'cinder': {
  29. 'db_password': '9RkYPCQT9V3LerPsp0qvuzmh',
  30. 'fixed_key': 'f74ce7f535cb61fc0ee8ba77',
  31. 'user_password': '62493085e6cfcaa4638ec08'
  32. }
  33. }
  34. }
  35. def test_set_cluster_with_empty_cluster_value(self, obj_mock):
  36. obj_mock.Cluster.get_by_uid.return_value = None
  37. with mock.patch.object(self.controller, '_set_task') as s_task:
  38. self.assertFalse(self.controller.set_cluster())
  39. obj_mock.Cluster.get_by_uid.assert_called_once_with(
  40. None,
  41. fail_if_not_found=False
  42. )
  43. s_task.assert_not_called()
  44. def test_set_cluster_with_non_empty_cluster_value(self, obj_mock):
  45. obj_mock.Cluster.get_by_uid.return_value = 'cluster'
  46. obj_mock.TransactionCollection.get_last_succeed_run.return_value =\
  47. 'task'
  48. with mock.patch.object(self.controller, '_set_task') as s_task:
  49. self.assertTrue(self.controller.set_cluster('id'))
  50. obj_mock.Cluster.get_by_uid.assert_called_once_with(
  51. 'id',
  52. fail_if_not_found=False
  53. )
  54. obj_mock.TransactionCollection.get_last_succeed_run.\
  55. assert_called_once_with('cluster')
  56. s_task.assert_any_call(self.controller.EXPECTED, None)
  57. s_task.assert_called_with(self.controller.CURRENT, 'task')
  58. def test_set_task_without_task_id(self, _):
  59. self.controller._cluster = 'cluster'
  60. with mock.patch.object(self.controller, '_set_task') as s_task:
  61. self.assertTrue(self.controller.set_task(self.controller.EXPECTED))
  62. s_task.assert_called_once_with(self.controller.EXPECTED, None)
  63. def test_set_task_when_task_is_found(self, obj_mock):
  64. mock_ = mock.MagicMock(id=1, cluster_id=1)
  65. self.controller._cluster = mock_
  66. obj_mock.Transaction.get_by_uid.return_value = mock_
  67. self.assertTrue(self.controller.set_task(self.controller.CURRENT, 1))
  68. obj_mock.Transaction.get_deployment_info.assert_called_once_with(
  69. mock_
  70. )
  71. def test_set_task_when_is_not_found(self, obj_mock):
  72. self.controller._cluster = 'cluster'
  73. obj_mock.Transaction.get_by_uid.return_value = None
  74. with mock.patch.object(self.controller, '_set_task') as s_task:
  75. self.assertFalse(
  76. self.controller.set_task(self.controller.EXPECTED, 1)
  77. )
  78. s_task.assert_not_called()
  79. def test_set_task_when_task_is_not_from_this_cluster(self, obj_mock):
  80. mock_ = mock.MagicMock(id=1, cluster_id=2)
  81. self.controller._cluster = mock_
  82. obj_mock.Transaction.get_by_uid.return_value = mock_
  83. self.assertFalse(self.controller.set_task(self.controller.CURRENT, 1))
  84. obj_mock.Transaction.get_deployment_info.assert_not_called()
  85. def test_set_node(self, _):
  86. self.controller._infos[self.controller.EXPECTED] = self.new_context
  87. self.assertTrue(self.controller.set_node(1))
  88. self.assertFalse(self.controller.set_node(2))
  89. def test_get_node(self, _):
  90. self.controller._infos[self.controller.EXPECTED] = self.new_context
  91. self.controller._node_id = 1
  92. self.assertEqual(self.controller.get_node(), self.new_context[1])
  93. def test_get_clusters(self, obj_mock):
  94. obj_mock.ClusterCollection.order_by.return_value = 'cluster'
  95. obj_mock.ClusterCollection.all.return_value = 'all'
  96. self.assertEqual(self.controller.get_clusters(), 'cluster')
  97. obj_mock.ClusterCollection.all.assert_called_once_with()
  98. obj_mock.ClusterCollection.order_by.assert_called_once_with(
  99. 'all',
  100. 'id'
  101. )
  102. def test_get_tasks(self, obj_mock):
  103. self.controller._cluster = mock.MagicMock(id=1)
  104. obj_mock.TransactionCollection.filter_by.return_value = 'query'
  105. obj_mock.TransactionCollection.filter_by_not.return_value = 'requery'
  106. obj_mock.TransactionCollection.order_by.return_value = 'tasks'
  107. self.assertEqual(self.controller.get_tasks(), 'tasks')
  108. obj_mock.TransactionCollection.filter_by.assert_called_once_with(
  109. None,
  110. cluster_id=self.controller.cluster.id,
  111. name=consts.TASK_NAMES.deployment
  112. )
  113. obj_mock.TransactionCollection.filter_by_not.assert_called_once_with(
  114. 'query', deployment_info=None
  115. )
  116. obj_mock.TransactionCollection.order_by.assert_called_once_with(
  117. 'requery', 'id'
  118. )
  119. def test_get_nodes(self, _):
  120. self.controller._infos[self.controller.EXPECTED] = {
  121. '1': {'uid': '1'}, '2': {'uid': '2'}}
  122. expected = [{'uid': '1'}, {'uid': '2'}]
  123. self.assertEqual(
  124. expected,
  125. list(self.controller.get_nodes())
  126. )
  127. def test_evaluate(self, _):
  128. old_context = {
  129. 1: {
  130. 'uid': 1,
  131. 'roles': ['primary-controller'],
  132. 'debug': 'true',
  133. 'cinder': {
  134. 'db_password': '9RkYPCQT9V3LerPsp0qvuzmh',
  135. 'fixed_key': 'f74ce7f535cb61fc0ee8ba77',
  136. 'user_password': 'n8BMurmecwUWcH52nbdxqPtz'
  137. }
  138. }
  139. }
  140. self.controller._infos = [old_context, self.new_context]
  141. self.controller._node_id = 1
  142. self.controller._cluster = True
  143. self.assertTrue(self.controller.evaluate('changed($)'))
  144. self.assertRaises(self.controller.evaluate('changed($.roles)'))
  145. def test_get_task(self, obj_mock):
  146. self.assertIsNone(self.controller._get_task(None))
  147. obj_mock.Transaction.get_by_uid.return_value = None
  148. self.assertFalse(self.controller._get_task(1))
  149. task = mock.MagicMock()
  150. task.cluster_id = 4
  151. self.controller._cluster = mock.MagicMock()
  152. self.controller._cluster.id = 4
  153. obj_mock.Transaction.get_by_uid.return_value = task
  154. self.assertEqual(self.controller._get_task(1), task)
  155. def test__set_task(self, obj_mock):
  156. obj_mock.Transaction.get_deployment_info.return_value = 'dep_info'
  157. with mock.patch.object(self.controller, '_set_info') as s_info:
  158. self.controller._set_task(self.controller.EXPECTED, 'task')
  159. self.assertEqual(self.controller._tasks[self.controller.EXPECTED],
  160. 'task')
  161. obj_mock.Transaction.get_deployment_info.assert_called_with(
  162. 'task'
  163. )
  164. s_info.assert_called_once_with(self.controller.EXPECTED, 'dep_info')
  165. @mock.patch(
  166. 'nailgun.orchestrator.deployment_serializers.serialize_for_lcm')
  167. def test_set_info(self, serialized, obj_mock):
  168. self.controller._cluster = mock.MagicMock()
  169. self.controller._node_id = 7
  170. self.controller._set_info(
  171. self.controller.CURRENT, {'common': {}, 'nodes': {'1': {'v': 1}}}
  172. )
  173. self.assertEqual(
  174. {'1': {'v': 1}}, self.controller._infos[self.controller.CURRENT],
  175. )
  176. self.assertEqual(self.controller._node_id, 7)
  177. self.controller._set_info(self.controller.CURRENT, None)
  178. self.assertEqual(self.controller._infos[self.controller.CURRENT], {})
  179. self.assertEqual(self.controller._node_id, 7)
  180. serialized.return_value = {
  181. 'common': {}, 'nodes': self.new_context.values()
  182. }
  183. self.controller._set_info(
  184. self.controller.EXPECTED, {'common': {'a': 2}, 'nodes': {'1': {}}}
  185. )
  186. self.assertEqual(
  187. {'1': {'a': 2}},
  188. self.controller._infos[self.controller.EXPECTED],
  189. )
  190. self.assertIsNone(self.controller._node_id)
  191. self.controller._node_id = 8
  192. self.controller._set_info(self.controller.EXPECTED, None)
  193. self.assertEqual(self.controller._infos[self.controller.EXPECTED],
  194. self.new_context)
  195. self.assertIsNone(self.controller._node_id)
  196. serialized.assert_called_once_with(
  197. self.controller._cluster,
  198. obj_mock.Cluster.get_nodes_not_for_deletion(
  199. self.controller._cluster)
  200. )
  201. @mock.patch('nailgun.fuyaql.fuyaql.print', create=True)
  202. class TestFuyaqlInterpreter(base.BaseUnitTest):
  203. def setUp(self):
  204. self.controller = mock.MagicMock(spec=fuyaql.FuYaqlController)
  205. self.interpreter = fuyaql.FuyaqlInterpreter(controller=self.controller)
  206. def test_show_help(self, print_mock):
  207. self.interpreter.show_help()
  208. self.assertEqual(
  209. len(self.interpreter.COMMANDS), print_mock.call_count
  210. )
  211. print_mock.assert_any_call(
  212. ":help", "-", self.interpreter.show_help.__doc__
  213. )
  214. def test_show_clusters_if_cluster_selected(self, _):
  215. self.controller.get_clusters.return_value = [
  216. {'id': 1, 'name': 'test', 'status': 'error'},
  217. {'id': 2}
  218. ]
  219. self.controller.cluster = {'id': 2}
  220. with mock.patch.object(self.interpreter, 'print_list') as print_mock:
  221. self.interpreter.show_clusters()
  222. print_mock.assert_called_once_with(
  223. ('id', 'name', 'status'),
  224. self.controller.get_clusters.return_value,
  225. mock.ANY
  226. )
  227. self.assertEqual(0, print_mock.call_args[0][2]({'id': 2}))
  228. self.assertRaises(ValueError, print_mock.call_args[0][2], {'id': 1})
  229. def test_show_clusters_if_no_cluster_selected(self, _):
  230. self.controller.get_clusters.return_value = [
  231. {'id': 1, 'name': 'test', 'status': 'error'},
  232. {'id': 2}
  233. ]
  234. self.controller.cluster = None
  235. with mock.patch.object(self.interpreter, 'print_list') as print_mock:
  236. self.interpreter.show_clusters()
  237. print_mock.assert_called_once_with(
  238. ('id', 'name', 'status'),
  239. self.controller.get_clusters.return_value,
  240. mock.ANY
  241. )
  242. self.assertRaises(ValueError, print_mock.call_args[0][2], {'id': 1})
  243. self.assertRaises(ValueError, print_mock.call_args[0][2], {'id': 2})
  244. def test_show_tasks_if_no_cluster(self, print_mock):
  245. self.controller.cluster = None
  246. self.interpreter.show_tasks()
  247. print_mock.assert_called_once_with("Select cluster at first.")
  248. def test_show_tasks_if_tasks_selected(self, _):
  249. self.controller.cluster = {'id': 1}
  250. self.controller.get_tasks.return_value = [
  251. {'id': 1, 'status': 'error'},
  252. {'id': 2},
  253. {'id': 3}
  254. ]
  255. self.controller.selected_tasks = [{'id': 2}, {'id': 3}]
  256. with mock.patch.object(self.interpreter, 'print_list') as print_mock:
  257. self.interpreter.show_tasks()
  258. print_mock.assert_called_once_with(
  259. ('id', 'status'),
  260. self.controller.get_tasks.return_value,
  261. mock.ANY
  262. )
  263. self.assertEqual(0, print_mock.call_args[0][2]({'id': 2}))
  264. self.assertEqual(1, print_mock.call_args[0][2]({'id': 3}))
  265. self.assertRaises(ValueError, print_mock.call_args[0][2], {'id': 1})
  266. def test_show_tasks_if_no_all_tasks_selected(self, _):
  267. self.controller.get_tasks.return_value = [
  268. {'id': 1, 'status': 'error'},
  269. {'id': 2},
  270. {'id': 3}
  271. ]
  272. self.controller.selected_tasks = [None, {'id': 3}]
  273. with mock.patch.object(self.interpreter, 'print_list') as print_mock:
  274. self.interpreter.show_tasks()
  275. print_mock.assert_called_once_with(
  276. ('id', 'status'),
  277. self.controller.get_tasks.return_value,
  278. mock.ANY
  279. )
  280. self.assertEqual(1, print_mock.call_args[0][2]({'id': 3}))
  281. self.assertRaises(ValueError, print_mock.call_args[0][2], {'id': 1})
  282. self.assertRaises(ValueError, print_mock.call_args[0][2], {'id': 2})
  283. def test_show_nodes_if_no_cluster(self, print_mock):
  284. self.controller.cluster = None
  285. self.interpreter.show_tasks()
  286. print_mock.assert_called_once_with("Select cluster at first.")
  287. def test_show_nodes_if_node_selected(self, _):
  288. self.controller.cluster = {'id': 1}
  289. self.controller.get_nodes.return_value = [
  290. {'uid': '1', 'status': 'ready', 'roles': ['controller']},
  291. {'uid': '2'},
  292. {'uid': '3'}
  293. ]
  294. self.controller.node_id = '2'
  295. with mock.patch.object(self.interpreter, 'print_list') as print_mock:
  296. self.interpreter.show_nodes()
  297. print_mock.assert_called_once_with(
  298. ('uid', 'status', 'roles'),
  299. self.controller.get_nodes.return_value,
  300. mock.ANY
  301. )
  302. get_index_func = print_mock.call_args[0][2]
  303. self.assertEqual(0, get_index_func({'uid': '2'}))
  304. self.assertRaises(ValueError, get_index_func, {'uid': '1'})
  305. self.assertRaises(ValueError, get_index_func, {'uid': '3'})
  306. def test_show_nodes_if_no_node_selected(self, _):
  307. self.controller.cluster = {'id': 1}
  308. self.controller.get_nodes.return_value = [
  309. {'uid': '1', 'status': 'ready', 'roles': ['controller']},
  310. {'uid': '2'},
  311. {'uid': '3'}
  312. ]
  313. self.controller.node_id = None
  314. with mock.patch.object(self.interpreter, 'print_list') as print_mock:
  315. self.interpreter.show_nodes()
  316. print_mock.assert_called_once_with(
  317. ('uid', 'status', 'roles'),
  318. self.controller.get_nodes.return_value,
  319. mock.ANY
  320. )
  321. get_index_func = print_mock.call_args[0][2]
  322. self.assertRaises(ValueError, get_index_func, {'uid': '1'})
  323. self.assertRaises(ValueError, get_index_func, {'uid': '2'})
  324. self.assertRaises(ValueError, get_index_func, {'uid': '3'})
  325. def test_show_cluster_if_no_cluster(self, print_mock):
  326. self.controller.cluster = None
  327. self.interpreter.show_cluster()
  328. print_mock.assert_called_once_with("There is no cluster.")
  329. def test_show_cluster_if_cluster(self, _):
  330. self.controller.cluster = {'id': 1, 'status': 'error', 'name': 'test'}
  331. with mock.patch.object(self.interpreter, 'print_object') as print_mock:
  332. self.interpreter.show_cluster()
  333. print_mock.assert_called_once_with(
  334. 'cluster', ('id', 'name', 'status'), self.controller.cluster
  335. )
  336. def test_show_task2(self, _):
  337. with mock.patch.object(self.interpreter, '_show_task') as show_mock:
  338. self.interpreter.show_task2()
  339. show_mock.assert_called_once_with(self.controller.EXPECTED)
  340. def test_show_task(self, _):
  341. with mock.patch.object(self.interpreter, '_show_task') as show_mock:
  342. self.interpreter.show_task1()
  343. show_mock.assert_called_once_with(self.controller.CURRENT)
  344. def test_show_node_if_no_node(self, print_mock):
  345. self.controller.node_id = None
  346. self.interpreter.show_node()
  347. print_mock.assert_called_once_with("Please select node at first.")
  348. self.assertEqual(0, self.controller.get_node.call_count)
  349. def test_show_node_if_node(self, _):
  350. self.controller.node_id = '2'
  351. self.controller.get_node_return_value = {'uid': 2}
  352. with mock.patch.object(self.interpreter, 'print_object') as print_mock:
  353. self.interpreter.show_node()
  354. print_mock.assert_called_once_with(
  355. 'node',
  356. ('uid', 'status', 'roles'),
  357. self.controller.get_node.return_value
  358. )
  359. def test_set_cluster(self, print_mock):
  360. """Select the cluster."""
  361. self.controller.set_cluster.side_effect = [True, False]
  362. self.interpreter.set_cluster('1')
  363. self.interpreter.set_cluster('2')
  364. print_mock.assert_called_once_with(
  365. "There is no cluster with id:", "2"
  366. )
  367. def test_set_node_if_no_cluster(self, print_mock):
  368. self.controller.cluster = None
  369. self.interpreter.set_node('1')
  370. print_mock.assert_called_once_with("Select cluster at first.")
  371. def test_set_node_if_cluster(self, print_mock):
  372. """Select the cluster."""
  373. self.controller.cluster = {'id': 1}
  374. self.controller.set_node.side_effect = [True, False]
  375. self.interpreter.set_node('1')
  376. self.interpreter.set_node('2')
  377. print_mock.assert_called_once_with(
  378. "There is no node with id:", "2"
  379. )
  380. def test_set_task2(self, _):
  381. with mock.patch.object(self.interpreter, '_set_task') as set_mock:
  382. self.interpreter.set_task2('2')
  383. set_mock.assert_called_once_with(self.controller.EXPECTED, '2')
  384. def test_set_task1(self, _):
  385. with mock.patch.object(self.interpreter, '_set_task') as set_mock:
  386. self.interpreter.set_task1('1')
  387. set_mock.assert_called_once_with(self.controller.CURRENT, '1')
  388. def test_evaluate_expression_if_no_node(self, print_mock):
  389. self.controller.node_id = None
  390. self.interpreter.evaluate_expression("$.toYaml()")
  391. print_mock.assert_called_once_with("Select node at first.")
  392. def test_evaluate_expression_if_node(self, _):
  393. self.controller.node_id = {'uid': '1'}
  394. self.controller.evaluate.return_value = '1'
  395. self.assertEqual(
  396. '1',
  397. self.interpreter.evaluate_expression("$.uid")
  398. )
  399. self.controller.evaluate.assert_called_once_with('$.uid')
  400. def test_execute_command_if_invalid_command(self, print_mock):
  401. self.interpreter.execute_command(":helpme")
  402. print_mock.assert_has_calls(
  403. [mock.call("Unknown command:", ":helpme"),
  404. mock.call("Please use :help to see list of available commands")]
  405. )
  406. def test_execute_command_with_arguments(self, _):
  407. set_mock = mock.MagicMock()
  408. with mock.patch.object(
  409. self.interpreter, 'set_cluster', new=set_mock.__call__):
  410. r = self.interpreter.execute_command(":use cluster 1")
  411. set_mock.assert_called_once_with('1')
  412. self.assertIs(set_mock.return_value, r)
  413. def test_execute_command_with_invalid_arguments(self, print_mock):
  414. self.interpreter.execute_command(":use cluster")
  415. print_mock.assert_called_once_with(
  416. 'Not enough arguments for a command were given.'
  417. )
  418. def test_execute_command_without_arguments(self, _):
  419. show_mock = mock.MagicMock()
  420. with mock.patch.object(
  421. self.interpreter, 'show_cluster', new=show_mock.__call__):
  422. self.interpreter.execute_command(":show cluster")
  423. show_mock.assert_called_once_with()
  424. def test_show_task_if_no_task(self, print_mock):
  425. self.controller.selected_tasks = [None, 1]
  426. self.interpreter._show_task(0)
  427. print_mock.assert_called_once_with("Please select task at first.")
  428. def test_show_task_if_task(self, _):
  429. self.controller.selected_tasks = [None, {'id': 1}]
  430. with mock.patch.object(self.interpreter, 'print_object') as print_mock:
  431. self.interpreter._show_task(1)
  432. print_mock.assert_called_once_with('task', ('id', 'status'), {'id': 1})
  433. def test_set_task_if_no_cluster(self, print_mock):
  434. self.controller.cluster = None
  435. self.interpreter._set_task(0, 1)
  436. print_mock.assert_called_once_with("Select cluster at first.")
  437. self.assertEqual(0, self.controller.set_task.call_count)
  438. def test_set_task_check_task_order(self, print_mock):
  439. self.controller.cluster = {'id': 1}
  440. self.controller.selected_tasks = [{'id': 5}, {'id': 10}]
  441. self.interpreter._set_task(0, 20)
  442. print_mock.assert_called_with(
  443. "The task, which belongs to state old cannot be"
  444. " under than task which belongs to state new."
  445. )
  446. self.interpreter._set_task(1, 1)
  447. print_mock.assert_called_with(
  448. "The task, which belongs to state new cannot be"
  449. " older than task which belongs to state old."
  450. )
  451. self.assertEqual(0, self.controller.set_task.call_count)
  452. def test_set_task_successfully(self, _):
  453. self.controller.CURRENT = 0
  454. self.controller.EXPECTED = 1
  455. self.controller.cluster = {'id': 1}
  456. self.controller.selected_tasks = [{'id': 5}, {'id': 10}]
  457. self.interpreter._set_task(self.controller.CURRENT, '')
  458. self.controller.set_task.assert_called_with(
  459. self.controller.CURRENT, 0
  460. )
  461. self.interpreter._set_task(self.controller.EXPECTED, '')
  462. self.controller.set_task.assert_called_with(
  463. self.controller.EXPECTED, 0
  464. )
  465. self.controller.selected_tasks = [{'id': 5}, None]
  466. self.interpreter._set_task(self.controller.CURRENT, '10')
  467. self.controller.set_task.assert_called_with(
  468. self.controller.CURRENT, 10
  469. )
  470. self.controller.selected_tasks = [None, {'id': 5}]
  471. self.interpreter._set_task(self.controller.EXPECTED, '1')
  472. self.controller.set_task.assert_called_with(
  473. self.controller.EXPECTED, 1
  474. )
  475. def test_print_list(self, print_mock):
  476. self.interpreter.print_list(
  477. ('id', 'status'),
  478. [{'id': 1, 'status': 'ok'}, {'id': 2}, {'id': 3}],
  479. lambda x: [2, 3].index(x['id'])
  480. )
  481. print_mock.assert_has_calls([
  482. mock.call('id\t|\tstatus'),
  483. mock.call('-' * 18),
  484. mock.call('1\t|\tok'),
  485. mock.call('*', end=' '),
  486. mock.call('2\t|\t-'),
  487. mock.call('**', end=' '),
  488. mock.call('3\t|\t-')
  489. ], any_order=False)
  490. def test_print_object(self, print_mock):
  491. self.interpreter.print_object(
  492. 'node',
  493. ('id', 'status'),
  494. {'id': 1},
  495. )
  496. print_mock.assert_has_calls([
  497. mock.call('Node:'),
  498. mock.call("\tid:\t1"),
  499. mock.call("\tstatus:\t-"),
  500. ], any_order=False)