PageRenderTime 38ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/magento2-base/dev/tests/integration/framework/Magento/TestFramework/Helper/Memory.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 160 lines | 72 code | 10 blank | 78 comment | 8 complexity | 3fcc4f796af42847f92a8a5533228243 MD5 | raw file
  1. <?php
  2. /**
  3. * Helper for determining system memory usage
  4. *
  5. * Uses OS tools to provide accurate information about factual memory consumption.
  6. * The PHP standard functions may return incorrect information because the process itself may have leaks.
  7. *
  8. * Copyright © 2016 Magento. All rights reserved.
  9. * See COPYING.txt for license details.
  10. */
  11. namespace Magento\TestFramework\Helper;
  12. class Memory
  13. {
  14. /**
  15. * Prefixes to specify unit of measure for memory amount
  16. *
  17. * Warning: it is important to maintain the exact order of letters in this literal,
  18. * as it is used to convert string with units to bytes
  19. */
  20. const MEMORY_UNITS = 'BKMGTPE';
  21. /**
  22. * @var \Magento\Framework\Shell
  23. */
  24. private $_shell;
  25. /**
  26. * Inject dependencies
  27. *
  28. * @param \Magento\Framework\Shell $shell
  29. */
  30. public function __construct(\Magento\Framework\Shell $shell)
  31. {
  32. $this->_shell = $shell;
  33. }
  34. /**
  35. * Retrieve the effective memory usage of the current process
  36. *
  37. * memory_get_usage() cannot be used because of the bug
  38. * @link https://bugs.php.net/bug.php?id=62467
  39. *
  40. * @return int Memory usage in bytes
  41. */
  42. public function getRealMemoryUsage()
  43. {
  44. $pid = getmypid();
  45. try {
  46. // try to use the Windows command line
  47. // some ports of Unix commands on Windows, such as MinGW, have limited capabilities and cannot be used
  48. $result = $this->_getWinProcessMemoryUsage($pid);
  49. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  50. // fall back to the Unix command line
  51. $result = $this->_getUnixProcessMemoryUsage($pid);
  52. }
  53. return $result;
  54. }
  55. /**
  56. * Retrieve the current process' memory usage using Unix command line interface
  57. *
  58. * @link http://linux.die.net/man/1/ps
  59. * @param int $pid
  60. * @return int Memory usage in bytes
  61. */
  62. protected function _getUnixProcessMemoryUsage($pid)
  63. {
  64. // RSS - resident set size, the non-swapped physical memory
  65. $command = 'ps --pid %s --format rss --no-headers';
  66. if ($this->isMacOS()) {
  67. $command = 'ps -p %s -o rss=';
  68. }
  69. $output = $this->_shell->execute($command, [$pid]);
  70. $result = $output . 'k';
  71. // kilobytes
  72. return self::convertToBytes($result);
  73. }
  74. /**
  75. * Retrieve the current process' memory usage using Windows command line interface
  76. *
  77. * @link http://technet.microsoft.com/en-us/library/bb491010.aspx
  78. * @param int $pid
  79. * @return int Memory usage in bytes
  80. */
  81. protected function _getWinProcessMemoryUsage($pid)
  82. {
  83. $output = $this->_shell->execute('tasklist.exe /fi %s /fo CSV /nh', ["PID eq {$pid}"]);
  84. $arr = str_getcsv($output);
  85. $memory = $arr[4];
  86. return self::convertToBytes($memory);
  87. }
  88. /**
  89. * Convert a number optionally followed by the unit symbol (B, K, M, G, etc.) to bytes
  90. *
  91. * @param string $number String representation of a number
  92. * @return int
  93. * @throws \InvalidArgumentException
  94. * @throws \OutOfBoundsException
  95. */
  96. public static function convertToBytes($number)
  97. {
  98. if (!preg_match('/^(.*\d)\h*(\D)$/', $number, $matches)) {
  99. throw new \InvalidArgumentException("Number format '{$number}' is not recognized.");
  100. }
  101. $unitSymbol = strtoupper($matches[2]);
  102. if (false === strpos(self::MEMORY_UNITS, $unitSymbol)) {
  103. throw new \InvalidArgumentException("The number '{$number}' has an unrecognized unit: '{$unitSymbol}'.");
  104. }
  105. $result = self::_convertToNumber($matches[1]);
  106. $pow = $unitSymbol ? strpos(self::MEMORY_UNITS, $unitSymbol) : 0;
  107. $is32Bit = PHP_INT_SIZE == 4;
  108. if ($is32Bit && $pow >= 4) {
  109. throw new \OutOfBoundsException("A 32-bit system is unable to process such a number.");
  110. }
  111. if ($unitSymbol) {
  112. $result *= pow(1024, $pow);
  113. }
  114. return (int)$result;
  115. }
  116. /**
  117. * Remove non-numeric characters in the string to cast it to a numeric value
  118. *
  119. * Incoming number can be presented in arbitrary format that depends on locale. We don't possess locale information.
  120. * So the best can be done is to treat number as an integer and eliminate delimiters.
  121. * Method will not behave correctly with non-integer numbers for the following reason:
  122. * - if value has more than one delimiter, such as in French notation: "1 234,56" -- then we can infer decimal part
  123. * - but the value has only one delimiter, such as "234,56", then it is impossible to know whether it is decimal
  124. * separator or not. Only knowing the right format would allow this.
  125. *
  126. * @param $number
  127. * @return string
  128. * @throws \InvalidArgumentException
  129. */
  130. protected static function _convertToNumber($number)
  131. {
  132. preg_match_all('/(\D+)/', $number, $matches);
  133. if (count(array_unique($matches[0])) > 1) {
  134. throw new \InvalidArgumentException(
  135. "The number '{$number}' seems to have decimal part. Only integer numbers are supported."
  136. );
  137. }
  138. return preg_replace('/\D+/', '', $number);
  139. }
  140. /**
  141. * Whether the operating system belongs to the Mac family
  142. *
  143. * @link http://php.net/manual/en/function.php-uname.php
  144. * @return boolean
  145. */
  146. public static function isMacOs()
  147. {
  148. return strtoupper(PHP_OS) === 'DARWIN';
  149. }
  150. }