PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/phoronix-test-suite/pts-core/objects/client/pts_module.php

#
PHP | 325 lines | 252 code | 43 blank | 30 comment | 68 complexity | 8141b05c2a2e3da4134ca636a225b983 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /*
  3. Phoronix Test Suite
  4. URLs: http://www.phoronix.com, http://www.phoronix-test-suite.com/
  5. Copyright (C) 2008 - 2011, Phoronix Media
  6. Copyright (C) 2008 - 2011, Michael Larabel
  7. pts_module_interface.php: The generic Phoronix Test Suite module object that is extended by the specific modules/plug-ins
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 3 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. class pts_module
  20. {
  21. const MODULE_UNLOAD = "MODULE_UNLOAD";
  22. const QUIT_PTS_CLIENT = "QUIT_PTS_CLIENT";
  23. public static function save_dir()
  24. {
  25. $prefix_dir = PTS_MODULE_DATA_PATH;
  26. pts_file_io::mkdir($prefix_dir);
  27. return $prefix_dir . str_replace('_', '-', self::module_name()) . '/';
  28. }
  29. public static function is_module($name)
  30. {
  31. return is_file(PTS_MODULE_LOCAL_PATH . $name . ".php") || is_file(PTS_MODULE_PATH . $name . ".php");
  32. }
  33. public static function module_config_save($module_name, $set_options = null)
  34. {
  35. // Validate the config files, update them (or write them) if needed, and other configuration file tasks
  36. pts_file_io::mkdir(PTS_MODULE_DATA_PATH . $module_name);
  37. $settings_to_write = array();
  38. if(is_file(PTS_MODULE_DATA_PATH . $module_name . "/module-settings.xml"))
  39. {
  40. $module_config_parser = new nye_XmlReader(PTS_MODULE_DATA_PATH . $module_name . "/module-settings.xml");
  41. $option_identifier = $module_config_parser->getXMLArrayValues('PhoronixTestSuite/ModuleSettings/Option/Identifier');
  42. $option_value = $module_config_parser->getXMLArrayValues('PhoronixTestSuite/ModuleSettings/Option/Value');
  43. for($i = 0; $i < count($option_identifier); $i++)
  44. {
  45. $settings_to_write[$option_identifier[$i]] = $option_value[$i];
  46. }
  47. }
  48. foreach($set_options as $identifier => $value)
  49. {
  50. $settings_to_write[$identifier] = $value;
  51. }
  52. $config = new nye_XmlWriter();
  53. foreach($settings_to_write as $identifier => $value)
  54. {
  55. $config->addXmlNode('PhoronixTestSuite/ModuleSettings/Option/Identifier', $identifier);
  56. $config->addXmlNode('PhoronixTestSuite/ModuleSettings/Option/Value', $value);
  57. }
  58. $config->saveXMLFile(PTS_MODULE_DATA_PATH . $module_name . "/module-settings.xml");
  59. }
  60. public static function is_module_setup()
  61. {
  62. $module_name = self::module_name();
  63. $is_setup = true;
  64. $module_setup_options = pts_module_manager::module_call($module_name, "module_setup");
  65. foreach($module_setup_options as $option)
  66. {
  67. if($option instanceOf pts_module_option)
  68. {
  69. if(pts_module::read_option($option->get_identifier()) == false && $option->setup_check_needed())
  70. {
  71. $is_setup = false;
  72. break;
  73. }
  74. }
  75. }
  76. return $is_setup;
  77. }
  78. public static function read_variable($var)
  79. {
  80. // For now this is just readung from the real env
  81. return trim(getenv($var));
  82. }
  83. public static function valid_run_command($module, $command = null)
  84. {
  85. if($command == null)
  86. {
  87. if(strpos($module, '.') != false)
  88. {
  89. list($module, $command) = explode('.', $module);
  90. }
  91. else
  92. {
  93. $command = 'run';
  94. }
  95. }
  96. if(!pts_module_manager::is_module_attached($module))
  97. {
  98. pts_module_manager::attach_module($module);
  99. }
  100. $all_options = pts_module_manager::module_call($module, 'user_commands');
  101. $valid = count($all_options) > 0 && ((isset($all_options[$command]) && method_exists($module, $all_options[$command])) || in_array($command, array('help')));
  102. return $valid ? array($module, $command) : false;
  103. }
  104. public static function read_option($identifier, $default_fallback = false)
  105. {
  106. $module_name = self::module_name();
  107. $value = false;
  108. $module_config_parser = new nye_XmlReader(PTS_MODULE_DATA_PATH . $module_name . "/module-settings.xml");
  109. $option_identifier = $module_config_parser->getXMLArrayValues('PhoronixTestSuite/ModuleSettings/Option/Identifier');
  110. $option_value = $module_config_parser->getXMLArrayValues('PhoronixTestSuite/ModuleSettings/Option/Value');
  111. for($i = 0; $i < count($option_identifier) && $value == false; $i++)
  112. {
  113. if($option_identifier[$i] == $identifier)
  114. {
  115. $value = $option_value[$i];
  116. }
  117. }
  118. if($default_fallback && empty($value))
  119. {
  120. // Find the default value
  121. $module_options = call_user_func(array($module_name, "module_setup"));
  122. for($i = 0; $i < count($module_options) && $value == false; $i++)
  123. {
  124. if($module_options[$i]->get_identifier() == $identifier)
  125. {
  126. $value = $module_options[$i]->get_default_value();
  127. }
  128. }
  129. }
  130. return $value;
  131. }
  132. public static function read_all_options()
  133. {
  134. $module_name = self::module_name();
  135. $options = array();
  136. $module_config_parser = new nye_XmlReader(PTS_MODULE_DATA_PATH . $module_name . "/module-settings.xml");
  137. $option_identifier = $module_config_parser->getXMLArrayValues('PhoronixTestSuite/ModuleSettings/Option/Identifier');
  138. $option_value = $module_config_parser->getXMLArrayValues('PhoronixTestSuite/ModuleSettings/Option/Value');
  139. for($i = 0; $i < count($option_identifier); $i++)
  140. {
  141. $options[$option_identifier[$i]] = $option_value[$i];
  142. }
  143. return $options;
  144. }
  145. public static function set_option($identifier, $value)
  146. {
  147. pts_module::module_config_save(self::module_name(), array($identifier => $value));
  148. }
  149. public static function save_file($file, $contents = null, $append = false)
  150. {
  151. // Saves a file for a module
  152. $save_base_dir = self::save_dir();
  153. pts_file_io::mkdir($save_base_dir);
  154. if(($extra_dir = dirname($file)) != "." && !is_dir($save_base_dir . $extra_dir))
  155. {
  156. mkdir($save_base_dir . $extra_dir);
  157. }
  158. if($append)
  159. {
  160. if(is_file($save_base_dir . $file))
  161. {
  162. if(file_put_contents($save_base_dir . $file, $contents . "\n", FILE_APPEND) != false)
  163. {
  164. return $save_base_dir . $file;
  165. }
  166. }
  167. }
  168. else
  169. {
  170. if(file_put_contents($save_base_dir . $file, $contents) != false)
  171. {
  172. return $save_base_dir . $file;
  173. }
  174. }
  175. return false;
  176. }
  177. public static function read_file($file)
  178. {
  179. $file = self::save_dir() . $file;
  180. return is_file($file) ? file_get_contents($file) : false;
  181. }
  182. public static function is_file($file)
  183. {
  184. $file = self::save_dir() . $file;
  185. return is_file($file);
  186. }
  187. public static function remove_file($file)
  188. {
  189. $file = self::save_dir() . $file;
  190. return is_file($file) && unlink($file);
  191. }
  192. public static function copy_file($from_file, $to_file)
  193. {
  194. // Copy a file for a module
  195. $save_base_dir = self::save_dir();
  196. pts_file_io::mkdir($save_base_dir);
  197. if(($extra_dir = dirname($to_file)) != "." && !is_dir($save_base_dir . $extra_dir))
  198. {
  199. mkdir($save_base_dir . $extra_dir);
  200. }
  201. if(is_file($from_file) && (!is_file($save_base_dir . $to_file) || md5_file($from_file) != md5_file($save_base_dir . $to_file)))
  202. {
  203. if(copy($from_file, $save_base_dir . $to_file))
  204. {
  205. return $save_base_dir . $to_file;
  206. }
  207. }
  208. return false;
  209. }
  210. public static function pts_fork_function($function)
  211. {
  212. self::pts_timed_function($function, -1);
  213. }
  214. public static function pts_timed_function($function, $time)
  215. {
  216. if(($time < 0.5 && $time != -1) || $time > 300)
  217. {
  218. return;
  219. }
  220. if(function_exists("pcntl_fork"))
  221. {
  222. $pid = pcntl_fork();
  223. if($pid != -1)
  224. {
  225. if($pid)
  226. {
  227. return $pid;
  228. }
  229. else
  230. {
  231. $loop_continue = true;
  232. /*
  233. ML: I think this below check can be safely removed
  234. $start_id = pts_unique_runtime_identifier();
  235. && ($start_id == pts_unique_runtime_identifier() || $start_id == PTS_INIT_TIME)
  236. */
  237. while(pts_test_run_manager::test_run_process_active() !== -1 && is_file(PTS_USER_LOCK) && $loop_continue)
  238. {
  239. call_user_func(array(self::module_name(), $function));
  240. if($time > 0)
  241. {
  242. sleep($time);
  243. }
  244. else if($time == -1)
  245. {
  246. $loop_continue = false;
  247. }
  248. }
  249. exit(0);
  250. }
  251. }
  252. }
  253. else
  254. {
  255. pts_client::$display->generic_error("php-pcntl must be installed for the " . self::module_name() . " module.");
  256. }
  257. }
  258. private static function module_name()
  259. {
  260. $module_name = "unknown";
  261. if(($current = pts_module_manager::get_current_module()) != null)
  262. {
  263. $module_name = $current;
  264. }
  265. else
  266. {
  267. $bt = debug_backtrace();
  268. for($i = 0; $i < count($bt) && $module_name == "unknown"; $i++)
  269. {
  270. if($bt[$i]["class"] != "pts_module")
  271. {
  272. $module_name = $bt[$i]["class"];
  273. }
  274. }
  275. }
  276. return $module_name;
  277. }
  278. }
  279. ?>