test_openscap.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. # -*- coding: utf-8 -*-
  2. # Import python libs
  3. from __future__ import absolute_import, print_function, unicode_literals
  4. from subprocess import PIPE
  5. # Import salt libs
  6. import salt.modules.openscap as openscap
  7. # Import 3rd-party libs
  8. from salt.ext import six
  9. from tests.support.mock import MagicMock, Mock, patch
  10. # Import salt test libs
  11. from tests.support.unit import TestCase
  12. class OpenscapTestCase(TestCase):
  13. random_temp_dir = "/tmp/unique-name"
  14. policy_file = "/usr/share/openscap/policy-file-xccdf.xml"
  15. def setUp(self):
  16. import salt.modules.openscap
  17. salt.modules.openscap.__salt__ = MagicMock()
  18. patchers = [
  19. patch("salt.modules.openscap.__salt__", MagicMock()),
  20. patch("salt.modules.openscap.shutil.rmtree", Mock()),
  21. patch(
  22. "salt.modules.openscap.tempfile.mkdtemp",
  23. Mock(return_value=self.random_temp_dir),
  24. ),
  25. ]
  26. for patcher in patchers:
  27. self.apply_patch(patcher)
  28. def apply_patch(self, patcher):
  29. patcher.start()
  30. self.addCleanup(patcher.stop)
  31. def test_openscap_xccdf_eval_success(self):
  32. with patch(
  33. "salt.modules.openscap.Popen",
  34. MagicMock(
  35. return_value=Mock(
  36. **{"returncode": 0, "communicate.return_value": ("", "")}
  37. )
  38. ),
  39. ):
  40. response = openscap.xccdf(
  41. "eval --profile Default {0}".format(self.policy_file)
  42. )
  43. self.assertEqual(openscap.tempfile.mkdtemp.call_count, 1)
  44. expected_cmd = [
  45. "oscap",
  46. "xccdf",
  47. "eval",
  48. "--oval-results",
  49. "--results",
  50. "results.xml",
  51. "--report",
  52. "report.html",
  53. "--profile",
  54. "Default",
  55. self.policy_file,
  56. ]
  57. openscap.Popen.assert_called_once_with(
  58. expected_cmd,
  59. cwd=openscap.tempfile.mkdtemp.return_value,
  60. stderr=PIPE,
  61. stdout=PIPE,
  62. )
  63. openscap.__salt__["cp.push_dir"].assert_called_once_with(
  64. self.random_temp_dir
  65. )
  66. self.assertEqual(openscap.shutil.rmtree.call_count, 1)
  67. self.assertEqual(
  68. response,
  69. {
  70. "upload_dir": self.random_temp_dir,
  71. "error": "",
  72. "success": True,
  73. "returncode": 0,
  74. },
  75. )
  76. def test_openscap_xccdf_eval_success_with_failing_rules(self):
  77. with patch(
  78. "salt.modules.openscap.Popen",
  79. MagicMock(
  80. return_value=Mock(
  81. **{"returncode": 2, "communicate.return_value": ("", "some error")}
  82. )
  83. ),
  84. ):
  85. response = openscap.xccdf(
  86. "eval --profile Default {0}".format(self.policy_file)
  87. )
  88. self.assertEqual(openscap.tempfile.mkdtemp.call_count, 1)
  89. expected_cmd = [
  90. "oscap",
  91. "xccdf",
  92. "eval",
  93. "--oval-results",
  94. "--results",
  95. "results.xml",
  96. "--report",
  97. "report.html",
  98. "--profile",
  99. "Default",
  100. self.policy_file,
  101. ]
  102. openscap.Popen.assert_called_once_with(
  103. expected_cmd,
  104. cwd=openscap.tempfile.mkdtemp.return_value,
  105. stderr=PIPE,
  106. stdout=PIPE,
  107. )
  108. openscap.__salt__["cp.push_dir"].assert_called_once_with(
  109. self.random_temp_dir
  110. )
  111. self.assertEqual(openscap.shutil.rmtree.call_count, 1)
  112. self.assertEqual(
  113. response,
  114. {
  115. "upload_dir": self.random_temp_dir,
  116. "error": "some error",
  117. "success": True,
  118. "returncode": 2,
  119. },
  120. )
  121. def test_openscap_xccdf_eval_fail_no_profile(self):
  122. response = openscap.xccdf("eval --param Default /unknown/param")
  123. if six.PY2:
  124. error = "argument --profile is required"
  125. else:
  126. error = "the following arguments are required: --profile"
  127. self.assertEqual(
  128. response,
  129. {"error": error, "upload_dir": None, "success": False, "returncode": None},
  130. )
  131. def test_openscap_xccdf_eval_success_ignore_unknown_params(self):
  132. with patch(
  133. "salt.modules.openscap.Popen",
  134. MagicMock(
  135. return_value=Mock(
  136. **{"returncode": 2, "communicate.return_value": ("", "some error")}
  137. )
  138. ),
  139. ):
  140. response = openscap.xccdf(
  141. "eval --profile Default --param Default /policy/file"
  142. )
  143. self.assertEqual(
  144. response,
  145. {
  146. "upload_dir": self.random_temp_dir,
  147. "error": "some error",
  148. "success": True,
  149. "returncode": 2,
  150. },
  151. )
  152. expected_cmd = [
  153. "oscap",
  154. "xccdf",
  155. "eval",
  156. "--oval-results",
  157. "--results",
  158. "results.xml",
  159. "--report",
  160. "report.html",
  161. "--profile",
  162. "Default",
  163. "/policy/file",
  164. ]
  165. openscap.Popen.assert_called_once_with(
  166. expected_cmd,
  167. cwd=openscap.tempfile.mkdtemp.return_value,
  168. stderr=PIPE,
  169. stdout=PIPE,
  170. )
  171. def test_openscap_xccdf_eval_evaluation_error(self):
  172. with patch(
  173. "salt.modules.openscap.Popen",
  174. MagicMock(
  175. return_value=Mock(
  176. **{
  177. "returncode": 1,
  178. "communicate.return_value": ("", "evaluation error"),
  179. }
  180. )
  181. ),
  182. ):
  183. response = openscap.xccdf(
  184. "eval --profile Default {0}".format(self.policy_file)
  185. )
  186. self.assertEqual(
  187. response,
  188. {
  189. "upload_dir": None,
  190. "error": "evaluation error",
  191. "success": False,
  192. "returncode": 1,
  193. },
  194. )
  195. def test_openscap_xccdf_eval_fail_not_implemented_action(self):
  196. response = openscap.xccdf("info {0}".format(self.policy_file))
  197. if six.PY2:
  198. mock_err = "argument action: invalid choice: 'info' (choose from u'eval')"
  199. else:
  200. mock_err = "argument action: invalid choice: 'info' (choose from 'eval')"
  201. self.assertEqual(
  202. response,
  203. {
  204. "upload_dir": None,
  205. "error": mock_err,
  206. "success": False,
  207. "returncode": None,
  208. },
  209. )