system_test.module 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <?php
  2. /**
  3. * Implements hook_menu().
  4. */
  5. function system_test_menu() {
  6. $items['system-test/sleep/%'] = array(
  7. 'page callback' => 'system_test_sleep',
  8. 'page arguments' => array(2),
  9. 'access callback' => TRUE,
  10. 'type' => MENU_CALLBACK,
  11. );
  12. $items['system-test/auth'] = array(
  13. 'page callback' => 'system_test_basic_auth_page',
  14. 'access callback' => TRUE,
  15. 'type' => MENU_CALLBACK,
  16. );
  17. $items['system-test/authorize-init/%'] = array(
  18. 'page callback' => 'system_test_authorize_init_page',
  19. 'page arguments' => array(2),
  20. 'access arguments' => array('administer software updates'),
  21. 'type' => MENU_CALLBACK,
  22. );
  23. $items['system-test/redirect/%'] = array(
  24. 'title' => 'Redirect',
  25. 'page callback' => 'system_test_redirect',
  26. 'page arguments' => array(2),
  27. 'access arguments' => array('access content'),
  28. 'type' => MENU_CALLBACK,
  29. );
  30. $items['system-test/multiple-redirects/%'] = array(
  31. 'title' => 'Redirect',
  32. 'page callback' => 'system_test_multiple_redirects',
  33. 'page arguments' => array(2),
  34. 'access arguments' => array('access content'),
  35. 'type' => MENU_CALLBACK,
  36. );
  37. $items['system-test/set-header'] = array(
  38. 'page callback' => 'system_test_set_header',
  39. 'access arguments' => array('access content'),
  40. 'type' => MENU_CALLBACK,
  41. );
  42. $items['system-test/redirect-noscheme'] = array(
  43. 'page callback' => 'system_test_redirect_noscheme',
  44. 'access arguments' => array('access content'),
  45. 'type' => MENU_CALLBACK,
  46. );
  47. $items['system-test/redirect-noparse'] = array(
  48. 'page callback' => 'system_test_redirect_noparse',
  49. 'access arguments' => array('access content'),
  50. 'type' => MENU_CALLBACK,
  51. );
  52. $items['system-test/redirect-invalid-scheme'] = array(
  53. 'page callback' => 'system_test_redirect_invalid_scheme',
  54. 'access arguments' => array('access content'),
  55. 'type' => MENU_CALLBACK,
  56. );
  57. $items['system-test/variable-get'] = array(
  58. 'title' => 'Variable Get',
  59. 'page callback' => 'variable_get',
  60. 'page arguments' => array('simpletest_bootstrap_variable_test', NULL),
  61. 'access arguments' => array('access content'),
  62. 'type' => MENU_CALLBACK,
  63. );
  64. $items['system-test/lock-acquire'] = array(
  65. 'title' => 'Lock acquire',
  66. 'page callback' => 'system_test_lock_acquire',
  67. 'access callback' => TRUE,
  68. 'type' => MENU_CALLBACK,
  69. );
  70. $items['system-test/lock-exit'] = array(
  71. 'title' => 'Lock acquire then exit',
  72. 'page callback' => 'system_test_lock_exit',
  73. 'access callback' => TRUE,
  74. 'type' => MENU_CALLBACK,
  75. );
  76. $items['system-test/main-content-handling'] = array(
  77. 'title' => 'Test main content handling',
  78. 'page callback' => 'system_test_main_content_fallback',
  79. 'access callback' => TRUE,
  80. 'type' => MENU_CALLBACK,
  81. );
  82. $items['system-test/main-content-fallback'] = array(
  83. 'title' => 'Test main content fallback',
  84. 'page callback' => 'system_test_main_content_fallback',
  85. 'access callback' => TRUE,
  86. 'type' => MENU_CALLBACK,
  87. );
  88. $items['system-test/main-content-duplication'] = array(
  89. 'title' => 'Test main content duplication',
  90. 'page callback' => 'system_test_main_content_fallback',
  91. 'access callback' => TRUE,
  92. 'type' => MENU_CALLBACK,
  93. );
  94. $items['system-test/shutdown-functions'] = array(
  95. 'title' => 'Test main content duplication',
  96. 'page callback' => 'system_test_page_shutdown_functions',
  97. 'access callback' => TRUE,
  98. 'type' => MENU_CALLBACK,
  99. );
  100. return $items;
  101. }
  102. function system_test_sleep($seconds) {
  103. sleep($seconds);
  104. }
  105. function system_test_basic_auth_page() {
  106. // The Authorization HTTP header is forwarded via Drupal's .htaccess file even
  107. // for PHP CGI SAPIs.
  108. if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
  109. $authorization_header = $_SERVER['HTTP_AUTHORIZATION'];
  110. }
  111. // If using CGI on Apache with mod_rewrite, the forwarded HTTP header appears
  112. // in the redirected HTTP headers. See
  113. // https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/ServerBag.php#L61
  114. elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
  115. $authorization_header = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
  116. }
  117. // Resemble PHP_AUTH_USER and PHP_AUTH_PW for a Basic authentication from
  118. // the HTTP_AUTHORIZATION header. See
  119. // http://www.php.net/manual/features.http-auth.php
  120. list($user, $pw) = explode(':', base64_decode(substr($authorization_header, 6)));
  121. $output = t('Username is @username.', array('@username' => $user));
  122. $output .= t('Password is @password.', array('@password' => $pw));
  123. return $output;
  124. }
  125. function system_test_redirect($code) {
  126. $code = (int) $code;
  127. if ($code != 200) {
  128. // Header names are case-insensitive.
  129. header("locaTION: " . url('system-test/redirect/200', array('absolute' => TRUE)), TRUE, $code);
  130. exit;
  131. }
  132. return '';
  133. }
  134. /**
  135. * Menu callback; sends a redirect header to itself until $count argument is 0.
  136. *
  137. * Emulates the variable number of redirects (given by initial $count argument)
  138. * to the final destination URL by continuous sending of 301 HTTP redirect
  139. * headers to itself together with decrementing the $count parameter until the
  140. * $count parameter reaches 0. After that it returns an empty string to render
  141. * the final destination page.
  142. *
  143. * @param $count
  144. * The count of redirects left until the final destination page.
  145. *
  146. * @returns
  147. * The location redirect if the $count > 0, otherwise an empty string.
  148. */
  149. function system_test_multiple_redirects($count) {
  150. $count = (int) $count;
  151. if ($count > 0) {
  152. header("location: " . url('system-test/multiple-redirects/' . --$count, array('absolute' => TRUE)), TRUE, 301);
  153. exit;
  154. }
  155. return '';
  156. }
  157. function system_test_set_header() {
  158. drupal_add_http_header($_GET['name'], $_GET['value']);
  159. return t('The following header was set: %name: %value', array('%name' => $_GET['name'], '%value' => $_GET['value']));
  160. }
  161. function system_test_redirect_noscheme() {
  162. header("Location: localhost/path", TRUE, 301);
  163. exit;
  164. }
  165. function system_test_redirect_noparse() {
  166. header("Location: http:///path", TRUE, 301);
  167. exit;
  168. }
  169. function system_test_redirect_invalid_scheme() {
  170. header("Location: ftp://localhost/path", TRUE, 301);
  171. exit;
  172. }
  173. /**
  174. * Implements hook_modules_installed().
  175. */
  176. function system_test_modules_installed($modules) {
  177. if (variable_get('test_verbose_module_hooks')) {
  178. foreach ($modules as $module) {
  179. drupal_set_message(t('hook_modules_installed fired for @module', array('@module' => $module)));
  180. }
  181. }
  182. }
  183. /**
  184. * Implements hook_modules_enabled().
  185. */
  186. function system_test_modules_enabled($modules) {
  187. if (variable_get('test_verbose_module_hooks')) {
  188. foreach ($modules as $module) {
  189. drupal_set_message(t('hook_modules_enabled fired for @module', array('@module' => $module)));
  190. }
  191. }
  192. }
  193. /**
  194. * Implements hook_modules_disabled().
  195. */
  196. function system_test_modules_disabled($modules) {
  197. if (variable_get('test_verbose_module_hooks')) {
  198. foreach ($modules as $module) {
  199. drupal_set_message(t('hook_modules_disabled fired for @module', array('@module' => $module)));
  200. }
  201. }
  202. }
  203. /**
  204. * Implements hook_modules_uninstalled().
  205. */
  206. function system_test_modules_uninstalled($modules) {
  207. if (variable_get('test_verbose_module_hooks')) {
  208. foreach ($modules as $module) {
  209. drupal_set_message(t('hook_modules_uninstalled fired for @module', array('@module' => $module)));
  210. }
  211. }
  212. }
  213. /**
  214. * Implements hook_boot().
  215. */
  216. function system_test_boot() {
  217. watchdog('system_test', 'hook_boot');
  218. }
  219. /**
  220. * Implements hook_init().
  221. */
  222. function system_test_init() {
  223. // Used by FrontPageTestCase to get the results of drupal_is_front_page().
  224. if (variable_get('front_page_output', 0) && drupal_is_front_page()) {
  225. drupal_set_message(t('On front page.'));
  226. }
  227. }
  228. /**
  229. * Implements hook_exit().
  230. */
  231. function system_test_exit() {
  232. watchdog('system_test', 'hook_exit');
  233. }
  234. /**
  235. * Implements hook_system_info_alter().
  236. */
  237. function system_test_system_info_alter(&$info, $file, $type) {
  238. // We need a static otherwise the last test will fail to alter common_test.
  239. static $test;
  240. if (($dependencies = variable_get('dependencies', array())) || $test) {
  241. if ($file->name == 'module_test') {
  242. $info['hidden'] = FALSE;
  243. $info['dependencies'][] = array_shift($dependencies);
  244. variable_set('dependencies', $dependencies);
  245. $test = TRUE;
  246. }
  247. if ($file->name == 'common_test') {
  248. $info['hidden'] = FALSE;
  249. $info['version'] = '7.x-2.4-beta3';
  250. }
  251. }
  252. // Make the system_dependencies_test visible by default.
  253. if ($file->name == 'system_dependencies_test') {
  254. $info['hidden'] = FALSE;
  255. }
  256. if (in_array($file->name, array(
  257. 'system_incompatible_module_version_dependencies_test',
  258. 'system_incompatible_core_version_dependencies_test',
  259. 'system_incompatible_module_version_test',
  260. 'system_incompatible_core_version_test',
  261. ))) {
  262. $info['hidden'] = FALSE;
  263. }
  264. if ($file->name == 'requirements1_test' || $file->name == 'requirements2_test') {
  265. $info['hidden'] = FALSE;
  266. }
  267. }
  268. /**
  269. * Try to acquire a named lock and report the outcome.
  270. */
  271. function system_test_lock_acquire() {
  272. if (lock_acquire('system_test_lock_acquire')) {
  273. lock_release('system_test_lock_acquire');
  274. return 'TRUE: Lock successfully acquired in system_test_lock_acquire()';
  275. }
  276. else {
  277. return 'FALSE: Lock not acquired in system_test_lock_acquire()';
  278. }
  279. }
  280. /**
  281. * Try to acquire a specific lock, and then exit.
  282. */
  283. function system_test_lock_exit() {
  284. if (lock_acquire('system_test_lock_exit', 900)) {
  285. echo 'TRUE: Lock successfully acquired in system_test_lock_exit()';
  286. // The shut-down function should release the lock.
  287. exit();
  288. }
  289. else {
  290. return 'FALSE: Lock not acquired in system_test_lock_exit()';
  291. }
  292. }
  293. /**
  294. * Implements hook_page_build().
  295. */
  296. function system_test_page_build(&$page) {
  297. $menu_item = menu_get_item();
  298. $main_content_display = &drupal_static('system_main_content_added', FALSE);
  299. if ($menu_item['path'] == 'system-test/main-content-handling') {
  300. $page['footer'] = drupal_set_page_content();
  301. $page['footer']['main']['#markup'] = '<div id="system-test-content">' . $page['footer']['main']['#markup'] . '</div>';
  302. }
  303. elseif ($menu_item['path'] == 'system-test/main-content-fallback') {
  304. drupal_set_page_content();
  305. $main_content_display = FALSE;
  306. }
  307. elseif ($menu_item['path'] == 'system-test/main-content-duplication') {
  308. drupal_set_page_content();
  309. }
  310. }
  311. /**
  312. * Menu callback to test main content fallback().
  313. */
  314. function system_test_main_content_fallback() {
  315. return t('Content to test main content fallback');
  316. }
  317. /**
  318. * A simple page callback which adds a register shutdown function.
  319. */
  320. function system_test_page_shutdown_functions($arg1, $arg2) {
  321. drupal_register_shutdown_function('_system_test_first_shutdown_function', $arg1, $arg2);
  322. }
  323. /**
  324. * Dummy shutdown function which registers another shutdown function.
  325. */
  326. function _system_test_first_shutdown_function($arg1, $arg2) {
  327. // Output something, page has already been printed and the session stored
  328. // so we can't use drupal_set_message.
  329. print t('First shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2));
  330. drupal_register_shutdown_function('_system_test_second_shutdown_function', $arg1, $arg2);
  331. }
  332. /**
  333. * Dummy shutdown function.
  334. */
  335. function _system_test_second_shutdown_function($arg1, $arg2) {
  336. // Output something, page has already been printed and the session stored
  337. // so we can't use drupal_set_message.
  338. print t('Second shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2));
  339. // Throw an exception with an HTML tag. Since this is called in a shutdown
  340. // function, it will not bubble up to the default exception handler but will
  341. // be caught in _drupal_shutdown_function() and be displayed through
  342. // _drupal_render_exception_safe().
  343. throw new Exception('Drupal is <blink>awesome</blink>.');
  344. }
  345. /**
  346. * Implements hook_filetransfer_info().
  347. */
  348. function system_test_filetransfer_info() {
  349. return array(
  350. 'system_test' => array(
  351. 'title' => t('System Test FileTransfer'),
  352. 'file' => 'system_test.module', // Should be a .inc, but for test, ok.
  353. 'class' => 'SystemTestFileTransfer',
  354. 'weight' => -10,
  355. ),
  356. );
  357. }
  358. /**
  359. * Mock FileTransfer object to test the settings form functionality.
  360. */
  361. class SystemTestFileTransfer {
  362. public static function factory() {
  363. return new SystemTestFileTransfer;
  364. }
  365. public function getSettingsForm() {
  366. $form = array();
  367. $form['system_test_username'] = array(
  368. '#type' => 'textfield',
  369. '#title' => t('System Test Username'),
  370. );
  371. return $form;
  372. }
  373. }
  374. /**
  375. * Page callback to initialize authorize.php during testing.
  376. *
  377. * @see system_authorized_init().
  378. */
  379. function system_test_authorize_init_page($page_title) {
  380. $authorize_url = $GLOBALS['base_url'] . '/authorize.php';
  381. system_authorized_init('system_test_authorize_run', drupal_get_path('module', 'system_test') . '/system_test.module', array(), $page_title);
  382. drupal_goto($authorize_url);
  383. }