pbs_client_nagle_performance.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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 os
  37. import timeit
  38. from tests.performance import *
  39. class TestClientNagles(TestPerformance):
  40. """
  41. Testing the effect of Nagles algorithm on CLI Performance
  42. """
  43. time_command = 'time'
  44. def setUp(self):
  45. """
  46. Base class method overriding
  47. builds absolute path of commands to execute
  48. """
  49. TestPerformance.setUp(self)
  50. self.time_command = self.du.which(exe="time")
  51. if self.time_command == "time":
  52. self.skipTest("Time command not found")
  53. def tearDown(self):
  54. """
  55. cleanup jobs
  56. """
  57. TestPerformance.tearDown(self)
  58. self.server.cleanup_jobs(runas=ROOT_USER)
  59. def compute_qdel_time(self):
  60. """
  61. Computes qdel time in secs"
  62. return :
  63. -1 on qdel fail
  64. """
  65. qsel_list = self.server.select()
  66. qsel_list = " ".join(qsel_list)
  67. command = self.time_command
  68. command += " -f \"%e\" "
  69. command += os.path.join(self.server.client_conf['PBS_EXEC'],
  70. 'bin',
  71. 'qdel ')
  72. command += qsel_list
  73. # compute elapse time without -E option
  74. qdel_perf = self.du.run_cmd(self.server.hostname,
  75. command,
  76. as_script=True,
  77. runas=TEST_USER1,
  78. logerr=False)
  79. if qdel_perf['rc'] != 0:
  80. return -1
  81. return qdel_perf['err'][0]
  82. def submit_jobs(self, user, num_jobs):
  83. """
  84. Submit specified number of simple jobs
  85. Arguments :
  86. user - user under which to submit jobs
  87. num_jobs - number of jobs to submit
  88. """
  89. job = Job(user)
  90. job.set_sleep_time(1)
  91. for _ in range(num_jobs):
  92. self.server.submit(job)
  93. @timeout(600)
  94. def test_qdel_nagle_perf(self):
  95. """
  96. Submit 500 jobs, measure qdel performace before/after adding managers
  97. """
  98. # Adding to managers ensures that packets are larger than 1023 bytes
  99. # that triggers Nagle's algorithm which slows down the communication.
  100. # Effect on TCP seems irreversible till server is restarted, so in
  101. # this test case we restart server so that any effects from earlier
  102. # test cases/runs do not interfere
  103. # Baseline qdel performance with scheduling false and managers unset
  104. # Restart server to ensure no effect from earlier tests/operations
  105. self.server.manager(MGR_CMD_SET, SERVER, {'scheduling': 'False'})
  106. self.server.manager(MGR_CMD_UNSET, SERVER, 'managers')
  107. self.server.restart()
  108. self.submit_jobs(TEST_USER1, 500)
  109. qdel_perf = self.compute_qdel_time()
  110. self.assertTrue((qdel_perf != -1), "qdel command failed")
  111. # Add to the managers list so that TCP packets are now larger and
  112. # triggers Nagle's
  113. manager = TEST_USER1.name + '@' + self.server.hostname
  114. self.server.manager(MGR_CMD_SET, SERVER, {
  115. 'managers': (INCR, manager)}, sudo=True)
  116. # Remeasure the qdel performance
  117. self.submit_jobs(TEST_USER1, 500)
  118. qdel_perf2 = self.compute_qdel_time()
  119. self.assertTrue((qdel_perf2 != -1), "qdel command failed")
  120. self.logger.info("qdel performance: " + str(qdel_perf))
  121. self.logger.info(
  122. "qdel performance after setting manager: " + str(qdel_perf2))
  123. @timeout(600)
  124. def test_qsub_perf(self):
  125. """
  126. Test that qsub performance have improved when run
  127. with -f option
  128. """
  129. # Restart server
  130. self.server.restart()
  131. # Submit a job for 500 times and timeit
  132. cmd = os.path.join(
  133. self.server.client_conf['PBS_EXEC'],
  134. 'bin',
  135. 'qsub -- /bin/true >/dev/null')
  136. start_time = timeit.default_timer()
  137. for x in range(1, 500):
  138. rv = self.du.run_cmd(self.server.hostname, cmd)
  139. self.assertTrue(rv['rc'] == 0)
  140. elap_time1 = timeit.default_timer() - float(start_time)
  141. # submit a job with -f for 500 times and timeit
  142. cmd = os.path.join(
  143. self.server.client_conf['PBS_EXEC'],
  144. 'bin',
  145. 'qsub -f -- /bin/true >/dev/null >/dev/null')
  146. start_time = timeit.default_timer()
  147. for x in range(1, 500):
  148. rv = self.du.run_cmd(self.server.hostname,
  149. cmd)
  150. self.assertTrue(rv['rc'] == 0)
  151. elap_time2 = timeit.default_timer() - float(start_time)
  152. self.logger.info("Time taken by qsub -f is " + str(elap_time2) +
  153. " and time taken by qsub is " + str(elap_time1))