pbs_pbsnodes.py 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. # coding: utf-8
  2. # Copyright (C) 1994-2018 Altair Engineering, Inc.
  3. # For more information, contact Altair at www.altair.com.
  4. #
  5. # This file is part of the PBS Professional ("PBS Pro") software.
  6. #
  7. # Open Source License Information:
  8. #
  9. # PBS Pro is free software. You can redistribute it and/or modify it under the
  10. # terms of the GNU Affero General Public License as published by the Free
  11. # Software Foundation, either version 3 of the License, or (at your option) any
  12. # later version.
  13. #
  14. # PBS Pro is distributed in the hope that it will be useful, but WITHOUT ANY
  15. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. # FOR A PARTICULAR PURPOSE.
  17. # See the GNU Affero General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Affero General Public License
  20. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. #
  22. # Commercial License Information:
  23. #
  24. # For a copy of the commercial license terms and conditions,
  25. # go to: (http://www.pbspro.com/UserArea/agreement.html)
  26. # or contact the Altair Legal Department.
  27. #
  28. # Altair’s dual-license business model allows companies, individuals, and
  29. # organizations to create proprietary derivative works of PBS Pro and
  30. # distribute them - whether embedded or bundled with other software -
  31. # under a commercial license agreement.
  32. #
  33. # Use of Altair’s trademarks, including but not limited to "PBS™",
  34. # "PBS Professional®", and "PBS Pro™" and Altair’s logos is subject to Altair's
  35. # trademark licensing policies.
  36. from tests.functional import *
  37. @tags('commands')
  38. class TestPbsnodes(TestFunctional):
  39. """
  40. This test suite contains regression tests for pbsnodes command.
  41. """
  42. def setUp(self):
  43. TestFunctional.setUp(self)
  44. self.header = ['vnode', 'state', 'OS', 'hardware', 'host',
  45. 'queue', 'mem', 'ncpus', 'nmics', 'ngpus', 'comment']
  46. self.pbs_exec = self.server.pbs_conf['PBS_EXEC']
  47. self.pbsnodes = [os.path.join(self.pbs_exec, 'bin', 'pbsnodes')]
  48. self.svrname = self.server.pbs_server_name
  49. self.hostA = self.moms.values()[0].shortname
  50. def common_setUp(self):
  51. """
  52. Common setUp for tests test_pbsnodes_as_user and test_pbsnodes_as_root
  53. """
  54. TestFunctional.setUp(self)
  55. self.server.manager(MGR_CMD_DELETE, NODE, id="",
  56. sudo=True, expect=True)
  57. self.server.manager(MGR_CMD_CREATE, NODE, id=self.mom.shortname)
  58. self.server.expect(NODE, {'state': 'free'})
  59. def get_newnode_attrs(self, user):
  60. """
  61. return expected values of attributes on a newly created node
  62. """
  63. expect_dict = {}
  64. expect_dict[ATTR_NODE_Mom] = self.server.hostname
  65. expect_dict[ATTR_NODE_ntype] = 'PBS'
  66. expect_dict[ATTR_NODE_state] = 'free'
  67. expect_dict[ATTR_rescavail + '.vnode'] = self.server.shortname
  68. expect_dict[ATTR_rescavail + '.host'] = self.server.shortname
  69. expect_dict[ATTR_NODE_resv_enable] = 'True'
  70. if user == 'root':
  71. expect_dict[ATTR_version] = self.server.pbs_version
  72. expect_dict[ATTR_NODE_Port] = '15002'
  73. return expect_dict
  74. def verify_node_dynamic_val(self, last_state_change_time, available_ncpus,
  75. pcpus, sharing, available_mem):
  76. """
  77. verifies node dynamic attributes have expected value
  78. """
  79. sharing_list = ['default_shared', 'default_excl', 'default_exclhost',
  80. 'ignore_excl', 'force_excl', 'force_exclhost']
  81. # Verify that 'last_state_change_time' has value in datetime format
  82. last_state_change_time = str(last_state_change_time)
  83. try:
  84. time.strptime(last_state_change_time, "%a %b %d %H:%M:%S %Y")
  85. except ValueError:
  86. self.fail("'last_state_change_time' has value in incorrect format")
  87. else:
  88. mssg = "'last_state_change_time' has value in correct format"
  89. self.logger.info(mssg)
  90. # checking resources_avalable.ncpus and pcpus value are positive value
  91. ncpus_val = int(available_ncpus)
  92. if ncpus_val >= 0:
  93. mssg = "resources_available.ncpus have positive int value"
  94. self.logger.info(mssg)
  95. else:
  96. self.fail("resources_available.ncpus have negative value")
  97. pcpus_val = int(pcpus)
  98. if pcpus_val >= 0:
  99. self.logger.info("pcpus have positive int value")
  100. else:
  101. self.fail("pcpus have negative value")
  102. # verify pcpus and ncpus value are same
  103. if pcpus_val == ncpus_val:
  104. self.logger.info("pcpus and ncpus have same value")
  105. else:
  106. self.fail("pcpus and ncpus not having same value")
  107. # verify node sharing attribute have one of the value in
  108. # sharing_val list
  109. mssg = "Node sharing attribute not have expected value"
  110. self.assertIn(sharing, sharing_list, mssg)
  111. # checking resources_avalable.mem value is positive value
  112. index = available_mem.find('kb')
  113. if int(available_mem[:index]) >= 0:
  114. mssg = "resources_available.mem have positive int value"
  115. self.logger.info(mssg)
  116. else:
  117. self.fail("resources_available.mem not having positive int value")
  118. def test_pbsnodes_S(self):
  119. """
  120. This verifies that 'pbsnodes -S' results in a usage message
  121. """
  122. pbsnodes_S = self.pbsnodes + ['-S']
  123. out = self.du.run_cmd(self.svrname, cmd=pbsnodes_S)
  124. self.logger.info(out['err'][0])
  125. self.assertIn('usage:', out['err'][
  126. 0], 'usage not found in error message')
  127. def test_pbsnodes_S_host(self):
  128. """
  129. This verifies that 'pbsnodes -S <host>' results in an output
  130. with correct headers.
  131. """
  132. pbsnodes_S_host = self.pbsnodes + ['-S', self.hostA]
  133. out1 = self.du.run_cmd(self.svrname, cmd=pbsnodes_S_host)
  134. self.logger.info(out1['out'])
  135. for hdr in self.header:
  136. self.assertIn(
  137. hdr, out1['out'][0],
  138. "header %s not found in output" % hdr)
  139. def test_pbsnodes_aS(self):
  140. """
  141. This verifies that 'pbsnodes -aS' results in an output
  142. with correct headers.
  143. """
  144. pbsnodes_aS = self.pbsnodes + ['-aS']
  145. out2 = self.du.run_cmd(self.svrname, cmd=pbsnodes_aS)
  146. self.logger.info(out2['out'])
  147. for hdr in self.header:
  148. self.assertIn(
  149. hdr, out2['out'][0],
  150. "header %s not found in output" % hdr)
  151. def test_pbsnodes_av(self):
  152. """
  153. This verifies the values of last_used_time in 'pbsnodes -av'
  154. result before and after server shutdown, once a job submitted.
  155. """
  156. j = Job(TEST_USER)
  157. j.set_sleep_time(1)
  158. jid = self.server.submit(j)
  159. self.server.accounting_match("E;%s;" % jid)
  160. prev = self.server.status(NODE, 'last_used_time')[0]['last_used_time']
  161. self.logger.info("Restarting server")
  162. self.server.restart()
  163. self.assertTrue(self.server.isUp(), 'Failed to restart Server Daemon')
  164. now = self.server.status(NODE, 'last_used_time')[0]['last_used_time']
  165. self.logger.info("Before: " + prev + ". After: " + now + ".")
  166. self.assertEquals(prev.strip(), now.strip(),
  167. 'Last used time mismatch after server restart')
  168. @skipOnCpuSet
  169. @skipOnCray
  170. def test_pbsnodes_as_user(self):
  171. """
  172. Validate default values of node attributes for non-root user
  173. """
  174. self.common_setUp()
  175. attr_dict = {}
  176. expected_attrs = self.get_newnode_attrs(TEST_USER)
  177. command = os.path.join(self.server.pbs_conf['PBS_EXEC'],
  178. 'bin', 'pbsnodes -a')
  179. ret = self.du.run_cmd(self.server.hostname, command)
  180. self.assertEqual(ret['rc'], 0)
  181. attr_list = ret['out']
  182. list_len = len(attr_list) - 1
  183. for i in range(1, list_len):
  184. attr = attr_list[i].split('=')[0].strip()
  185. val = attr_list[i].split('=')[1].strip()
  186. attr_dict[attr] = val
  187. # comparing the pbsnodes -a output with expected result
  188. for attr in expected_attrs:
  189. self.assertEqual(expected_attrs[attr], attr_dict[attr])
  190. self.verify_node_dynamic_val(attr_dict['last_state_change_time'],
  191. attr_dict['resources_available.ncpus'],
  192. attr_dict['pcpus'], attr_dict['sharing'],
  193. attr_dict['resources_available.mem'])
  194. @tags('smoke')
  195. @skipOnCpuSet
  196. @skipOnCray
  197. def test_pbsnodes_as_root(self):
  198. """
  199. Validate default values of node attributes for root user
  200. """
  201. self.common_setUp()
  202. attr_dict = {}
  203. expected_attrs = self.get_newnode_attrs('root')
  204. command = os.path.join(self.server.pbs_conf['PBS_EXEC'],
  205. 'bin', 'pbsnodes -a')
  206. ret = self.du.run_cmd(self.server.hostname, command, sudo=True)
  207. self.assertEqual(ret['rc'], 0)
  208. attr_list = ret['out']
  209. list_len = len(attr_list) - 1
  210. for i in range(1, list_len):
  211. attr = attr_list[i].split('=')[0].strip()
  212. val = attr_list[i].split('=')[1].strip()
  213. attr_dict[attr] = val
  214. # comparing the pbsnodes -a output with expected result
  215. for attr in expected_attrs:
  216. self.assertEqual(expected_attrs[attr], attr_dict[attr])
  217. self.verify_node_dynamic_val(attr_dict['last_state_change_time'],
  218. attr_dict['resources_available.ncpus'],
  219. attr_dict['pcpus'], attr_dict['sharing'],
  220. attr_dict['resources_available.mem'])