test_highstate.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. # -*- coding: utf-8 -*-
  2. """
  3. unittests for highstate outputter
  4. """
  5. # Import Python Libs
  6. from __future__ import absolute_import
  7. import salt.output.highstate as highstate
  8. # Import Salt Libs
  9. import salt.utils.stringutils
  10. # Import 3rd-party libs
  11. from salt.ext import six
  12. # Import Salt Testing Libs
  13. from tests.support.mixins import LoaderModuleMockMixin
  14. from tests.support.unit import TestCase
  15. class JsonTestCase(TestCase, LoaderModuleMockMixin):
  16. """
  17. Test cases for salt.output.highstate
  18. """
  19. def setup_loader_modules(self):
  20. return {
  21. highstate: {
  22. "__opts__": {
  23. "extension_modules": "",
  24. "optimization_order": [0, 1, 2],
  25. "color": False,
  26. }
  27. }
  28. }
  29. def setUp(self):
  30. self.data = {
  31. "data": {
  32. "master": {
  33. "salt_|-call_sleep_state_|-call_sleep_state_|-state": {
  34. "__id__": "call_sleep_state",
  35. "__jid__": "20170418153529810135",
  36. "__run_num__": 0,
  37. "__sls__": "orch.simple",
  38. "changes": {
  39. "out": "highstate",
  40. "ret": {
  41. "minion": {
  42. "module_|-simple-ping_|-test.ping_|-run": {
  43. "__id__": "simple-ping",
  44. "__run_num__": 0,
  45. "__sls__": "simple-ping",
  46. "changes": {"ret": True},
  47. "comment": "Module function test.ping executed",
  48. "duration": 56.179,
  49. "name": "test.ping",
  50. "result": True,
  51. "start_time": "15:35:31.282099",
  52. }
  53. },
  54. "sub_minion": {
  55. "module_|-simple-ping_|-test.ping_|-run": {
  56. "__id__": "simple-ping",
  57. "__run_num__": 0,
  58. "__sls__": "simple-ping",
  59. "changes": {"ret": True},
  60. "comment": "Module function test.ping executed",
  61. "duration": 54.103,
  62. "name": "test.ping",
  63. "result": True,
  64. "start_time": "15:35:31.005606",
  65. }
  66. },
  67. },
  68. },
  69. "comment": "States ran successfully. Updating sub_minion, minion.",
  70. "duration": 1638.047,
  71. "name": "call_sleep_state",
  72. "result": True,
  73. "start_time": "15:35:29.762657",
  74. },
  75. "salt_|-cmd_run_example_|-cmd.run_|-function": {
  76. "__id__": "cmd_run_example",
  77. "__jid__": "20200411195112288850",
  78. "__run_num__": 1,
  79. "__sls__": "orch.simple",
  80. "changes": {
  81. "out": "highstate",
  82. "ret": {"minion": "file1\nfile2\nfile3"},
  83. },
  84. "comment": "Function ran successfully. Function cmd.run ran on minion.",
  85. "duration": 412.397,
  86. "name": "cmd.run",
  87. "result": True,
  88. "start_time": "21:51:12.185868",
  89. },
  90. }
  91. },
  92. "outputter": "highstate",
  93. "retcode": 0,
  94. }
  95. self.addCleanup(delattr, self, "data")
  96. def test_default_output(self):
  97. ret = highstate.output(self.data)
  98. self.assertIn("Succeeded: 1 (changed=1)", ret)
  99. self.assertIn("Failed: 0", ret)
  100. self.assertIn("Total states run: 1", ret)
  101. self.assertIn(" file2", ret)
  102. def test_output_comment_is_not_unicode(self):
  103. entry = None
  104. for key in (
  105. "data",
  106. "master",
  107. "salt_|-call_sleep_state_|-call_sleep_state_|-state",
  108. "changes",
  109. "ret",
  110. "minion",
  111. "module_|-simple-ping_|-test.ping_|-run",
  112. ):
  113. if entry is None:
  114. entry = self.data[key]
  115. continue
  116. entry = entry[key]
  117. if six.PY2:
  118. entry["comment"] = salt.utils.stringutils.to_unicode(entry["comment"])
  119. else:
  120. entry["comment"] = salt.utils.stringutils.to_bytes(entry["comment"])
  121. ret = highstate.output(self.data)
  122. self.assertIn("Succeeded: 1 (changed=1)", ret)
  123. self.assertIn("Failed: 0", ret)
  124. self.assertIn("Total states run: 1", ret)
  125. self.assertIn(" file2", ret)
  126. # this should all pass the above tests
  127. class JsonNestedTestCase(TestCase, LoaderModuleMockMixin):
  128. """
  129. Test cases for nested salt.output.highstate (ie orchestrations calling other orchs)
  130. """
  131. def setup_loader_modules(self):
  132. return {
  133. highstate: {
  134. "__opts__": {
  135. "extension_modules": "",
  136. "color": False,
  137. "optimization_order": [0, 1, 2],
  138. }
  139. }
  140. }
  141. def setUp(self):
  142. self.data = {
  143. "outputter": "highstate",
  144. "data": {
  145. "local_master": {
  146. "salt_|-nested_|-state.orchestrate_|-runner": {
  147. "comment": "Runner function 'state.orchestrate' executed.",
  148. "name": "state.orchestrate",
  149. "__orchestration__": True,
  150. "start_time": "09:22:53.158742",
  151. "result": True,
  152. "duration": 980.694,
  153. "__run_num__": 0,
  154. "__jid__": "20180326092253538853",
  155. "__sls__": "orch.test.nested",
  156. "changes": {
  157. "return": {
  158. "outputter": "highstate",
  159. "data": {
  160. "local_master": {
  161. "test_|-always-passes-with-changes_|-oinaosf_|-succeed_with_changes": {
  162. "comment": "Success!",
  163. "name": "oinaosf",
  164. "start_time": "09:22:54.128415",
  165. "result": True,
  166. "duration": 0.437,
  167. "__run_num__": 0,
  168. "__sls__": "orch.test.changes",
  169. "changes": {
  170. "testing": {
  171. "new": "Something pretended to change",
  172. "old": "Unchanged",
  173. }
  174. },
  175. "__id__": "always-passes-with-changes",
  176. },
  177. "test_|-always-passes_|-fasdfasddfasdfoo_|-succeed_without_changes": {
  178. "comment": "Success!",
  179. "name": "fasdfasddfasdfoo",
  180. "start_time": "09:22:54.128986",
  181. "result": True,
  182. "duration": 0.25,
  183. "__run_num__": 1,
  184. "__sls__": "orch.test.changes",
  185. "changes": {},
  186. "__id__": "always-passes",
  187. },
  188. }
  189. },
  190. "retcode": 0,
  191. }
  192. },
  193. "__id__": "nested",
  194. }
  195. }
  196. },
  197. "retcode": 0,
  198. }
  199. self.addCleanup(delattr, self, "data")
  200. def test_nested_output(self):
  201. ret = highstate.output(self.data)
  202. self.assertIn("Succeeded: 1 (changed=1)", ret)
  203. self.assertIn("Failed: 0", ret)
  204. self.assertIn("Total states run: 1", ret)
  205. # the whitespace is relevant in this case, it is testing that it is nested
  206. self.assertIn(" ID: always-passes-with-changes", ret)
  207. self.assertIn(" Started: 09:22:54.128415", ret)
  208. self.assertIn(" Succeeded: 2 (changed=1)", ret)
  209. self.assertIn(" Failed: 0", ret)
  210. self.assertIn(" Total states run: 2", ret)