pbs_ralter.py 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  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. class TestPbsResvAlter(TestFunctional):
  38. """
  39. This test suite is for testing the reservation times modification feature.
  40. """
  41. # Class variables
  42. tzone = None
  43. # These must be equal to the declarations in pbs_error.h
  44. PBSE_UNKRESVID = 236
  45. PBSE_RESV_NOT_EMPTY = 74
  46. PBSE_STDG_RESV_OCCR_CONFLICT = 75
  47. PBSE_INCORRECT_USAGE = 2
  48. fmt = "%a %b %d %H:%M:%S %Y"
  49. bu = BatchUtils()
  50. def setUp(self):
  51. TestFunctional.setUp(self)
  52. self.server.set_op_mode(PTL_CLI)
  53. # Set PBS_TZID, needed for standing reservation.
  54. if 'PBS_TZID' in self.conf:
  55. self.tzone = self.conf['PBS_TZID']
  56. elif 'PBS_TZID' in os.environ:
  57. self.tzone = os.environ['PBS_TZID']
  58. else:
  59. self.logger.info('Timezone not set, using Asia/Kolkata')
  60. self.tzone = 'Asia/Kolkata'
  61. a = {'resources_available.ncpus': 4}
  62. self.server.create_vnodes('vnode', a, num=2, mom=self.mom,
  63. usenatvnode=True)
  64. self.server.manager(MGR_CMD_SET, SERVER, {
  65. 'log_events': 4095}, expect=True)
  66. def submit_and_confirm_reservation(self, offset, duration, standing=False,
  67. select="1:ncpus=4",
  68. rrule="FREQ=HOURLY;COUNT=2",
  69. ExpectSuccess=1):
  70. """
  71. Helper function to submit a reservation and wait until it is confirmed.
  72. It also checks for the corresponding server and accounting logs.
  73. :param offset: time in seconds after which the reservation should
  74. start.
  75. :type offset: int
  76. :param duration: duration of the reservation to be submitted.
  77. :type duration: int
  78. :param standing: whether to submit a standing reservation. Default: No.
  79. :type standing: bool
  80. :param select: select specification for the reservation,
  81. Default: "1:ncpus=4"
  82. :type select: string.
  83. :param rrule: iCal recurrence rule for submitting a standing
  84. reservation. Default: "FREQ=HOURLY;COUNT=2"
  85. :type select: string.
  86. :param ExpectSuccess: Whether the caller expects the submission to be
  87. successful or not.
  88. :type ExpectSuccess: int.
  89. """
  90. start = int(time.time()) + offset
  91. end = start + duration
  92. if standing:
  93. attrs = {'Resource_List.select': select,
  94. 'reserve_start': start,
  95. 'reserve_end': end,
  96. 'reserve_timezone': self.tzone,
  97. 'reserve_rrule': rrule}
  98. else:
  99. attrs = {'Resource_List.select': select,
  100. 'reserve_start': start,
  101. 'reserve_end': end}
  102. rid = self.server.submit(Reservation(TEST_USER, attrs))
  103. msg = "Resv;" + rid + ";New reservation submitted start="
  104. msg += time.strftime(self.fmt, time.localtime(int(start)))
  105. msg += " end="
  106. msg += time.strftime(self.fmt, time.localtime(int(end)))
  107. if standing:
  108. msg += " recurrence_rrule=" + rrule + " timezone="
  109. msg += self.tzone
  110. self.server.log_match(msg, interval=2, max_attempts=30)
  111. if ExpectSuccess:
  112. attrs = {'reserve_state': (MATCH_RE, 'RESV_CONFIRMED|2')}
  113. self.server.expect(RESV, attrs, id=rid)
  114. msg = "Resv;" + rid + ";Reservation confirmed"
  115. self.server.log_match(msg, interval=2,
  116. max_attempts=30)
  117. self.server.expect(RESV, attrs, id=rid)
  118. acct_msg = "U;" + rid + ";requestor=" + TEST_USER.name + "@.*"
  119. if standing:
  120. acct_msg += " recurrence_rrule=" + re.escape(rrule)
  121. acct_msg += " timezone=" + re.escape(self.tzone)
  122. self.server.accounting_match(acct_msg, interval=2, regexp=True,
  123. max_attempts=30)
  124. else:
  125. msg = "Resv;" + rid + ";Reservation denied"
  126. self.server.log_match(msg, interval=2,
  127. max_attempts=30)
  128. return rid, start, end
  129. def check_resv_running(self, rid, offset=0, display=True):
  130. """
  131. Helper method to wait for reservation to start running.
  132. :param rid: Reservation id.
  133. :type rid: string.
  134. :param offset: Time in seconds to wait for the reservation to start
  135. running.
  136. :type offset: int.
  137. :param display: Whether to display a message or not, default - Yes.
  138. :type display: bool
  139. """
  140. if offset > 0:
  141. if display:
  142. self.logger.info("Waiting for reservation to start running.")
  143. else:
  144. self.logger.info("Sleeping.")
  145. attrs = {'reserve_state': (MATCH_RE, 'RESV_RUNNING|5')}
  146. self.server.expect(RESV, attrs, id=rid, offset=offset)
  147. def check_occr_finish(self, rid, duration):
  148. """
  149. Helper method to wait for a reservation occurrence to finish.
  150. This method will not work when waiting for the last occurrence of a
  151. standing reservation to finish running.
  152. :param rid: Reservation id.
  153. :type rid: string.
  154. :param duration: Time in seconds to wait for the reservation to finish
  155. running.
  156. :type duration: int.
  157. :param standing: Whether to display a message or not, default - Yes.
  158. :type standing: bool
  159. NOTE: This won't work for the final occurrence of a standing
  160. reservation.
  161. """
  162. if duration > 0:
  163. self.logger.info("Waiting for reservation to finish.")
  164. attrs = {'reserve_state': (MATCH_RE, 'RESV_CONFIRMED|2')}
  165. self.server.expect(RESV, attrs, id=rid,
  166. offset=(duration - 5), interval=2)
  167. def check_standing_resv_second_occurrence(self, rid, start, end):
  168. """
  169. Helper method to verify that the second occurrence of a standing
  170. reservation retains its original start and end times.
  171. Assumption: This method assumes that rid represents an HOURLY
  172. reservation.
  173. :param rid: Reservation id.
  174. :type rid: string.
  175. :param start: Start time of the first occurrence of the reservation.
  176. :type start: int.
  177. :param end: End time of the first occurrence of the reservation.
  178. :type end: int.
  179. """
  180. next_start = start + 3600
  181. next_end = end + 3600
  182. duration = end - start
  183. next_start_conv = self.bu.convert_seconds_to_datetime(
  184. next_start, self.fmt)
  185. next_end_conv = self.bu.convert_seconds_to_datetime(
  186. next_end, self.fmt)
  187. attrs = {'reserve_start': next_start_conv,
  188. 'reserve_end': next_end_conv,
  189. 'reserve_duration': duration}
  190. self.server.expect(RESV, attrs, id=rid)
  191. def submit_job_to_resv(self, rid, sleep=10):
  192. """
  193. Helper method for submitting a sleep job to the reservation.
  194. :param rid: Reservation id.
  195. :type rid: string.
  196. :param sleep: Sleep time in seconds for the job.
  197. :type sleep: int.
  198. """
  199. r_queue = rid.split('.')[0]
  200. a = {'queue': r_queue}
  201. j = Job(TEST_USER, a)
  202. j.set_sleep_time(sleep)
  203. jid = self.server.submit(j)
  204. return jid
  205. def alter_a_reservation(self, r, start, end, shift,
  206. alter_s=False, alter_e=False,
  207. whichMessage=1, confirm=True,
  208. interactive=0, sequence=1):
  209. """
  210. Helper method for altering a reservation.
  211. This method also checks for the server and accounting logs.
  212. :param r: Reservation id.
  213. :type r: string.
  214. :param start: Start time of the reservation.
  215. :type start: int.
  216. :param end: End time of the reservation.
  217. :type end: int.
  218. :param shift: Time in seconds the reservation times will be moved.
  219. :type shift: int.
  220. :param alter_s: Whether the caller intends to change the start time.
  221. Default - False.
  222. :type alter_s: bool.
  223. :param alter_e: Whether the caller intends to change the end time.
  224. Default - False.
  225. :type alter_e: bool.
  226. :param whichMessage: Which message is expected to be returned.
  227. Default: 1.
  228. =0 - PbsResvAlterError exception will be raised,
  229. so check for appropriate error response.
  230. =1 - No exception, check for "CONFIRMED" message
  231. =2 - No exception, check for "UNCONFIRMED" message
  232. =3 - No exception, check for "DENIED" message
  233. :type whichMessage: int.
  234. :param confirm: The expected state of the reservation after it is
  235. altered. It can be either Confirmed or Running.
  236. Default - Confirmed State.
  237. :type confirm: bool.
  238. :param interactive: Time in seconds the CLI waits for a reply.
  239. Default - 0 seconds.
  240. :type interactive: int.
  241. :param sequence: To check the number of log matches corresponding
  242. to alter.
  243. Default: 1
  244. :type sequence: int.
  245. """
  246. new_start = start
  247. new_end = end
  248. attrs = {}
  249. if alter_s:
  250. new_start = start + shift
  251. new_start_conv = self.bu.convert_seconds_to_datetime(
  252. new_start)
  253. attrs['reserve_start'] = new_start_conv
  254. if alter_e:
  255. new_end = end + shift
  256. new_end_conv = self.bu.convert_seconds_to_datetime(new_end)
  257. attrs['reserve_end'] = new_end_conv
  258. if interactive > 0:
  259. attrs['interactive'] = interactive
  260. new_duration = new_end - new_start
  261. if whichMessage:
  262. msg = ['']
  263. acct_msg = ['']
  264. if interactive:
  265. if whichMessage == 1:
  266. msg = "pbs_ralter: " + r + " CONFIRMED"
  267. elif whichMessage == 2:
  268. msg = "pbs_ralter: " + r + " UNCONFIRMED"
  269. else:
  270. msg = "pbs_ralter: " + r + " DENIED"
  271. else:
  272. msg = "pbs_ralter: " + r + " ALTER REQUESTED"
  273. self.server.alterresv(r, attrs)
  274. self.assertEqual(msg, self.server.last_out[0])
  275. self.logger.info(msg + " displayed")
  276. msg = "Resv;" + r + ";Attempting to modify reservation "
  277. if alter_s:
  278. msg += "start="
  279. msg += time.strftime(self.fmt, time.localtime(int(new_start)))
  280. if alter_e:
  281. if alter_s:
  282. msg += " "
  283. acct_msg += " "
  284. msg += "end="
  285. msg += time.strftime(self.fmt, time.localtime(int(new_end)))
  286. acct_msg += "end="
  287. acct_msg += str(new_end)
  288. self.server.log_match(msg, interval=2, max_attempts=30)
  289. if whichMessage == 1:
  290. if alter_s:
  291. new_start_conv = self.bu.convert_seconds_to_datetime(
  292. new_start, self.fmt)
  293. attrs['reserve_start'] = new_start_conv
  294. if alter_e:
  295. new_end_conv = self.bu.convert_seconds_to_datetime(
  296. new_end, self.fmt)
  297. attrs['reserve_end'] = new_end_conv
  298. attrs['reserve_duration'] = new_duration
  299. if confirm:
  300. attrs['reserve_state'] = (MATCH_RE, 'RESV_CONFIRMED|2')
  301. else:
  302. attrs['reserve_state'] = (MATCH_RE, 'RESV_RUNNING|5')
  303. self.server.expect(RESV, attrs, id=r)
  304. acct_msg = "Y;" + r + ";requestor=Scheduler@.*" + " start="
  305. acct_msg += str(new_start) + " end=" + str(new_end)
  306. self.server.status(RESV, 'resv_nodes', id=r)
  307. acct_msg += " nodes="
  308. acct_msg += re.escape(self.server.reservations[r].resvnodes())
  309. if r[0] == 'S':
  310. self.server.status(RESV, 'reserve_count', id=r)
  311. count = self.server.reservations[r].attributes[
  312. 'reserve_count']
  313. acct_msg += " count=" + count
  314. self.server.accounting_match(acct_msg, regexp=True, interval=2,
  315. max_attempts=30)
  316. # Check if reservation reports new start time
  317. # and updated duration.
  318. msg = "Resv;" + r + ";Reservation alter confirmed"
  319. else:
  320. msg = "Resv;" + r + ";Reservation alter denied"
  321. interval = 0.5
  322. max_attempts = 20
  323. for attempts in range(1, max_attempts + 1):
  324. lines = self.server.log_match(msg, n='ALL', allmatch=True,
  325. max_attempts=5)
  326. info_msg = "log_match: searching " + \
  327. str(sequence) + " sequence of message: " + \
  328. msg + ": Got: " + str(len(lines))
  329. self.logger.info(info_msg)
  330. if len(lines) == sequence:
  331. break
  332. else:
  333. attempts = attempts + 1
  334. time.sleep(interval)
  335. if attempts > max_attempts:
  336. raise PtlLogMatchError(rc=1, rv=False, msg=info_msg)
  337. return new_start, new_end
  338. else:
  339. try:
  340. self.server.alterresv(r, attrs)
  341. except PbsResvAlterError as e:
  342. if e.rc == self.PBSE_RESV_NOT_EMPTY:
  343. msg = "pbs_ralter: Reservation not empty"
  344. elif e.rc == self.PBSE_UNKRESVID:
  345. msg = "pbs_ralter: Unknown Reservation Id"
  346. elif e.rc == self.PBSE_STDG_RESV_OCCR_CONFLICT:
  347. msg = "Requested time(s) will interfere with "
  348. msg += "a later occurrence"
  349. log_msg = "Resv;" + r + ";" + msg
  350. msg = "pbs_ralter: " + msg
  351. self.server.log_match(log_msg, interval=2,
  352. max_attempts=30)
  353. elif e.rc == self.PBSE_INCORRECT_USAGE:
  354. pass
  355. self.assertNotEqual(e.msg, msg)
  356. return start, end
  357. else:
  358. self.assertFalse("Reservation alter allowed when it should" +
  359. "not be.")
  360. def test_alter_advance_resv_start_time_before_run(self):
  361. """
  362. This test case covers the below scenarios for an advance reservation
  363. that has not started running.
  364. 1. Make an advance reservation start late (empty reservation)
  365. 2. Make an advance reservation start early (empty reservation)
  366. 3. Make an advance reservation start early (with a job in it)
  367. All the above operations are expected to be successful.
  368. """
  369. offset = 20
  370. duration = 20
  371. shift = 10
  372. rid, start, end = self.submit_and_confirm_reservation(offset, duration)
  373. new_start, new_end = self.alter_a_reservation(rid, start, end, shift,
  374. alter_s=True, sequence=1)
  375. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  376. -shift, alter_s=True,
  377. interactive=5,
  378. sequence=2)
  379. # Submit a job to the reservation and change its start time.
  380. self.submit_job_to_resv(rid)
  381. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  382. -shift, alter_s=True,
  383. sequence=3)
  384. def test_alter_advance_resv_start_time_after_run(self):
  385. """
  386. This test case covers the below scenarios for an advance reservation
  387. that has started running.
  388. 1. Make an advance reservation start late (empty reservation)
  389. 2. Make an advance reservation start late (with a job in it)
  390. Only operation 1 should be successful, operation 2 should fail.
  391. """
  392. offset = 10
  393. duration = 20
  394. shift = 10
  395. rid, start, end = self.submit_and_confirm_reservation(offset, duration)
  396. # Wait for the reservation to start running.
  397. self.check_resv_running(rid, offset)
  398. # Changing start time should be allowed as the reservation is empty.
  399. self.alter_a_reservation(rid, start, end, shift, alter_s=True)
  400. # Wait for the reservation to start running.
  401. self.check_resv_running(rid, offset)
  402. # Submit a job to the reservation.
  403. self.submit_job_to_resv(rid)
  404. # Changing start time should fail this time as it is not empty.
  405. self.alter_a_reservation(rid, start, end, shift, alter_s=True,
  406. whichMessage=0)
  407. def test_alter_advance_resv_end_time_before_run(self):
  408. """
  409. This test case covers the below scenarios for an advance reservation
  410. that has not started running.
  411. 1. Make an advance reservation end late (empty reservation)
  412. 2. Make an advance reservation end late (empty reservation)
  413. 3. Make an advance reservation end late (with a job in it)
  414. All the above operations are expected to be successful.
  415. """
  416. duration = 20
  417. shift = 10
  418. offset = 10
  419. rid, start, end = self.submit_and_confirm_reservation(offset, duration)
  420. new_start, new_end = self.alter_a_reservation(rid, start, end, shift,
  421. alter_e=True, sequence=1)
  422. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  423. shift, alter_e=True,
  424. sequence=2)
  425. # Submit a job to the reservation.
  426. self.submit_job_to_resv(rid)
  427. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  428. shift, alter_e=True,
  429. sequence=3)
  430. def test_alter_advance_resv_end_time_after_run(self):
  431. """
  432. This test case covers the below scenarios for an advance reservation
  433. that has started running.
  434. 1. Make an advance reservation end late (with a job in it)
  435. The above operation is expected to be successful.
  436. """
  437. duration = 20
  438. shift = 10
  439. offset = 10
  440. sleep = 25
  441. rid, start, end = self.submit_and_confirm_reservation(offset, duration)
  442. # Submit a job to the reservation.
  443. jid = self.submit_job_to_resv(rid, sleep)
  444. # Wait for the reservation to start running.
  445. self.check_resv_running(rid, offset)
  446. self.alter_a_reservation(rid, start, end, shift, alter_e=True,
  447. confirm=False)
  448. self.check_resv_running(rid, duration, 0)
  449. self.server.expect(JOB, {'job_state': "R"}, id=jid)
  450. def test_alter_advance_resv_both_times_before_run(self):
  451. """
  452. This test case covers the below scenarios for an advance reservation
  453. that has not started running.
  454. 1. Make an advance reservation start and end late (empty reservation)
  455. 2. Make an advance reservation start and end early (empty reservation)
  456. 3. Make an advance reservation start and end early (with a job in it)
  457. All the above operations are expected to be successful.
  458. """
  459. offset = 40
  460. duration = 20
  461. shift = 10
  462. rid, start, end = self.submit_and_confirm_reservation(offset, duration)
  463. new_start, new_end = self.alter_a_reservation(rid, start, end,
  464. shift, alter_s=True,
  465. alter_e=True, sequence=1)
  466. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  467. -shift, alter_s=True,
  468. alter_e=True, sequence=2)
  469. # Submit a job to the reservation and change its start time.
  470. self.submit_job_to_resv(rid)
  471. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  472. -shift, alter_s=True,
  473. alter_e=True, sequence=3)
  474. def test_alter_advance_resv_both_times_after_run(self):
  475. """
  476. This test case covers the below scenarios for an advance reservation
  477. that has started running.
  478. 1. Make an advance reservation start and end late (empty reservation)
  479. 2. Make an advance reservation start and end late (with a job in it)
  480. Only operation 1 should be successful, operation 2 should fail.
  481. """
  482. offset = 10
  483. duration = 20
  484. shift = 10
  485. rid, start, end = self.submit_and_confirm_reservation(offset, duration)
  486. # Wait for the reservation to start running.
  487. self.check_resv_running(rid, offset)
  488. # Changing start time should be allowed as the reservation is empty.
  489. new_start, new_end = self.alter_a_reservation(rid, start, end,
  490. shift, alter_s=True,
  491. alter_e=True)
  492. # Wait for the reservation to start running.
  493. self.check_resv_running(rid, offset)
  494. # Submit a job to the reservation.
  495. self.submit_job_to_resv(rid)
  496. # Changing start time should fail this time as it is not empty.
  497. self.alter_a_reservation(rid, new_start, new_end,
  498. shift, alter_s=True,
  499. alter_e=True, whichMessage=0)
  500. def test_alter_standing_resv_start_time_before_run(self):
  501. """
  502. This test case covers the below scenarios for a standing reservation
  503. that has not started running.
  504. 1. Make an occurrence of a standing reservation start
  505. late (empty reservation)
  506. 2. Make an occurrence of a standing reservation start
  507. early (empty reservation)
  508. 3. Make an occurrence of a standing reservation start
  509. early (with a job in it)
  510. 4. After the first occurrence of the reservation finishes, verify that
  511. the start and end time of the second occurrence have not changed.
  512. All the above operations are expected to be successful.
  513. """
  514. offset = 30
  515. duration = 20
  516. shift = 15
  517. rid, start, end = self.submit_and_confirm_reservation(offset,
  518. duration,
  519. standing=True)
  520. new_start, new_end = self.alter_a_reservation(rid, start, end, shift,
  521. alter_s=True, sequence=1)
  522. new_start, new_end = self.alter_a_reservation(rid, new_start,
  523. new_end, -shift,
  524. alter_s=True, sequence=2)
  525. # Submit a job to the reservation and change its start time.
  526. self.submit_job_to_resv(rid)
  527. new_start, new_end = self.alter_a_reservation(rid, new_start,
  528. new_end, -shift,
  529. alter_s=True, sequence=3)
  530. # Wait for the reservation to start running.
  531. self.check_resv_running(rid, offset - shift)
  532. # Wait for the reservation occurrence to finish.
  533. new_duration = new_end - new_start
  534. self.check_occr_finish(rid, new_duration)
  535. # Check that duration of the second occurrence is not altered.
  536. self.check_standing_resv_second_occurrence(rid, start, end)
  537. def test_alter_standing_resv_start_time_after_run(self):
  538. """
  539. This test case covers the below scenarios for a standing reservation
  540. that has started running.
  541. 1. Make an occurrence of a standing reservation start
  542. late (empty reservation)
  543. 2. Make an occurrence of a standing reservation start
  544. late (with a job in it)
  545. 3. After the first occurrence of the reservation finishes, verify that
  546. the start and end time of the second occurrence have not changed.
  547. Only operations 1 and 3 should be successful, operation 2 should fail.
  548. """
  549. offset = 10
  550. duration = 20
  551. shift = 10
  552. rid, start, end = self.submit_and_confirm_reservation(offset, duration,
  553. standing=True)
  554. # Wait for the reservation to start running.
  555. self.check_resv_running(rid, offset)
  556. # Changing start time should be allowed as the reservation is empty.
  557. new_start, new_end = self.alter_a_reservation(rid, start, end, shift,
  558. alter_s=True)
  559. # Wait for the reservation to start running.
  560. self.check_resv_running(rid, offset)
  561. # Submit a job to the reservation.
  562. self.submit_job_to_resv(rid)
  563. # Changing start time should fail this time as it is not empty.
  564. self.alter_a_reservation(rid, new_start, new_end, shift,
  565. alter_s=True, whichMessage=False)
  566. # Wait for the reservation occurrence to finish.
  567. new_duration = new_end - new_start
  568. self.check_occr_finish(rid, new_duration)
  569. # Check that duration of the second occurrence is not altered.
  570. self.check_standing_resv_second_occurrence(rid, start, end)
  571. def test_alter_standing_resv_end_time_before_run(self):
  572. """
  573. This test case covers the below scenarios for a standing reservation
  574. that has not started running and some scenarios after it starts
  575. running.
  576. 1. Make an occurrence of a standing reservation end
  577. late (empty reservation)
  578. 2. Make an occurrence of a standing reservation end early
  579. (empty reservation)
  580. 3. Make an occurrence of a standing reservation end
  581. late (with a job in it)
  582. 4. Check if the reservation continues to be in Running state after the
  583. original end time has passed.
  584. 5. Verify that the job inside this reservation also continues to run
  585. after the original end time has passed.
  586. 6. After the first occurrence of the reservation finishes, verify that
  587. the start and end time of the second occurrence have not changed.
  588. All the above operations are expected to be successful.
  589. """
  590. duration = 20
  591. shift = 10
  592. offset = 10
  593. rid, start, end = self.submit_and_confirm_reservation(offset, duration,
  594. standing=True)
  595. new_start, new_end = self.alter_a_reservation(rid, start, end, shift,
  596. alter_e=True, sequence=1)
  597. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  598. -shift, alter_e=True,
  599. sequence=2)
  600. # Submit a job to the reservation.
  601. jid = self.submit_job_to_resv(rid, 100)
  602. new_start, new_end = self.alter_a_reservation(rid, start, end, shift,
  603. alter_e=True, sequence=3)
  604. self.check_resv_running(rid, offset)
  605. self.server.expect(JOB, {'job_state': "R"}, id=jid)
  606. # Sleep for the actual duration.
  607. time.sleep(duration)
  608. self.check_resv_running(rid)
  609. self.server.expect(JOB, {'job_state': "R"}, id=jid)
  610. # Wait for the reservation occurrence to finish.
  611. self.check_occr_finish(rid, shift)
  612. # Check that duration of the second occurrence is not altered.
  613. self.check_standing_resv_second_occurrence(rid, start, end)
  614. def test_alter_standing_resv_end_time_after_run(self):
  615. """
  616. This test case covers the below scenarios for a standing reservation
  617. that has started running.
  618. 1. Make an occurrence of a standing reservation end
  619. late (with a job in it)
  620. 2. Check if the reservation continues to be in Running state after the
  621. original end time has passed.
  622. 3. Verify that the job inside this reservation also continues to run
  623. after the original end time has passed.
  624. 4. After the first occurrence of the reservation finishes, verify that
  625. the start and end time of the second occurrence have not changed.
  626. All the above operations are expected to be successful.
  627. """
  628. duration = 20
  629. shift = 10
  630. offset = 10
  631. sleep = 25
  632. rid, start, end = self.submit_and_confirm_reservation(offset, duration,
  633. standing=True)
  634. # Submit a job to the reservation.
  635. jid = self.submit_job_to_resv(rid, sleep)
  636. # Wait for the reservation to start running.
  637. self.check_resv_running(rid, offset)
  638. new_end = self.alter_a_reservation(rid, start, end,
  639. shift, alter_e=True,
  640. confirm=False)[1]
  641. self.check_resv_running(rid, duration, 0)
  642. self.server.expect(JOB, {'job_state': "R"}, id=jid)
  643. # Wait for the reservation occurrence to finish.
  644. new_duration = int(new_end - time.time())
  645. self.check_occr_finish(rid, new_duration)
  646. # Check that duration of the second occurrence is not altered.
  647. self.check_standing_resv_second_occurrence(rid, start, end)
  648. def test_alter_standing_resv_both_times_before_run(self):
  649. """
  650. This test case covers the below scenarios for a standing reservation
  651. that has not started running.
  652. 1. Make an occurrence of a standing reservation start and end
  653. late (empty reservation).
  654. 2. Make an occurrence of a standing reservation start and end early
  655. (empty reservation).
  656. 3. Make an occurrence of a standing reservation start and end early
  657. (with a job in it).
  658. 4. Check if the reservation starts and ends as per the new times.
  659. 5. After the first occurrence of the reservation finishes, verify that
  660. the start and end time of the second occurrence have not changed.
  661. All the above operations are expected to be successful.
  662. """
  663. offset = 40
  664. duration = 20
  665. shift = 10
  666. rid, start, end = self.submit_and_confirm_reservation(offset,
  667. duration,
  668. standing=True)
  669. new_start, new_end = self.alter_a_reservation(rid, start, end,
  670. shift, alter_s=True,
  671. alter_e=True, sequence=1)
  672. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  673. -shift, alter_s=True,
  674. alter_e=True, sequence=2)
  675. # Submit a job to the reservation and change its start time.
  676. self.submit_job_to_resv(rid)
  677. new_start, new_end = self.alter_a_reservation(rid, new_start, new_end,
  678. -shift, alter_s=True,
  679. alter_e=True, sequence=3)
  680. # Wait for the reservation to start running.
  681. self.check_resv_running(rid, offset - shift)
  682. # Wait for the reservation occurrence to finish.
  683. self.check_occr_finish(rid, duration)
  684. # Check that duration of the second occurrence is not altered.
  685. self.check_standing_resv_second_occurrence(rid, start, end)
  686. def test_alter_standing_resv_both_times_after_run(self):
  687. """
  688. This test case covers the below scenarios for a standing reservation
  689. that has started running.
  690. 1. Make an occurrence of a standing reservation start and end
  691. late (empty reservation).
  692. 2. Make an occurrence of a standing reservation start and end
  693. late (with a job in it).
  694. 3. Check if the reservation starts and ends as per the new times.
  695. 4. After the first occurrence of the reservation finishes, verify that
  696. the start and end time of the second occurrence have not changed.
  697. Only scenario 1, 3 and 4 should be successful, operation 3
  698. should fail.
  699. """
  700. offset = 10
  701. duration = 20
  702. shift = 10
  703. rid, start, end = self.submit_and_confirm_reservation(offset, duration,
  704. standing=True)
  705. # Wait for the reservation to start running.
  706. self.check_resv_running(rid, offset)
  707. # Changing start time should be allowed as the reservation is empty.
  708. new_start, new_end = self.alter_a_reservation(rid, start, end,
  709. shift, alter_s=True,
  710. alter_e=True,
  711. confirm=False)
  712. # Wait for the reservation to start running.
  713. self.check_resv_running(rid, offset)
  714. # Submit a job to the reservation.
  715. self.submit_job_to_resv(rid)
  716. # Changing start time should fail this time as it is not empty.
  717. self.alter_a_reservation(rid, new_start, new_end, shift,
  718. alter_s=True, alter_e=True,
  719. whichMessage=False)
  720. # Wait for the reservation occurrence to finish.
  721. self.check_occr_finish(rid, duration)
  722. # Check that duration of the second occurrence is not altered.
  723. self.check_standing_resv_second_occurrence(rid, start, end)
  724. def test_conflict_two_advance_resvs(self):
  725. """
  726. This test confirms that an advance reservation cannot be extended
  727. (made to end late) if there is a conflicting reservation and all the
  728. nodes in the complex are busy.
  729. Two back to back advance reservations are submitted that use all the
  730. nodes in the complex to test this.
  731. """
  732. duration = 120
  733. shift = 10
  734. offset1 = 60
  735. offset2 = 180
  736. rid1, start1, end1 = self.submit_and_confirm_reservation(
  737. offset1, duration, select="2:ncpus=4")
  738. rid2, start2, end2 = self.submit_and_confirm_reservation(
  739. offset2, duration, select="2:ncpus=4")
  740. self.submit_and_confirm_reservation(offset1, duration,
  741. select="2:ncpus=4",
  742. ExpectSuccess=0)
  743. self.alter_a_reservation(rid1, start1, end1, shift, alter_e=True,
  744. whichMessage=3)
  745. self.alter_a_reservation(rid1, start1, end1, shift, alter_e=True,
  746. whichMessage=3, interactive=5, sequence=2)
  747. self.alter_a_reservation(rid2, start2, end2, -shift, alter_s=True,
  748. whichMessage=3)
  749. self.alter_a_reservation(rid2, start2, end2, -shift, alter_s=True,
  750. whichMessage=3, interactive=5, sequence=2)
  751. def test_conflict_two_standing_resvs(self):
  752. """
  753. This test confirms that an occurrence of a standing reservation cannot
  754. be extended (made to end late) if there is a conflicting reservation
  755. and all the nodes in the complex are busy.
  756. Two back to back standing reservations are submitted that use all the
  757. nodes in the complex to test this.
  758. """
  759. duration = 120
  760. shift = 10
  761. offset1 = 60
  762. offset2 = 180
  763. rid1, start1, end1 = self.submit_and_confirm_reservation(
  764. offset1, duration, select="2:ncpus=4", standing=True)
  765. rid2, start2, end2 = self.submit_and_confirm_reservation(
  766. offset2, duration, select="2:ncpus=4", standing=True)
  767. self.submit_and_confirm_reservation(offset1, duration,
  768. select="2:ncpus=4",
  769. ExpectSuccess=0, standing=True)
  770. self.alter_a_reservation(rid1, start1, end1, shift, alter_e=True,
  771. whichMessage=3)
  772. self.alter_a_reservation(rid1, start1, end1, shift, alter_e=True,
  773. whichMessage=3, interactive=5, sequence=2)
  774. self.alter_a_reservation(rid2, start2, end2, -shift, alter_s=True,
  775. whichMessage=3)
  776. self.alter_a_reservation(rid2, start2, end2, -shift, alter_s=True,
  777. whichMessage=3, interactive=5, sequence=2)
  778. def test_check_alternate_nodes_advance_resv_endtime(self):
  779. """
  780. This test confirms that an advance reservation can be extended even if
  781. there is a conflicting reservation but there are nodes in the complex
  782. that satisfy the resource requirements of the reservation.
  783. Two back to back advance reservations are submitted that use the
  784. same nodes in the complex to test this and end time of the later
  785. reservation is altered.
  786. """
  787. duration = 120
  788. shift = 10
  789. offset1 = 60
  790. offset2 = 180
  791. rid1, start1, end1 = self.submit_and_confirm_reservation(
  792. offset1, duration, select="1:ncpus=4")
  793. self.server.status(RESV, 'resv_nodes', id=rid1)
  794. resv_node = self.server.reservations[rid1].get_vnodes()[0]
  795. select = "1:vnode=" + resv_node + ":ncpus=4"
  796. rid2 = self.submit_and_confirm_reservation(
  797. offset2, duration, select=select)[0]
  798. attrs = {'resv_nodes': (MATCH_RE, re.escape(resv_node))}
  799. self.server.expect(RESV, attrs, id=rid2)
  800. nodes = self.server.status(NODE)
  801. free_node = nodes[resv_node == nodes[0]['id']]['id']
  802. self.alter_a_reservation(rid1, start1, end1, shift, alter_e=True)
  803. attrs = {'resv_nodes': (MATCH_RE, re.escape(free_node))}
  804. self.server.expect(RESV, attrs, id=rid1)
  805. def test_check_alternate_nodes_advance_resv_starttime(self):
  806. """
  807. This test confirms that an advance reservation can be extended even if
  808. there is a conflicting reservation but there are nodes in the complex
  809. that satisfy the resource requirements of the reservation.
  810. Two back to back advance reservations are submitted that use the
  811. same nodes in the complex to test this and start time of the former
  812. reservation is altered.
  813. """
  814. duration = 120
  815. shift = 40
  816. offset1 = 180
  817. offset2 = 30
  818. rid1, start1, end1 = self.submit_and_confirm_reservation(
  819. offset1, duration, select="1:ncpus=4")
  820. self.server.status(RESV, 'resv_nodes', id=rid1)
  821. resv_node = self.server.reservations[rid1].get_vnodes()[0]
  822. select = "1:vnode=" + resv_node + ":ncpus=4"
  823. rid2 = self.submit_and_confirm_reservation(offset2, duration,
  824. select=select)[0]
  825. attrs = {'resv_nodes': (MATCH_RE, re.escape(resv_node))}
  826. self.server.expect(RESV, attrs, id=rid2)
  827. nodes = self.server.status(NODE)
  828. free_node = nodes[resv_node == nodes[0]['id']]['id']
  829. self.alter_a_reservation(rid1, start1, end1, -shift, alter_s=True)
  830. attrs = {'resv_nodes': (MATCH_RE, re.escape(free_node))}
  831. self.server.expect(RESV, attrs, id=rid1)
  832. def test_check_alternate_nodes_standing_resv_endtime(self):
  833. """
  834. This test confirms that an occurrence of a standing reservation can be
  835. extended even if there is a conflicting reservation but there are
  836. nodes in the complex that satisfy the resource requirements of the
  837. reservation.
  838. Two back to back standing reservations are submitted that use the
  839. same nodes in the complex to test this and end time of the later
  840. reservation is altered.
  841. """
  842. duration = 120
  843. shift = 10
  844. offset1 = 60
  845. offset2 = 180
  846. rid1, start1, end1 = self.submit_and_confirm_reservation(
  847. offset1, duration, standing=True)
  848. self.server.status(RESV, 'resv_nodes', id=rid1)
  849. resv_node = self.server.reservations[rid1].get_vnodes()[0]
  850. select = "1:vnode=" + resv_node + ":ncpus=4"
  851. rid2 = self.submit_and_confirm_reservation(offset2, duration,
  852. select=select,
  853. standing=True)[0]
  854. attrs = {'resv_nodes': (MATCH_RE, re.escape(resv_node))}
  855. self.server.expect(RESV, attrs, id=rid2)
  856. nodes = self.server.status(NODE)
  857. free_node = nodes[resv_node == nodes[0]['id']]['id']
  858. self.alter_a_reservation(rid1, start1, end1, shift, alter_e=True)
  859. attrs = {'resv_nodes': (MATCH_RE, re.escape(free_node))}
  860. self.server.expect(RESV, attrs, id=rid1)
  861. def test_check_alternate_nodes_standing_resv_starttime(self):
  862. """
  863. This test confirms that an advance reservation can be extended even if
  864. there is a conflicting reservation but there are nodes in the complex
  865. that satisfy the resource requirements of the reservation.
  866. Two back to back advance reservations are submitted that use the
  867. same nodes in the complex to test this and start time of the former
  868. reservation is altered.
  869. """
  870. duration = 120
  871. shift = 40
  872. offset1 = 30
  873. offset2 = 180
  874. rid1, start1, end1 = self.submit_and_confirm_reservation(
  875. offset2, duration, select="1:ncpus=4", standing=True)
  876. self.server.status(RESV, 'resv_nodes', id=rid1)
  877. resv_node = self.server.reservations[rid1].get_vnodes()[0]
  878. select = "1:vnode=" + resv_node + ":ncpus=4"
  879. rid2 = self.submit_and_confirm_reservation(offset1, duration,
  880. select=select,
  881. standing=True)[0]
  882. attrs = {'resv_nodes': (MATCH_RE, re.escape(resv_node))}
  883. self.server.expect(RESV, attrs, id=rid2)
  884. nodes = self.server.status(NODE)
  885. free_node = nodes[resv_node == nodes[0]['id']]['id']
  886. self.alter_a_reservation(rid1, start1, end1, -shift, alter_s=True)
  887. attrs = {'resv_nodes': (MATCH_RE, re.escape(free_node))}
  888. self.server.expect(RESV, attrs, id=rid1)
  889. def test_conflict_standing_resv_occurrence(self):
  890. """
  891. This test confirms that if the requested time while altering an
  892. occurrence of a standing reservation will conflict with a later
  893. occurrence of the same standing reservation, the alter request
  894. will be denied.
  895. """
  896. duration = 60
  897. shift = 10
  898. offset = 10
  899. rid, start, end = self.submit_and_confirm_reservation(
  900. offset, duration, select="1:ncpus=4", standing=True,
  901. rrule="FREQ=MINUTELY;COUNT=2")
  902. self.alter_a_reservation(rid, start, end, shift, alter_e=True,
  903. whichMessage=0)
  904. def test_large_resv_nodes_server_crash(self):
  905. """
  906. This test is to test whether the server crashes or not when a very
  907. large resv_nodes is being recorded in the 'Y' accounting log.
  908. If tested with a build without the fix, the test case will fail
  909. and vice versa.
  910. """
  911. duration = 60
  912. shift = 10
  913. offset = 10
  914. a = {'resources_available.ncpus': 4}
  915. self.server.create_vnodes('vnode', a, num=256, mom=self.mom,
  916. usenatvnode=True)
  917. rid, start, end = self.submit_and_confirm_reservation(
  918. offset, duration, select="256:ncpus=4")
  919. self.alter_a_reservation(rid, start, end, shift, alter_s=True)
  920. def test_alter_advance_resv_boundary_values(self):
  921. """
  922. This test checks the alter of start and end times at the boundary
  923. values for advance reservation.
  924. """
  925. duration = 30
  926. shift = 5
  927. offset = 5
  928. rid, start, end = self.submit_and_confirm_reservation(
  929. offset, duration)
  930. start, end = self.alter_a_reservation(
  931. rid, start, end, shift, alter_e=True, sequence=1)
  932. start, end = self.alter_a_reservation(
  933. rid, start, end, -shift, alter_e=True, sequence=2)
  934. start, end = self.alter_a_reservation(
  935. rid, start, end, shift, alter_s=True, sequence=3)
  936. self.alter_a_reservation(
  937. rid, start, end, -shift, alter_s=True, sequence=4)
  938. def test_alter_standing_resv_boundary_values(self):
  939. """
  940. This test checks the alter of start and end times at the boundary
  941. values for standing reservation.
  942. """
  943. duration = 30
  944. shift = 5
  945. offset = 5
  946. rid, start, end = self.submit_and_confirm_reservation(
  947. offset, duration, standing=True)
  948. start, end = self.alter_a_reservation(
  949. rid, start, end, shift, alter_e=True, sequence=1)
  950. start, end = self.alter_a_reservation(
  951. rid, start, end, -shift, alter_e=True, sequence=2)
  952. start, end = self.alter_a_reservation(
  953. rid, start, end, shift, alter_s=True, sequence=3)
  954. self.alter_a_reservation(
  955. rid, start, end, -shift, alter_s=True, sequence=4)
  956. def test_alter_degraded_resv_mom_down(self):
  957. """
  958. This test checks the alter of start and end times of reservations
  959. when mom is down.
  960. """
  961. duration = 30
  962. shift = 5
  963. offset = 60
  964. rid1, start1, end1 = self.submit_and_confirm_reservation(
  965. offset, duration, select="1:ncpus=2")
  966. rid2, start2, end2 = self.submit_and_confirm_reservation(
  967. offset, duration, select="1:ncpus=2", standing=True)
  968. self.mom.stop()
  969. msg = 'mom is not down'
  970. self.assertFalse(self.mom.isUp(), msg)
  971. attrs = {'reserve_state': (MATCH_RE, 'RESV_DEGRADED|10')}
  972. self.server.expect(RESV, attrs, id=rid1)
  973. self.server.expect(RESV, attrs, id=rid2)
  974. self.alter_a_reservation(rid1, start1, end1, shift, alter_s=True,
  975. alter_e=True, whichMessage=3, sequence=1)
  976. self.alter_a_reservation(rid2, start2, end2, shift, alter_s=True,
  977. alter_e=True, whichMessage=3, sequence=1)
  978. self.alter_a_reservation(rid1, start1, end1, shift, alter_s=True,
  979. alter_e=True, whichMessage=3, interactive=2,
  980. sequence=2)
  981. self.alter_a_reservation(rid2, start2, end2, shift, alter_s=True,
  982. alter_e=True, whichMessage=3, interactive=2,
  983. sequence=2)
  984. self.mom.start()
  985. # test same for node offline case
  986. attrs1 = {'reserve_state': (MATCH_RE, 'RESV_CONFIRMED|2')}
  987. self.server.expect(RESV, attrs1, id=rid1)
  988. self.server.expect(RESV, attrs1, id=rid2)
  989. resv_node1 = self.server.status(RESV, 'resv_nodes', id=rid1)[0][
  990. 'resv_nodes'].split(':')[0].split('(')[1]
  991. resv_node2 = self.server.status(RESV, 'resv_nodes', id=rid2)[0][
  992. 'resv_nodes'].split(':')[0].split('(')[1]
  993. if resv_node1 is resv_node2:
  994. self.server.manager(MGR_CMD_SET, NODE, {
  995. 'state': "offline"}, id=resv_node1)
  996. else:
  997. self.server.manager(MGR_CMD_SET, NODE, {
  998. 'state': "offline"}, id=resv_node1)
  999. self.server.manager(MGR_CMD_SET, NODE, {
  1000. 'state': "offline"}, id=resv_node2)
  1001. self.server.expect(RESV, attrs, id=rid1)
  1002. self.server.expect(RESV, attrs, id=rid2)
  1003. self.alter_a_reservation(rid1, start1, end1, shift, alter_s=True,
  1004. alter_e=True, whichMessage=3, sequence=3)
  1005. self.alter_a_reservation(rid2, start2, end2, shift, alter_s=True,
  1006. alter_e=True, whichMessage=3, sequence=3)
  1007. self.alter_a_reservation(rid1, start1, end1, shift, alter_s=True,
  1008. alter_e=True, whichMessage=3, interactive=2,
  1009. sequence=4)
  1010. self.alter_a_reservation(rid2, start2, end2, shift, alter_s=True,
  1011. alter_e=True, whichMessage=3, interactive=2,
  1012. sequence=4)
  1013. def test_alter_resv_name(self):
  1014. """
  1015. This test checks the alter of reservation name.
  1016. """
  1017. duration = 30
  1018. offset = 5
  1019. rid1 = self.submit_and_confirm_reservation(
  1020. offset, duration)
  1021. rid2 = self.submit_and_confirm_reservation(
  1022. offset, duration, standing=True)
  1023. attr1 = {ATTR_N: "Adv_Resv"}
  1024. self.server.alterresv(rid1[0], attr1)
  1025. attr2 = {ATTR_N: "Std_Resv"}
  1026. self.server.alterresv(rid2[0], attr2)
  1027. attr1 = {'Reserve_Name': "Adv_Resv"}
  1028. attr2 = {'Reserve_Name': "Std_Resv"}
  1029. self.server.expect(RESV, attr1, id=rid1[0])
  1030. self.server.expect(RESV, attr2, id=rid2[0])
  1031. def test_alter_user_permission(self):
  1032. """
  1033. This test checks the user permissions for pbs_ralter.
  1034. """
  1035. duration = 30
  1036. offset = 5
  1037. shift = 10
  1038. rid1, start1, end1 = self.submit_and_confirm_reservation(
  1039. offset, duration)
  1040. rid2, start2, end2 = self.submit_and_confirm_reservation(
  1041. offset, duration, standing=True)
  1042. new_start1 = self.bu.convert_seconds_to_datetime(start1 + shift)
  1043. new_start2 = self.bu.convert_seconds_to_datetime(start2 + shift)
  1044. new_end1 = self.bu.convert_seconds_to_datetime(end1 + shift)
  1045. new_end2 = self.bu.convert_seconds_to_datetime(end2 + shift)
  1046. try:
  1047. attr = {'reserve_start': new_start1, 'reserve_end': new_end1}
  1048. self.server.alterresv(rid1, attr, runas=TEST_USER1)
  1049. except PbsResvAlterError as e:
  1050. self.assertTrue("Unauthorized Request" in e.msg[0])
  1051. try:
  1052. attr = {'reserve_start': new_start2, 'reserve_end': new_end2}
  1053. self.server.alterresv(rid2, attr, runas=TEST_USER1)
  1054. except PbsResvAlterError as e:
  1055. self.assertTrue("Unauthorized Request" in e.msg[0])