helpers.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. # -*- coding: utf-8 -*-
  2. """
  3. tests.support.pytest.helpers
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5. PyTest helpers functions
  6. """
  7. import os
  8. import shutil
  9. import tempfile
  10. import textwrap
  11. from contextlib import contextmanager
  12. import pytest
  13. import salt.utils.files
  14. from tests.support.runtests import RUNTIME_VARS
  15. @pytest.helpers.register
  16. @contextmanager
  17. def temp_directory(name=None):
  18. """
  19. This helper creates a temporary directory. It should be used as a context manager
  20. which returns the temporary directory path, and, once out of context, deletes it.
  21. Can be directly imported and used, or, it can be used as a pytest helper function if
  22. ``pytest-helpers-namespace`` is installed.
  23. .. code-block:: python
  24. import os
  25. import pytest
  26. def test_blah():
  27. with pytest.helpers.temp_directory() as tpath:
  28. print(tpath)
  29. assert os.path.exists(tpath)
  30. assert not os.path.exists(tpath)
  31. """
  32. try:
  33. if name is not None:
  34. directory_path = os.path.join(RUNTIME_VARS.TMP, name)
  35. else:
  36. directory_path = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
  37. if not os.path.isdir(directory_path):
  38. os.makedirs(directory_path)
  39. yield directory_path
  40. finally:
  41. shutil.rmtree(directory_path, ignore_errors=True)
  42. @pytest.helpers.register
  43. @contextmanager
  44. def temp_file(name=None, contents=None, directory=None, strip_first_newline=True):
  45. """
  46. This helper creates a temporary file. It should be used as a context manager
  47. which returns the temporary file path, and, once out of context, deletes it.
  48. Can be directly imported and used, or, it can be used as a pytest helper function if
  49. ``pytest-helpers-namespace`` is installed.
  50. .. code-block:: python
  51. import os
  52. import pytest
  53. def test_blah():
  54. with pytest.helpers.temp_file("blah.txt") as tpath:
  55. print(tpath)
  56. assert os.path.exists(tpath)
  57. assert not os.path.exists(tpath)
  58. Args:
  59. name(str):
  60. The temporary file name
  61. contents(str):
  62. The contents of the temporary file
  63. directory(str):
  64. The directory where to create the temporary file. If ``None``, then ``RUNTIME_VARS.TMP``
  65. will be used.
  66. strip_first_newline(bool):
  67. Wether to strip the initial first new line char or not.
  68. """
  69. try:
  70. if directory is None:
  71. directory = RUNTIME_VARS.TMP
  72. if name is not None:
  73. file_path = os.path.join(directory, name)
  74. else:
  75. handle, file_path = tempfile.mkstemp(dir=directory)
  76. os.close(handle)
  77. file_directory = os.path.dirname(file_path)
  78. if not os.path.isdir(file_directory):
  79. os.makedirs(file_directory)
  80. if contents is not None:
  81. if contents:
  82. if contents.startswith("\n") and strip_first_newline:
  83. contents = contents[1:]
  84. file_contents = textwrap.dedent(contents)
  85. else:
  86. file_contents = contents
  87. with salt.utils.files.fopen(file_path, "w") as wfh:
  88. wfh.write(file_contents)
  89. yield file_path
  90. finally:
  91. try:
  92. os.unlink(file_path)
  93. except OSError:
  94. # Already deleted
  95. pass
  96. @pytest.helpers.register
  97. def temp_state_file(name, contents, saltenv="base", strip_first_newline=True):
  98. """
  99. This helper creates a temporary state file. It should be used as a context manager
  100. which returns the temporary state file path, and, once out of context, deletes it.
  101. Can be directly imported and used, or, it can be used as a pytest helper function if
  102. ``pytest-helpers-namespace`` is installed.
  103. .. code-block:: python
  104. import os
  105. import pytest
  106. def test_blah():
  107. with pytest.helpers.temp_state_file("blah.sls") as tpath:
  108. print(tpath)
  109. assert os.path.exists(tpath)
  110. assert not os.path.exists(tpath)
  111. Depending on the saltenv, it will be created under ``RUNTIME_VARS.TMP_STATE_TREE`` or
  112. ``RUNTIME_VARS.TMP_PRODENV_STATE_TREE``.
  113. Args:
  114. name(str):
  115. The temporary state file name
  116. contents(str):
  117. The contents of the temporary file
  118. saltenv(str):
  119. The salt env to use. Either ``base`` or ``prod``
  120. strip_first_newline(bool):
  121. Wether to strip the initial first new line char or not.
  122. """
  123. if saltenv == "base":
  124. directory = RUNTIME_VARS.TMP_STATE_TREE
  125. elif saltenv == "prod":
  126. directory = RUNTIME_VARS.TMP_PRODENV_STATE_TREE
  127. else:
  128. raise RuntimeError(
  129. '"saltenv" can only be "base" or "prod", not "{}"'.format(saltenv)
  130. )
  131. return temp_file(
  132. name, contents, directory=directory, strip_first_newline=strip_first_newline
  133. )
  134. @pytest.helpers.register
  135. def temp_pillar_file(name, contents, saltenv="base", strip_first_newline=True):
  136. """
  137. This helper creates a temporary pillar file. It should be used as a context manager
  138. which returns the temporary pillar file path, and, once out of context, deletes it.
  139. Can be directly imported and used, or, it can be used as a pytest helper function if
  140. ``pytest-helpers-namespace`` is installed.
  141. .. code-block:: python
  142. import os
  143. import pytest
  144. def test_blah():
  145. with pytest.helpers.temp_pillar_file("blah.sls") as tpath:
  146. print(tpath)
  147. assert os.path.exists(tpath)
  148. assert not os.path.exists(tpath)
  149. Depending on the saltenv, it will be created under ``RUNTIME_VARS.TMP_PILLAR_TREE`` or
  150. ``RUNTIME_VARS.TMP_PRODENV_PILLAR_TREE``.
  151. Args:
  152. name(str):
  153. The temporary state file name
  154. contents(str):
  155. The contents of the temporary file
  156. saltenv(str):
  157. The salt env to use. Either ``base`` or ``prod``
  158. strip_first_newline(bool):
  159. Wether to strip the initial first new line char or not.
  160. """
  161. if saltenv == "base":
  162. directory = RUNTIME_VARS.TMP_PILLAR_TREE
  163. elif saltenv == "prod":
  164. directory = RUNTIME_VARS.TMP_PRODENV_PILLAR_TREE
  165. else:
  166. raise RuntimeError(
  167. '"saltenv" can only be "base" or "prod", not "{}"'.format(saltenv)
  168. )
  169. return temp_file(
  170. name, contents, directory=directory, strip_first_newline=strip_first_newline
  171. )
  172. # Only allow star importing the functions defined in this module
  173. __all__ = [
  174. name
  175. for (name, func) in locals().items()
  176. if getattr(func, "__module__", None) == __name__
  177. ]