upgrade.test 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. <?php
  2. /**
  3. * Perform end-to-end tests of the upgrade path.
  4. */
  5. abstract class UpgradePathTestCase extends DrupalWebTestCase {
  6. /**
  7. * The file path(s) to the dumped database(s) to load into the child site.
  8. *
  9. * @var array
  10. */
  11. var $databaseDumpFiles = array();
  12. /**
  13. * Flag that indicates whether the child site has been upgraded.
  14. */
  15. var $upgradedSite = FALSE;
  16. /**
  17. * Array of errors triggered during the upgrade process.
  18. */
  19. var $upgradeErrors = array();
  20. /**
  21. * Array of modules loaded when the test starts.
  22. */
  23. var $loadedModules = array();
  24. /**
  25. * Flag to indicate whether zlib is installed or not.
  26. */
  27. var $zlibInstalled = TRUE;
  28. /**
  29. * Flag to indicate whether there are pending updates or not.
  30. */
  31. var $pendingUpdates = TRUE;
  32. /**
  33. * Constructs an UpgradePathTestCase object.
  34. *
  35. * @param $test_id
  36. * (optional) The ID of the test. Tests with the same id are reported
  37. * together.
  38. */
  39. function __construct($test_id = NULL) {
  40. parent::__construct($test_id);
  41. $this->zlibInstalled = function_exists('gzopen');
  42. }
  43. /**
  44. * Prepares the appropriate session for the release of Drupal being upgraded.
  45. */
  46. protected function prepareD7Session() {
  47. // Generate and set a D6-compatible session cookie.
  48. $this->curlInitialize();
  49. $sid = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
  50. $session_name = update_get_d6_session_name();
  51. curl_setopt($this->curlHandle, CURLOPT_COOKIE, rawurlencode($session_name) . '=' . rawurlencode($sid));
  52. // Force our way into the session of the child site.
  53. drupal_save_session(TRUE);
  54. // A session cannot be written without the ssid column which is missing on
  55. // Drupal 6 sites.
  56. db_add_field('sessions', 'ssid', array('description' => "Secure session ID. The value is generated by Drupal's session handlers.", 'type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
  57. _drupal_session_write($sid, '');
  58. // Remove the temporarily added ssid column.
  59. db_drop_field('sessions', 'ssid');
  60. drupal_save_session(FALSE);
  61. }
  62. /**
  63. * Overrides DrupalWebTestCase::setUp() for upgrade testing.
  64. *
  65. * @see DrupalWebTestCase::prepareDatabasePrefix()
  66. * @see DrupalWebTestCase::changeDatabasePrefix()
  67. * @see DrupalWebTestCase::prepareEnvironment()
  68. */
  69. protected function setUp() {
  70. // We are going to set a missing zlib requirement property for usage
  71. // during the performUpgrade() and tearDown() methods. Also set that the
  72. // tests failed.
  73. if (!$this->zlibInstalled) {
  74. parent::setUp();
  75. return;
  76. }
  77. global $user, $language, $conf;
  78. // Load the Update API.
  79. require_once DRUPAL_ROOT . '/includes/update.inc';
  80. // Reset flags.
  81. $this->upgradedSite = FALSE;
  82. $this->upgradeErrors = array();
  83. $this->loadedModules = module_list();
  84. // Create the database prefix for this test.
  85. $this->prepareDatabasePrefix();
  86. // Prepare the environment for running tests.
  87. $this->prepareEnvironment();
  88. if (!$this->setupEnvironment) {
  89. return FALSE;
  90. }
  91. // Reset all statics and variables to perform tests in a clean environment.
  92. $conf = array();
  93. drupal_static_reset();
  94. // Change the database prefix.
  95. // All static variables need to be reset before the database prefix is
  96. // changed, since DrupalCacheArray implementations attempt to
  97. // write back to persistent caches when they are destructed.
  98. $this->changeDatabasePrefix();
  99. if (!$this->setupDatabasePrefix) {
  100. return FALSE;
  101. }
  102. // Unregister the registry.
  103. // This is required to make sure that the database layer works properly.
  104. spl_autoload_unregister('drupal_autoload_class');
  105. spl_autoload_unregister('drupal_autoload_interface');
  106. // Load the database from the portable PHP dump.
  107. // The files may be gzipped.
  108. foreach ($this->databaseDumpFiles as $file) {
  109. if (substr($file, -3) == '.gz') {
  110. $file = "compress.zlib://$file";
  111. }
  112. require $file;
  113. }
  114. // Set path variables.
  115. $this->variable_set('file_public_path', $this->public_files_directory);
  116. $this->variable_set('file_private_path', $this->private_files_directory);
  117. $this->variable_set('file_temporary_path', $this->temp_files_directory);
  118. $this->pass('Finished loading the dump.');
  119. // Ensure that the session is not written to the new environment and replace
  120. // the global $user session with uid 1 from the new test site.
  121. drupal_save_session(FALSE);
  122. // Login as uid 1.
  123. $user = db_query('SELECT * FROM {users} WHERE uid = :uid', array(':uid' => 1))->fetchObject();
  124. // Generate and set a D6-compatible session cookie.
  125. $this->prepareD7Session();
  126. // Restore necessary variables.
  127. $this->variable_set('clean_url', $this->originalCleanUrl);
  128. $this->variable_set('site_mail', 'simpletest@example.com');
  129. drupal_set_time_limit($this->timeLimit);
  130. $this->setup = TRUE;
  131. }
  132. /**
  133. * Specialized variable_set() that works even if the child site is not upgraded.
  134. *
  135. * @param $name
  136. * The name of the variable to set.
  137. * @param $value
  138. * The value to set. This can be any PHP data type; these functions take care
  139. * of serialization as necessary.
  140. */
  141. protected function variable_set($name, $value) {
  142. db_delete('variable')
  143. ->condition('name', $name)
  144. ->execute();
  145. db_insert('variable')
  146. ->fields(array(
  147. 'name' => $name,
  148. 'value' => serialize($value),
  149. ))
  150. ->execute();
  151. try {
  152. cache_clear_all('variables', 'cache');
  153. cache_clear_all('variables', 'cache_bootstrap');
  154. }
  155. // Since cache_bootstrap won't exist in a Drupal 6 site, ignore the
  156. // exception if the above fails.
  157. catch (Exception $e) {}
  158. }
  159. /**
  160. * Specialized refreshVariables().
  161. */
  162. protected function refreshVariables() {
  163. // No operation if the child has not been upgraded yet.
  164. if (!$this->upgradedSite) {
  165. return parent::refreshVariables();
  166. }
  167. }
  168. /**
  169. * Perform the upgrade.
  170. *
  171. * @param $register_errors
  172. * Register the errors during the upgrade process as failures.
  173. * @return
  174. * TRUE if the upgrade succeeded, FALSE otherwise.
  175. */
  176. protected function performUpgrade($register_errors = TRUE) {
  177. if (!$this->zlibInstalled) {
  178. $this->fail(t('Missing zlib requirement for upgrade tests.'));
  179. return FALSE;
  180. }
  181. $update_url = $GLOBALS['base_url'] . '/update.php';
  182. // Load the first update screen.
  183. $this->drupalGet($update_url, array('external' => TRUE));
  184. if (!$this->assertResponse(200)) {
  185. return FALSE;
  186. }
  187. // Continue.
  188. $this->drupalPost(NULL, array(), t('Continue'));
  189. if (!$this->assertResponse(200)) {
  190. return FALSE;
  191. }
  192. // The test should pass if there are no pending updates.
  193. $content = $this->drupalGetContent();
  194. if (strpos($content, t('No pending updates.')) !== FALSE) {
  195. $this->pass(t('No pending updates and therefore no upgrade process to test.'));
  196. $this->pendingUpdates = FALSE;
  197. return TRUE;
  198. }
  199. // Go!
  200. $this->drupalPost(NULL, array(), t('Apply pending updates'));
  201. if (!$this->assertResponse(200)) {
  202. return FALSE;
  203. }
  204. // Check for errors during the update process.
  205. foreach ($this->xpath('//li[@class=:class]', array(':class' => 'failure')) as $element) {
  206. $message = strip_tags($element->asXML());
  207. $this->upgradeErrors[] = $message;
  208. if ($register_errors) {
  209. $this->fail($message);
  210. }
  211. }
  212. if (!empty($this->upgradeErrors)) {
  213. // Upgrade failed, the installation might be in an inconsistent state,
  214. // don't process.
  215. return FALSE;
  216. }
  217. // Check if there still are pending updates.
  218. $this->drupalGet($update_url, array('external' => TRUE));
  219. $this->drupalPost(NULL, array(), t('Continue'));
  220. if (!$this->assertText(t('No pending updates.'), t('No pending updates at the end of the update process.'))) {
  221. return FALSE;
  222. }
  223. // Upgrade succeed, rebuild the environment so that we can call the API
  224. // of the child site directly from this request.
  225. $this->upgradedSite = TRUE;
  226. // Reload module list. For modules that are enabled in the test database,
  227. // but not on the test client, we need to load the code here.
  228. $new_modules = array_diff(module_list(TRUE), $this->loadedModules);
  229. foreach ($new_modules as $module) {
  230. drupal_load('module', $module);
  231. }
  232. // Reload hook implementations
  233. module_implements('', FALSE, TRUE);
  234. // Rebuild caches.
  235. drupal_static_reset();
  236. drupal_flush_all_caches();
  237. // Reload global $conf array and permissions.
  238. $this->refreshVariables();
  239. $this->checkPermissions(array(), TRUE);
  240. return TRUE;
  241. }
  242. /**
  243. * Force uninstall all modules from a test database, except those listed.
  244. *
  245. * @param $modules
  246. * The list of modules to keep installed. Required core modules will
  247. * always be kept.
  248. */
  249. protected function uninstallModulesExcept(array $modules) {
  250. $required_modules = array('block', 'dblog', 'filter', 'node', 'system', 'update', 'user');
  251. $modules = array_merge($required_modules, $modules);
  252. db_delete('system')
  253. ->condition('type', 'module')
  254. ->condition('name', $modules, 'NOT IN')
  255. ->execute();
  256. }
  257. }
  258. /**
  259. * Performs end-to-end point test of the release update path.
  260. */
  261. abstract class UpdatePathTestCase extends UpgradePathTestCase {
  262. /**
  263. * Overrides UpgradePathTestCase::prepareD7Session().
  264. */
  265. protected function prepareD7Session() {
  266. // Generate and set a D7-compatible session cookie.
  267. $this->curlInitialize();
  268. $sid = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
  269. curl_setopt($this->curlHandle, CURLOPT_COOKIE, rawurlencode(session_name()) . '=' . rawurlencode($sid));
  270. // Force our way into the session of the child site.
  271. drupal_save_session(TRUE);
  272. _drupal_session_write($sid, '');
  273. drupal_save_session(FALSE);
  274. }
  275. }
  276. /**
  277. * Perform basic upgrade tests.
  278. *
  279. * Load a bare installation of Drupal 6 and run the upgrade process on it.
  280. *
  281. * The install only contains dblog (although it's optional, it's only so that
  282. * another hook_watchdog module can take its place, the site is not functional
  283. * without watchdog) and update.
  284. */
  285. class BasicUpgradePath extends UpgradePathTestCase {
  286. public static function getInfo() {
  287. return array(
  288. 'name' => 'Basic upgrade path',
  289. 'description' => 'Basic upgrade path tests.',
  290. 'group' => 'Upgrade path',
  291. );
  292. }
  293. public function setUp() {
  294. // Path to the database dump files.
  295. $this->databaseDumpFiles = array(
  296. drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.bare.database.php',
  297. );
  298. parent::setUp();
  299. }
  300. /**
  301. * Test a failed upgrade, and verify that the failure is reported.
  302. */
  303. public function testFailedUpgrade() {
  304. // Destroy a table that the upgrade process needs.
  305. db_drop_table('access');
  306. // Assert that the upgrade fails.
  307. $this->assertFalse($this->performUpgrade(FALSE) && $this->pendingUpdates, t('A failed upgrade should return messages.'));
  308. }
  309. /**
  310. * Test a successful upgrade.
  311. */
  312. public function testBasicUpgrade() {
  313. $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
  314. // Hit the frontpage.
  315. $this->drupalGet('');
  316. $this->assertResponse(200);
  317. // Verify that we are still logged in.
  318. $this->drupalGet('user');
  319. $this->clickLink(t('Edit'));
  320. $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.'));
  321. // Logout and verify that we can login back in with our initial password.
  322. $this->drupalLogout();
  323. $this->drupalLogin((object) array(
  324. 'uid' => 1,
  325. 'name' => 'admin',
  326. 'pass_raw' => 'admin',
  327. ));
  328. // The previous login should've triggered a password rehash, so login one
  329. // more time to make sure the new hash is readable.
  330. $this->drupalLogout();
  331. $this->drupalLogin((object) array(
  332. 'uid' => 1,
  333. 'name' => 'admin',
  334. 'pass_raw' => 'admin',
  335. ));
  336. // Test that the site name is correctly displayed.
  337. $this->assertText('Drupal 6', t('The site name is correctly displayed.'));
  338. // Verify that the main admin sections are available.
  339. $this->drupalGet('admin');
  340. $this->assertText(t('Content'));
  341. $this->assertText(t('Appearance'));
  342. $this->assertText(t('People'));
  343. $this->assertText(t('Configuration'));
  344. $this->assertText(t('Reports'));
  345. $this->assertText(t('Structure'));
  346. $this->assertText(t('Modules'));
  347. // Confirm that no {menu_links} entry exists for user/autocomplete.
  348. $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
  349. $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete'));
  350. // Test that the environment after the upgrade is in a consistent status.
  351. $update_d6 = variable_get('update_d6', FALSE);
  352. $this->assertFalse($update_d6, t('The D6 upgrade flag variable has been correctly disabled.'));
  353. }
  354. }
  355. /**
  356. * Performs point release update tests on a bare database.
  357. *
  358. * Loads an installation of Drupal 7.0 and runs the update process on it.
  359. *
  360. * The install contains the standard profile (plus all optional) modules
  361. * without any content so that an update from any of the modules under this
  362. * profile installation can be wholly tested.
  363. */
  364. class BasicStandardUpdatePath extends UpdatePathTestCase {
  365. public static function getInfo() {
  366. return array(
  367. 'name' => 'Basic standard + all profile update path',
  368. 'description' => 'Basic update path tests for a standard profile install with all enabled modules.',
  369. 'group' => 'Upgrade path',
  370. );
  371. }
  372. public function setUp() {
  373. // Path to the database dump files.
  374. $this->databaseDumpFiles = array(
  375. drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz',
  376. );
  377. parent::setUp();
  378. }
  379. /**
  380. * Tests a successful point release update.
  381. */
  382. public function testBasicStandardUpdate() {
  383. $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
  384. // Hit the frontpage.
  385. $this->drupalGet('');
  386. $this->assertResponse(200);
  387. // Verify that we are still logged in.
  388. $this->drupalGet('user');
  389. $this->clickLink(t('Edit'));
  390. $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.'));
  391. // Logout and verify that we can login back in with our initial password.
  392. $this->drupalLogout();
  393. $this->drupalLogin((object) array(
  394. 'uid' => 1,
  395. 'name' => 'admin',
  396. 'pass_raw' => 'admin',
  397. ));
  398. // The previous login should've triggered a password rehash, so login one
  399. // more time to make sure the new hash is readable.
  400. $this->drupalLogout();
  401. $this->drupalLogin((object) array(
  402. 'uid' => 1,
  403. 'name' => 'admin',
  404. 'pass_raw' => 'admin',
  405. ));
  406. // Test that the site name is correctly displayed.
  407. $this->assertText('Drupal', t('The site name is correctly displayed.'));
  408. // Verify that the main admin sections are available.
  409. $this->drupalGet('admin');
  410. $this->assertText(t('Content'));
  411. $this->assertText(t('Appearance'));
  412. $this->assertText(t('People'));
  413. $this->assertText(t('Configuration'));
  414. $this->assertText(t('Reports'));
  415. $this->assertText(t('Structure'));
  416. $this->assertText(t('Modules'));
  417. // Confirm that no {menu_links} entry exists for user/autocomplete.
  418. $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
  419. $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete'));
  420. }
  421. }
  422. /**
  423. * Performs point release update tests on a bare database.
  424. *
  425. * Loads an installation of Drupal 7.0 and runs the update process on it.
  426. *
  427. * The install contains the minimal profile modules (without any generated
  428. * content) so that an update from of a site under this profile may be tested.
  429. */
  430. class BasicMinimalUpdatePath extends UpdatePathTestCase {
  431. public static function getInfo() {
  432. return array(
  433. 'name' => 'Basic minimal profile update path',
  434. 'description' => 'Basic update path tests for a minimal profile install.',
  435. 'group' => 'Upgrade path',
  436. );
  437. }
  438. public function setUp() {
  439. // Path to the database dump files.
  440. $this->databaseDumpFiles = array(
  441. drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz',
  442. );
  443. parent::setUp();
  444. }
  445. /**
  446. * Tests a successful point release update.
  447. */
  448. public function testBasicMinimalUpdate() {
  449. $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
  450. // Hit the frontpage.
  451. $this->drupalGet('');
  452. $this->assertResponse(200);
  453. // Verify that we are still logged in.
  454. $this->drupalGet('user');
  455. $this->clickLink(t('Edit'));
  456. $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.'));
  457. // Logout and verify that we can login back in with our initial password.
  458. $this->drupalLogout();
  459. $this->drupalLogin((object) array(
  460. 'uid' => 1,
  461. 'name' => 'admin',
  462. 'pass_raw' => 'admin',
  463. ));
  464. // The previous login should've triggered a password rehash, so login one
  465. // more time to make sure the new hash is readable.
  466. $this->drupalLogout();
  467. $this->drupalLogin((object) array(
  468. 'uid' => 1,
  469. 'name' => 'admin',
  470. 'pass_raw' => 'admin',
  471. ));
  472. // Test that the site name is correctly displayed.
  473. $this->assertText('Drupal', t('The site name is correctly displayed.'));
  474. // Verify that the main admin sections are available.
  475. $this->drupalGet('admin');
  476. $this->assertText(t('Content'));
  477. $this->assertText(t('Appearance'));
  478. $this->assertText(t('People'));
  479. $this->assertText(t('Configuration'));
  480. $this->assertText(t('Reports'));
  481. $this->assertText(t('Structure'));
  482. $this->assertText(t('Modules'));
  483. // Confirm that no {menu_links} entry exists for user/autocomplete.
  484. $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
  485. $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete'));
  486. }
  487. }
  488. /**
  489. * Performs point release update tests on a 'filled' database.
  490. *
  491. * Loads an installation of Drupal 7.0 and runs the update process on it.
  492. *
  493. * The install contains the standard profile (plus all optional) modules
  494. * with generated content so that an update from any of the modules under this
  495. * profile installation can be wholly tested.
  496. */
  497. class FilledStandardUpdatePath extends UpdatePathTestCase {
  498. public static function getInfo() {
  499. return array(
  500. 'name' => 'Basic standard + all profile update path, populated database',
  501. 'description' => 'Basic update path tests for a standard profile install with all enabled modules and a populated database.',
  502. 'group' => 'Upgrade path',
  503. );
  504. }
  505. public function setUp() {
  506. // Path to the database dump files.
  507. $this->databaseDumpFiles = array(
  508. drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.standard_all.database.php.gz',
  509. );
  510. parent::setUp();
  511. }
  512. /**
  513. * Tests a successful point release update.
  514. */
  515. public function testFilledStandardUpdate() {
  516. $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
  517. // Hit the frontpage.
  518. $this->drupalGet('');
  519. $this->assertResponse(200);
  520. // Verify that we are still logged in.
  521. $this->drupalGet('user');
  522. $this->clickLink(t('Edit'));
  523. $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.'));
  524. // Logout and verify that we can login back in with our initial password.
  525. $this->drupalLogout();
  526. $this->drupalLogin((object) array(
  527. 'uid' => 1,
  528. 'name' => 'admin',
  529. 'pass_raw' => 'admin',
  530. ));
  531. // The previous login should've triggered a password rehash, so login one
  532. // more time to make sure the new hash is readable.
  533. $this->drupalLogout();
  534. $this->drupalLogin((object) array(
  535. 'uid' => 1,
  536. 'name' => 'admin',
  537. 'pass_raw' => 'admin',
  538. ));
  539. // Test that the site name is correctly displayed.
  540. $this->assertText('Drupal', t('The site name is correctly displayed.'));
  541. // Verify that the main admin sections are available.
  542. $this->drupalGet('admin');
  543. $this->assertText(t('Content'));
  544. $this->assertText(t('Appearance'));
  545. $this->assertText(t('People'));
  546. $this->assertText(t('Configuration'));
  547. $this->assertText(t('Reports'));
  548. $this->assertText(t('Structure'));
  549. $this->assertText(t('Modules'));
  550. // Confirm that no {menu_links} entry exists for user/autocomplete.
  551. $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
  552. $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete'));
  553. }
  554. }
  555. /**
  556. * Performs point release update tests on a populated database.
  557. *
  558. * Loads an installation of Drupal 7.0 and runs the update process on it.
  559. *
  560. * The install contains the minimal profile modules (along with generated
  561. * content) so that an update from of a site under this profile may be tested.
  562. */
  563. class FilledMinimalUpdatePath extends UpdatePathTestCase {
  564. public static function getInfo() {
  565. return array(
  566. 'name' => 'Basic minimal profile update path, populated database',
  567. 'description' => 'Basic update path tests for a minimal profile install with a populated database.',
  568. 'group' => 'Upgrade path',
  569. );
  570. }
  571. public function setUp() {
  572. // Path to the database dump files.
  573. $this->databaseDumpFiles = array(
  574. drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.minimal.database.php.gz',
  575. );
  576. parent::setUp();
  577. }
  578. /**
  579. * Tests a successful point release update.
  580. */
  581. public function testFilledStandardUpdate() {
  582. $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.'));
  583. // Hit the frontpage.
  584. $this->drupalGet('');
  585. $this->assertResponse(200);
  586. // Verify that we are still logged in.
  587. $this->drupalGet('user');
  588. $this->clickLink(t('Edit'));
  589. $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.'));
  590. // Logout and verify that we can login back in with our initial password.
  591. $this->drupalLogout();
  592. $this->drupalLogin((object) array(
  593. 'uid' => 1,
  594. 'name' => 'admin',
  595. 'pass_raw' => 'admin',
  596. ));
  597. // The previous login should've triggered a password rehash, so login one
  598. // more time to make sure the new hash is readable.
  599. $this->drupalLogout();
  600. $this->drupalLogin((object) array(
  601. 'uid' => 1,
  602. 'name' => 'admin',
  603. 'pass_raw' => 'admin',
  604. ));
  605. // Test that the site name is correctly displayed.
  606. $this->assertText('Drupal', t('The site name is correctly displayed.'));
  607. // Verify that the main admin sections are available.
  608. $this->drupalGet('admin');
  609. $this->assertText(t('Content'));
  610. $this->assertText(t('Appearance'));
  611. $this->assertText(t('People'));
  612. $this->assertText(t('Configuration'));
  613. $this->assertText(t('Reports'));
  614. $this->assertText(t('Structure'));
  615. $this->assertText(t('Modules'));
  616. // Confirm that no {menu_links} entry exists for user/autocomplete.
  617. $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField();
  618. $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete'));
  619. }
  620. }