test_fileserver.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. """
  2. Tests for the fileserver runner
  3. """
  4. import contextlib
  5. import pathlib
  6. import pytest
  7. from tests.support.case import ShellCase
  8. from tests.support.helpers import PRE_PYTEST_SKIP_REASON, slowTest
  9. from tests.support.mock import MagicMock, create_autospec, patch
  10. from tests.support.runtests import RUNTIME_VARS
  11. @pytest.mark.windows_whitelisted
  12. class FileserverTest(ShellCase):
  13. """
  14. Test the fileserver runner
  15. """
  16. @slowTest
  17. def test_dir_list(self):
  18. """
  19. fileserver.dir_list
  20. """
  21. ret = self.run_run_plus(fun="fileserver.dir_list")
  22. self.assertIsInstance(ret["return"], list)
  23. self.assertTrue("_modules" in ret["return"])
  24. # Backend submitted as a string
  25. ret = self.run_run_plus(fun="fileserver.dir_list", backend="roots")
  26. self.assertIsInstance(ret["return"], list)
  27. self.assertTrue("_modules" in ret["return"])
  28. # Backend submitted as a list
  29. ret = self.run_run_plus(fun="fileserver.dir_list", backend=["roots"])
  30. self.assertIsInstance(ret["return"], list)
  31. self.assertTrue("_modules" in ret["return"])
  32. @slowTest
  33. def test_empty_dir_list(self):
  34. """
  35. fileserver.empty_dir_list
  36. """
  37. ret = self.run_run_plus(fun="fileserver.empty_dir_list")
  38. self.assertIsInstance(ret["return"], list)
  39. self.assertEqual(ret["return"], [])
  40. # Backend submitted as a string
  41. ret = self.run_run_plus(fun="fileserver.empty_dir_list", backend="roots")
  42. self.assertIsInstance(ret["return"], list)
  43. self.assertEqual(ret["return"], [])
  44. # Backend submitted as a list
  45. ret = self.run_run_plus(fun="fileserver.empty_dir_list", backend=["roots"])
  46. self.assertIsInstance(ret["return"], list)
  47. self.assertEqual(ret["return"], [])
  48. @slowTest
  49. def test_envs(self):
  50. """
  51. fileserver.envs
  52. """
  53. ret = self.run_run_plus(fun="fileserver.envs")
  54. self.assertIsInstance(ret["return"], list)
  55. # Backend submitted as a string
  56. ret = self.run_run_plus(fun="fileserver.envs", backend="roots")
  57. self.assertIsInstance(ret["return"], list)
  58. # Backend submitted as a list
  59. ret = self.run_run_plus(fun="fileserver.envs", backend=["roots"])
  60. self.assertIsInstance(ret["return"], list)
  61. @slowTest
  62. def test_clear_file_list_cache(self):
  63. """
  64. fileserver.clear_file_list_cache
  65. If this test fails, then something may have changed in the test suite
  66. and we may have more than just "roots" configured in the fileserver
  67. backends. This assert will need to be updated accordingly.
  68. """
  69. saltenvs = sorted(self.run_run_plus(fun="fileserver.envs")["return"])
  70. @contextlib.contextmanager
  71. def gen_cache():
  72. """
  73. Create file_list cache so we have something to clear
  74. """
  75. for saltenv in saltenvs:
  76. self.run_run_plus(fun="fileserver.file_list", saltenv=saltenv)
  77. yield
  78. # Test with no arguments
  79. with gen_cache():
  80. ret = self.run_run_plus(fun="fileserver.clear_file_list_cache")
  81. ret["return"]["roots"].sort()
  82. self.assertEqual(ret["return"], {"roots": saltenvs})
  83. # Test with backend passed as string
  84. with gen_cache():
  85. ret = self.run_run_plus(
  86. fun="fileserver.clear_file_list_cache", backend="roots"
  87. )
  88. ret["return"]["roots"].sort()
  89. self.assertEqual(ret["return"], {"roots": saltenvs})
  90. # Test with backend passed as list
  91. with gen_cache():
  92. ret = self.run_run_plus(
  93. fun="fileserver.clear_file_list_cache", backend=["roots"]
  94. )
  95. ret["return"]["roots"].sort()
  96. self.assertEqual(ret["return"], {"roots": saltenvs})
  97. # Test with backend passed as string, but with a nonsense backend
  98. with gen_cache():
  99. ret = self.run_run_plus(
  100. fun="fileserver.clear_file_list_cache", backend="notarealbackend"
  101. )
  102. self.assertEqual(ret["return"], {})
  103. # Test with saltenv passed as string
  104. with gen_cache():
  105. ret = self.run_run_plus(
  106. fun="fileserver.clear_file_list_cache", saltenv="base"
  107. )
  108. self.assertEqual(ret["return"], {"roots": ["base"]})
  109. # Test with saltenv passed as list
  110. with gen_cache():
  111. ret = self.run_run_plus(
  112. fun="fileserver.clear_file_list_cache", saltenv=["base"]
  113. )
  114. self.assertEqual(ret["return"], {"roots": ["base"]})
  115. # Test with saltenv passed as string, but with a nonsense saltenv
  116. with gen_cache():
  117. ret = self.run_run_plus(
  118. fun="fileserver.clear_file_list_cache", saltenv="notarealsaltenv"
  119. )
  120. self.assertEqual(ret["return"], {})
  121. # Test with both backend and saltenv passed
  122. with gen_cache():
  123. ret = self.run_run_plus(
  124. fun="fileserver.clear_file_list_cache", backend="roots", saltenv="base"
  125. )
  126. self.assertEqual(ret["return"], {"roots": ["base"]})
  127. @slowTest
  128. def test_file_list(self):
  129. """
  130. fileserver.file_list
  131. """
  132. ret = self.run_run_plus(fun="fileserver.file_list")
  133. self.assertIsInstance(ret["return"], list)
  134. self.assertTrue("grail/scene33" in ret["return"])
  135. # Backend submitted as a string
  136. ret = self.run_run_plus(fun="fileserver.file_list", backend="roots")
  137. self.assertIsInstance(ret["return"], list)
  138. self.assertTrue("grail/scene33" in ret["return"])
  139. # Backend submitted as a list
  140. ret = self.run_run_plus(fun="fileserver.file_list", backend=["roots"])
  141. self.assertIsInstance(ret["return"], list)
  142. self.assertTrue("grail/scene33" in ret["return"])
  143. @slowTest
  144. @pytest.mark.skip_on_windows(reason=PRE_PYTEST_SKIP_REASON)
  145. def test_symlink_list(self):
  146. """
  147. fileserver.symlink_list
  148. """
  149. source_sym = pathlib.Path(RUNTIME_VARS.TMP_BASEENV_STATE_TREE) / "source_sym_1"
  150. source_sym.write_text("")
  151. dest_sym = pathlib.Path(RUNTIME_VARS.TMP_BASEENV_STATE_TREE) / "dest_sym_1"
  152. dest_sym.symlink_to(str(source_sym))
  153. self.addCleanup(dest_sym.unlink)
  154. self.addCleanup(source_sym.unlink)
  155. ret = self.run_run_plus(fun="fileserver.symlink_list")
  156. self.assertIsInstance(ret["return"], dict)
  157. self.assertTrue("dest_sym_1" in ret["return"])
  158. # Backend submitted as a string
  159. ret = self.run_run_plus(fun="fileserver.symlink_list", backend="roots")
  160. self.assertIsInstance(ret["return"], dict)
  161. self.assertTrue("dest_sym_1" in ret["return"])
  162. # Backend submitted as a list
  163. ret = self.run_run_plus(fun="fileserver.symlink_list", backend=["roots"])
  164. self.assertIsInstance(ret["return"], dict)
  165. self.assertTrue("dest_sym_1" in ret["return"])
  166. @slowTest
  167. def test_update(self):
  168. """
  169. fileserver.update
  170. """
  171. ret = self.run_run_plus(fun="fileserver.update")
  172. self.assertTrue(ret["return"])
  173. # Backend submitted as a string
  174. ret = self.run_run_plus(fun="fileserver.update", backend="roots")
  175. self.assertTrue(ret["return"])
  176. # Backend submitted as a list
  177. ret = self.run_run_plus(fun="fileserver.update", backend=["roots"])
  178. self.assertTrue(ret["return"])
  179. # Other arguments are passed to backend
  180. def mock_gitfs_update(remotes=None):
  181. pass
  182. mock_backend_func = create_autospec(mock_gitfs_update)
  183. mock_return_value = {
  184. "gitfs.envs": None, # This is needed to activate the backend
  185. "gitfs.update": mock_backend_func,
  186. }
  187. with patch("salt.loader.fileserver", MagicMock(return_value=mock_return_value)):
  188. ret = self.run_run_plus(
  189. fun="fileserver.update", backend="gitfs", remotes="myrepo,yourrepo"
  190. )
  191. self.assertTrue(ret["return"])
  192. mock_backend_func.assert_called_once_with(remotes="myrepo,yourrepo")
  193. # Unknown arguments are passed to backend
  194. with patch("salt.loader.fileserver", MagicMock(return_value=mock_return_value)):
  195. ret = self.run_run_plus(
  196. fun="fileserver.update", backend="gitfs", unknown_arg="foo"
  197. )
  198. self.assertIn(
  199. "Passed invalid arguments: got an unexpected keyword argument 'unknown_arg'",
  200. ret["return"],
  201. )