pbs_resc_used_single_node.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. import time
  37. from tests.functional import *
  38. class Test_singleNode_Job_ResourceUsed(TestFunctional):
  39. rsc_list = ['foo_str', 'foo_f', 'foo_i', 'foo_str2', 'foo_str3']
  40. def tearDown(self):
  41. self.du.set_pbs_config(confs={'PBS_SERVER': self.server.hostname})
  42. TestFunctional.tearDown(self)
  43. for r in self.rsc_list:
  44. try:
  45. self.server.manager(MGR_CMD_DELETE, RSC, id=r, runas=ROOT_USER)
  46. except:
  47. pass
  48. self.server.restart()
  49. self.mom.restart()
  50. def setUp(self):
  51. TestFunctional.setUp(self)
  52. for r in self.rsc_list:
  53. try:
  54. self.server.manager(MGR_CMD_DELETE, RSC, id=r, runas=ROOT_USER)
  55. except:
  56. pass
  57. self.server.restart()
  58. self.momA = self.moms.values()[0]
  59. self.momA.restart()
  60. self.momA.delete_vnode_defs()
  61. self.hostA = self.momA.shortname
  62. rc = self.server.manager(MGR_CMD_DELETE, NODE, None, "")
  63. self.assertEqual(rc, 0)
  64. rc = self.server.manager(MGR_CMD_CREATE, NODE, id=self.hostA)
  65. self.assertEqual(rc, 0)
  66. self.server.expect(NODE, {'state': 'free'}, id=self.hostA)
  67. a = {'job_history_enable': 'True'}
  68. self.server.manager(MGR_CMD_SET, SERVER, a)
  69. # Next set some custom resources via qmgr -c 'create resource'
  70. attr = {'type': 'string', 'flag': 'h'}
  71. r = 'foo_str2'
  72. rc = self.server.manager(
  73. MGR_CMD_CREATE, RSC, attr, id=r, runas=ROOT_USER, logerr=False)
  74. self.assertEqual(rc, 0)
  75. r = 'foo_str3'
  76. rc = self.server.manager(
  77. MGR_CMD_CREATE, RSC, attr, id=r, runas=ROOT_USER, logerr=False)
  78. self.assertEqual(rc, 0)
  79. attr['type'] = 'string_array'
  80. r = 'stra'
  81. rc = self.server.manager(
  82. MGR_CMD_CREATE, RSC, attr, id=r, runas=ROOT_USER, logerr=False)
  83. self.assertEqual(rc, 0)
  84. # Set some custom resources via exechost_startup hook.
  85. startup_hook_body = """
  86. import pbs
  87. e=pbs.event()
  88. localnode=pbs.get_local_nodename()
  89. e.vnode_list[localnode].resources_available['foo_i'] = 7
  90. e.vnode_list[localnode].resources_available['foo_f'] = 5.0
  91. e.vnode_list[localnode].resources_available['foo_str'] = "seventyseven"
  92. e.vnode_list[localnode].resources_available['foo_str2'] = "seven"
  93. """
  94. hook_name = "start"
  95. a = {'event': "exechost_startup", 'enabled': 'True'}
  96. rv = self.server.create_import_hook(
  97. hook_name,
  98. a,
  99. startup_hook_body,
  100. overwrite=True)
  101. self.assertTrue(rv)
  102. self.momA.signal("-HUP")
  103. # Give the moms a chance to receive the updated resource.
  104. # Ensure the new resource is seen by all moms.
  105. m = self.momA.log_match("resourcedef;copy hook-related file",
  106. max_attempts=20, interval=1)
  107. self.assertTrue(m)
  108. def test_epilogue_single_node(self):
  109. """
  110. Test accumulation of resources of a single node job from an
  111. exechost_epilogue hook.
  112. """
  113. self.logger.info("test_epilogue_single_node")
  114. hook_body = """
  115. import pbs
  116. e=pbs.event()
  117. pbs.logmsg(pbs.LOG_DEBUG, "executed epilogue hook")
  118. e.job.resources_used["vmem"] = pbs.size("9gb")
  119. e.job.resources_used["foo_i"] = 9
  120. e.job.resources_used["foo_f"] = 0.09
  121. e.job.resources_used["foo_str"] = '{"seven":7}'
  122. e.job.resources_used["foo_str3"] = \
  123. "\"\"{"a":6,"b":"some value #$%^&*@","c":54.4,"d":"32.5gb"}\"\"\"
  124. e.job.resources_used["foo_str2"] = "seven"
  125. e.job.resources_used["cput"] = 10
  126. e.job.resources_used["stra"] = '"glad,elated","happy"'
  127. """
  128. hook_name = "epi"
  129. a = {'event': "execjob_epilogue", 'enabled': 'True'}
  130. rv = self.server.create_import_hook(
  131. hook_name,
  132. a,
  133. hook_body,
  134. overwrite=True)
  135. self.assertTrue(rv)
  136. a = {'Resource_List.select': '1:ncpus=1',
  137. 'Resource_List.walltime': 3
  138. }
  139. j = Job(TEST_USER)
  140. j.set_attributes(a)
  141. j.set_sleep_time("3")
  142. jid = self.server.submit(j)
  143. # The results should show value for custom resources 'foo_i',
  144. # 'foo_f', 'foo_str', 'foo_str3', and builtin resources 'vmem',
  145. # 'cput', and should be accumulating based on the hook script,
  146. # For 'string' type resources set to a json string will be within
  147. # single quotes.
  148. #
  149. # foo_str and foo_str3 are string type resource set to JSON
  150. # format string
  151. self.server.expect(JOB, {
  152. 'job_state': 'F',
  153. 'resources_used.foo_f': '0.09',
  154. 'resources_used.foo_i': '9',
  155. 'resources_used.foo_str': '\'{"seven": 7}\'',
  156. 'resources_used.foo_str2': 'seven',
  157. 'resources_used.stra': "\"glad,elated\",\"happy\"",
  158. 'resources_used.vmem': '9gb',
  159. 'resources_used.cput': '00:00:10',
  160. 'resources_used.ncpus': '1'},
  161. extend='x', offset=10, attrop=PTL_AND, id=jid)
  162. # Match accounting_logs entry
  163. acctlog_match = 'resources_used.foo_f=0.09'
  164. s = self.server.accounting_match(
  165. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  166. self.assertTrue(s)
  167. acctlog_match = 'resources_used.foo_i=9'
  168. s = self.server.accounting_match(
  169. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  170. self.assertTrue(s)
  171. acctlog_match = 'resources_used.foo_str=\'{"seven": 7}\''
  172. s = self.server.accounting_match(
  173. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  174. self.assertTrue(s)
  175. acctlog_match = 'resources_used.vmem=9gb'
  176. s = self.server.accounting_match(
  177. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  178. self.assertTrue(s)
  179. acctlog_match = 'resources_used.cput=00:00:10'
  180. s = self.server.accounting_match(
  181. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  182. self.assertTrue(s)
  183. acctlog_match = 'resources_used.foo_str2=seven'
  184. s = self.server.accounting_match(
  185. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  186. self.assertTrue(s)
  187. acctlog_match = 'resources_used.ncpus=1'
  188. s = self.server.accounting_match(
  189. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  190. self.assertTrue(s)
  191. acctlog_match = 'resources_used.foo_str3='
  192. s = self.server.accounting_match(
  193. "E;%s;.*%s'{.*}'.*" % (jid, acctlog_match), regexp=True, n=100)
  194. self.assertTrue(s)
  195. acctlog_match = 'resources_used.stra=\"glad\,elated\"\,\"happy\"'
  196. s = self.server.accounting_match(
  197. "E;%s;.*%s.*" % (jid, acctlog_match), regexp=True, n=100)
  198. self.assertTrue(s)