test_batch.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Nicole Thomas <nicole@saltstack.com>
  4. '''
  5. # Import Python libs
  6. from __future__ import absolute_import, print_function, unicode_literals
  7. # Import Salt Testing Libs
  8. from tests.support.case import ShellCase
  9. # Import Salt libs
  10. import salt.utils.platform
  11. class BatchTest(ShellCase):
  12. '''
  13. Integration tests for the salt.cli.batch module
  14. '''
  15. if salt.utils.platform.is_windows():
  16. run_timeout = 180
  17. else:
  18. run_timeout = 30
  19. def test_batch_run(self):
  20. '''
  21. Tests executing a simple batch command to help catch regressions
  22. '''
  23. ret = 'Executing run on [{0}]'.format(repr('sub_minion'))
  24. cmd = self.run_salt(
  25. '"*minion" test.echo "batch testing" -b 50%',
  26. timeout=self.run_timeout,
  27. )
  28. self.assertIn(ret, cmd)
  29. def test_batch_run_number(self):
  30. '''
  31. Tests executing a simple batch command using a number division instead of
  32. a percentage with full batch CLI call.
  33. '''
  34. ret = "Executing run on [{0}, {1}]".format(repr('minion'), repr('sub_minion'))
  35. cmd = self.run_salt(
  36. '"*minion" test.ping --batch-size 2',
  37. timeout=self.run_timeout,
  38. )
  39. self.assertIn(ret, cmd)
  40. def test_batch_run_grains_targeting(self):
  41. '''
  42. Tests executing a batch command using a percentage divisor as well as grains
  43. targeting.
  44. '''
  45. os_grain = ''
  46. sub_min_ret = "Executing run on [{0}]".format(repr('sub_minion'))
  47. min_ret = "Executing run on [{0}]".format(repr('minion'))
  48. for item in self.run_salt('minion grains.get os'):
  49. if item != 'minion:':
  50. os_grain = item
  51. os_grain = os_grain.strip()
  52. cmd = self.run_salt(
  53. '-C "G@os:{0} and not localhost" -b 25% test.ping'.format(os_grain),
  54. timeout=self.run_timeout,
  55. )
  56. self.assertIn(sub_min_ret, cmd)
  57. self.assertIn(min_ret, cmd)
  58. def test_batch_exit_code(self):
  59. '''
  60. Test that a failed state returns a non-zero exit code in batch mode
  61. '''
  62. cmd = self.run_salt(
  63. ' "*" state.single test.fail_without_changes name=test_me -b 25%',
  64. with_retcode=True,
  65. timeout=self.run_timeout,
  66. )
  67. self.assertEqual(cmd[-1], 2)
  68. # Test for failhard + batch. The best possible solution here was to do something like that:
  69. # assertRaises(StopIteration)
  70. # But it's impossible due to nature of the tests execution via fork()
  71. def test_batch_module_stopping_after_error(self):
  72. '''
  73. Test that a failed command stops the batch run
  74. '''
  75. minions_list = []
  76. retcode = None
  77. # Executing salt with batch: 1 and with failhard. It should stop after the first error.
  78. cmd = self.run_salt(
  79. '"*minion" test.retcode 42 -b 1 --out=yaml --failhard',
  80. timeout=self.run_timeout,
  81. )
  82. # Parsing the output. Idea is to fetch number on minions and retcode of the execution.
  83. # retcode var could be overwritten in case of broken failhard but number of minions check should still fail.
  84. for line in cmd:
  85. if line.startswith('Executing run on'):
  86. minions_list.append(line)
  87. if line.startswith('retcode'):
  88. retcode = line[-1]
  89. # We expect to have only one minion to be run
  90. self.assertEqual(1, len(minions_list))
  91. # We expect to find a retcode in the output
  92. self.assertIsNot(None, retcode)
  93. # We expect retcode to be non-zero
  94. self.assertNotEqual(0, retcode)
  95. def test_batch_state_stopping_after_error(self):
  96. '''
  97. Test that a failed state stops the batch run
  98. '''
  99. minions_list = []
  100. retcode = None
  101. # Executing salt with batch: 1 and with failhard. It should stop after the first error.
  102. cmd = self.run_salt(
  103. '"*minion" state.single test.fail_without_changes name=test_me -b 1 --out=yaml --failhard',
  104. timeout=self.run_timeout,
  105. )
  106. # Parsing the output. Idea is to fetch number on minions and retcode of the execution.
  107. # retcode var could be overwritten in case of broken failhard but number of minions check should still fail.
  108. for line in cmd:
  109. if line.startswith('Executing run on'):
  110. minions_list.append(line)
  111. if line.startswith('retcode'):
  112. retcode = line[-1]
  113. # We expect to have only one minion to be run
  114. self.assertEqual(1, len(minions_list))
  115. # We expect to find a retcode in the output
  116. self.assertIsNot(None, retcode)
  117. # We expect retcode to be non-zero
  118. self.assertNotEqual(0, retcode)