t('Backup and Migrate Functionality'), 'desc' => t('Executes the functionality test suite for backup and migrate.'), 'group' => t('Backup and Migrate module'), ); } var $admin_user; var $directory_backup; /** * SimpleTest core method: code run before each and every test method. */ function setUp() { parent::setUp(); // Create an administrative user with permission to do all functions $permissions = array( 'perform backup', 'access backup files', 'delete backup files', 'restore from backup', ); $this->admin_user = $this->drupalCreateUserRolePerm($permissions); // move the existing backup dir out of the way $directory = _backup_migrate_get_save_path(); if (is_dir($directory)) { $this->directory_backup = $directory . $this->randomName(5, '_'); rename($directory, $this->directory_backup); } } /** * SimpleTest core method: code run after each and every test method. */ function tearDown() { // if ($this->directory_backup) { $directory = _backup_migrate_get_save_path(); $this->delete_directory(_backup_migrate_get_save_path()); rename($this->directory_backup, $directory); } parent::tearDown(); } function testManualBackup() { $directory = _backup_migrate_get_save_path(); $edit = array( 'backup_migrate_file_name' => $this->randomName(5, 'backup'), 'backup_migrate_exclude_tables[]' => array(), 'backup_migrate_nodata_tables[]' => array(), 'backup_migrate_compression' => "none", 'backup_migrate_timestamp_format' => '', 'backup_migrate_destination' => "save", 'backup_migrate_append_timestamp' => false, 'backup_migrate_save_settings' => false, ); $this->drupalLoginUser($this->admin_user); $this->drupalPostRequest("admin/content/backup_migrate", $edit, t('Backup Database')); $this->assertTrue(file_exists($directory ."/manual/". $edit['backup_migrate_file_name'] .'.sql'), t("Checking that a backup file was created", array('!key' => $key))); $edit['backup_migrate_compression'] = 'gzip'; $this->drupalPostRequest("admin/content/backup_migrate", $edit, t('Backup Database')); $this->assertTrue(file_exists($directory ."/manual/". $edit['backup_migrate_file_name'] .'.sql.gz'), t("Checking that a backup file was created", array('!key' => $key))); $edit['backup_migrate_compression'] = 'bzip'; $this->drupalPostRequest("admin/content/backup_migrate", $edit, t('Backup Database')); $this->assertTrue(file_exists($directory ."/manual/". $edit['backup_migrate_file_name'] .'.sql.bz'), t("Checking that a backup file was created", array('!key' => $key))); $edit['backup_migrate_compression'] = 'zip'; $this->drupalPostRequest("admin/content/backup_migrate", $edit, t('Backup Database')); $this->assertTrue(file_exists($directory ."/manual/". $edit['backup_migrate_file_name'] .'.sql.zip'), t("Checking that a backup file was created", array('!key' => $key))); $this->delete_directory($directory); } function testSaveDefaultSettings() { $directory = _backup_migrate_get_save_path(); $tables = _backup_migrate_get_table_names(); $edit = array( 'backup_migrate_file_name' => $this->randomName(5, 'backup'), 'backup_migrate_exclude_tables[]' => $tables, 'backup_migrate_nodata_tables[]' => $tables, 'backup_migrate_compression' => "gzip", 'backup_migrate_timestamp_format' => 'Y-m-d', 'backup_migrate_destination' => "download", 'backup_migrate_append_timestamp' => false, 'backup_migrate_save_settings' => true, ); foreach ($edit as $key => $value) { $this->drupalVariableSet($key, NULL); } $this->drupalLoginUser($this->admin_user); $this->drupalPostRequest("admin/content/backup_migrate", $edit, t('Backup Database')); // load vars from db (becuase they were saved by a seperate thread, they are not available to variable_get) $vars = variable_init(); unset($edit['backup_migrate_save_settings']); foreach ($edit as $key => $value) { $key = str_replace("[]", '', $key); $this->assertEqual($vars[$key], $value, t('Checking that the variable !var was set', array('!var' => $key))); } $this->drupalGet(url("logout", NULL, NULL, TRUE)); $this->delete_directory($directory); } function testListSavedBackups() { $types = array( 'manual' => "admin/content/backup_migrate/files", 'scheduled' => "admin/content/backup_migrate/files/scheduled" ); foreach ($types as $type => $url) { $directory = _backup_migrate_check_destination_dir($type); // add some files $valid_extensions = array(".sql", ".gz", ".bz", ".zip"); $invalid_extensions = array(".txt", ".doc", ".svn", ".abc", ".xyz", ""); $files = array(); for ($i = 0; $i < 4; $i++) { $valid = $i % 2 == 0; if ($valid) { $file = $this->randomName(rand(1, 64), '') . $valid_extensions[array_rand($valid_extensions)]; } else { $file = $this->randomName(rand(1, 64), '') . $invalid_extensions[array_rand($invalid_extensions)]; } $path = $directory ."/". $file; $size = rand(10, 100); file_put_contents($path, $this->randomName($size, '')); $files[] = array( 'name' => $file, 'path' => $directory ."/". $file, 'size' => format_size($size), 'time' => date("m/d/Y h:i a", filectime($path)), 'valid' => $valid, ); } // check access only permissions $permissions = array( 'access backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url($url, NULL, NULL, TRUE)); foreach ($files as $file) { if (!$file['valid']) { $this->assertNoText($file['name'], t("checking that an invalid file is not in the file list")); } else { $this->assertText($file['name'], t("checking that a valid file name (!text) is in the file list", array("!text" => $file['name']))); $this->assertText($file['size'], t("checking that a valid file size (!text) is in the file list", array("!text" => $file['size']))); $this->assertText($file['time'], t("checking that a valid file time (!text) is in the file list", array("!text" => $file['time']))); $this->assertWantedRaw(l("download", "system/files/". $file['path']), t("checking that the download link is in the file list")); $this->assertNoUnwantedRaw(l("restore", "admin/content/backup_migrate/restorefile/". $file['path']), t("checking that the restore link is not in the file list")); $this->assertNoUnwantedRaw(l("delete", "admin/content/backup_migrate/delete/". $file['path']), t("checking that the delete link is not in the file list")); } } $this->drupalGet(url("logout", NULL, NULL, TRUE)); // check restore permissions $permissions = array( 'access backup files', 'restore from backup', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url($url, NULL, NULL, TRUE)); foreach ($files as $file) { if (!$file['valid']) { $this->assertNoText($file['name'], t("checking that an invalid file is not in the file list")); } else { $this->assertText($file['name'], t("checking that a valid file name (!text) is in the file list", array("!text" => $file['name']))); $this->assertText($file['size'], t("checking that a valid file size (!text) is in the file list", array("!text" => $file['size']))); $this->assertText($file['time'], t("checking that a valid file time (!text) is in the file list", array("!text" => $file['time']))); $this->assertWantedRaw(l("download", "system/files/". $file['path']), t("checking that the download link is in the file list")); $this->assertWantedRaw(l("restore", "admin/content/backup_migrate/restorefile/". $file['path']), t("checking that the restore link is not in the file list")); $this->assertNoUnwantedRaw(l("delete", "admin/content/backup_migrate/delete/". $file['path']), t("checking that the delete link is not in the file list")); } } $this->drupalGet(url("logout", NULL, NULL, TRUE)); // check delete permissions $permissions = array( 'access backup files', 'delete backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url($url, NULL, NULL, TRUE)); foreach ($files as $file) { if (!$file['valid']) { $this->assertNoText($file['name'], t("checking that an invalid file is not in the file list")); } else { $this->assertText($file['name'], t("checking that a valid file name (!text) is in the file list", array("!text" => $file['name']))); $this->assertText($file['size'], t("checking that a valid file size (!text) is in the file list", array("!text" => $file['size']))); $this->assertText($file['time'], t("checking that a valid file time (!text) is in the file list", array("!text" => $file['time']))); $this->assertWantedRaw(l("download", "system/files/". $file['path']), t("checking that the download link is in the file list")); $this->assertNoUnwantedRaw(l("restore", "admin/content/backup_migrate/restorefile/". $file['path']), t("checking that the restore link is not in the file list")); $this->assertWantedRaw(l("delete", "admin/content/backup_migrate/delete/". $file['path']), t("checking that the delete link is not in the file list")); } } $this->drupalGet(url("logout", NULL, NULL, TRUE)); } $this->delete_directory(_backup_migrate_get_save_path()); } function testDownloadBackup() { $types = array( 'manual' => "admin/content/backup_migrate/files", 'scheduled' => "admin/content/backup_migrate/files/scheduled" ); foreach ($types as $type => $url) { $directory = _backup_migrate_check_destination_dir($type); // add a file $file = $this->randomName(rand(1, 64), '') .".sql"; $path = $directory ."/". $file; $size = rand(10, 100); $contents = $this->randomName($size, ''); file_put_contents($path, $contents); $direct_url = $GLOBALS['base_url'] .'/'. $path; $private_url = url('system/files/'. $path, NULL, NULL, TRUE); // check logged out user $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PUBLIC); $this->drupalGet(url($direct_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url($private_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PRIVATE); $this->drupalGet(url($direct_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url($private_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); // check no access perms $permissions = array(); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PUBLIC); $this->drupalGet(url($direct_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url($private_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PRIVATE); $this->drupalGet(url($direct_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url($private_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); $permissions = array( 'access backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url($url, NULL, NULL, TRUE)); $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PUBLIC); $this->drupalGet(url($direct_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url($private_url, NULL, NULL, TRUE)); $this->assertResponse(array("200"), t("Checking that the user was not access denied")); $this->assertHeader("Content-Disposition", 'attachment; filename="'. $file .'"'); $this->assertText($contents); $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PRIVATE); $this->drupalGet(url($direct_url, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url($private_url, NULL, NULL, TRUE)); $this->assertResponse(array("200"), t("Checking that the user was not access denied")); $this->assertHeader("Content-Disposition", 'attachment; filename="'. $file .'"'); $this->assertText($contents); $this->drupalGet(url("logout", NULL, NULL, TRUE)); } } function testDeleteBackup() { foreach (array('manual', 'scheduled') as $type) { $directory = _backup_migrate_check_destination_dir($type); $file = $directory ."/". $this->randomName(rand(1, 64), '') .'.sql'; file_put_contents($file, $this->randomName(100, '')); $this->assertTrue(file_exists($file), t("Reality checking that the test file was created")); // user without delete access // check access only permissions $permissions = array( 'access backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url("admin/content/backup_migrate/delete/". $file, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->assertTrue(file_exists($file), t("Checking that the backup file was not deleted")); $this->post(url("admin/content/backup_migrate/delete/". $file, NULL, NULL, TRUE), array('confirm' => 1)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->assertTrue(file_exists($file), t("Checking that the backup file was not deleted")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); // user with delete access // check access only permissions $permissions = array( 'access backup files', 'delete backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url("admin/content/backup_migrate/delete/". $file, NULL, NULL, TRUE)); $this->assertWantedRaw(t('Are you sure you want to delete the backup file at %path?', array('%path' => $file)), t("checking a confirmation message is displayed")); $this->assertSubmit(t("Delete"), t('Checking that the delete button is there')); $this->assertTrue(file_exists($file), t("Checking that the backup file was not deleted")); $this->drupalPostRequest("admin/content/backup_migrate/delete/". $file, array(), t('Delete')); // we should check that the module notifies the user that the file has been deleted. // only we can't, because the module doesn't actually do that... oops $this->assertFalse(file_exists($file), t("Checking that the backup file was deleted")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); } $this->delete_directory(_backup_migrate_get_save_path()); } function testRestoreFromSaved() { foreach (array('manual', 'scheduled') as $type) { $directory = _backup_migrate_check_destination_dir($type); $file = $directory ."/". $this->randomName(rand(1, 64), '') .'.sql'; $test_table = $this->randomName(10, 'testtable_'); file_put_contents($file, "CREATE TABLE $test_table (testid int(10));"); $this->assertTrue(file_exists($file), t("Reality checking that the test file was created")); // user without restore access // check access only permissions $permissions = array( 'access backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url("admin/content/backup_migrate/restorefile/". $file, NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->post(url("admin/content/backup_migrate/restorefile/". $file, NULL, NULL, TRUE), array('confirm' => 1)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); // user with restore access // check access only permissions $permissions = array( 'access backup files', 'restore from backup', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url("admin/content/backup_migrate/restorefile/". $file, NULL, NULL, TRUE)); $this->assertWantedRaw(t('Are you sure you want to restore the database from the backup at %path?', array('%path' => $file)), t("checking a confirmation message is displayed")); $this->assertSubmit(t("Restore"), t('Checking that the restore button is there')); $this->drupalPostRequest("admin/content/backup_migrate/restorefile/". $file, array(), t('Restore')); // check that the file was imported into the db $this->assertTrue(in_array($test_table, _backup_migrate_get_table_names()), t("Checking that the test table is present.")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); db_query("DROP TABLE $test_table;"); } $this->delete_directory(_backup_migrate_get_save_path()); } function testRestoreFromUpload() { $directory = _backup_migrate_check_destination_dir($type); $file = file_directory_temp() .'/'. $this->randomName(10, '') .'.sql'; $test_table = $this->randomName(10, 'testtable_'); file_put_contents($file, "CREATE TABLE $test_table (testid int(10));"); $this->assertTrue(file_exists($file), t("Reality checking that the test file was created")); $edit = array(); $edit['files[backup_migrate_restore_upload]'] = $file; // user without restore access // check access only permissions $permissions = array( 'access backup files', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url("admin/content/backup_migrate/restore/", NULL, NULL, TRUE)); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->post(url("admin/content/backup_migrate/restore/", NULL, NULL, TRUE), $edit); $this->assertResponse(array("401", "403"), t("Checking that the user was access denied")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); // user with restore access // check access only permissions $permissions = array( 'access backup files', 'restore from backup', ); $user = $this->drupalCreateUserRolePerm($permissions); $this->drupalLoginUser($user); $this->drupalGet(url("admin/content/backup_migrate/restore/", NULL, NULL, TRUE)); $this->assertSubmit(t("Restore Database"), t('Checking that the restore button is there')); $this->drupalPostRequest("admin/content/backup_migrate/restore/", $edit, t('Restore Database')); // check that the file was imported into the db $this->assertTrue(in_array($test_table, _backup_migrate_get_table_names()), t("Checking that the test table is present.")); $this->drupalGet(url("logout", NULL, NULL, TRUE)); db_query("DROP TABLE $test_table;"); } // utlility functions function assertDrupalMessage($type, $drupal_message, $message) { foreach (@$_SESSION['messages'][$type] as $session_message) { if ($session_message == $drupal_message) { $this->assertTrue(true, $message); return; } } $this->assertTrue(false, $message); } function removeDrupalMessage($type, $drupal_message) { foreach (@$_SESSION['messages'][$type] as $key => $session_message) { if ($session_message == $drupal_message) { unset($_SESSION['messages'][$type][$key]); } } } function delete_directory($dirname) { if (is_dir($dirname) && $dir_handle = opendir($dirname)) { while ($file = readdir($dir_handle)) { if ($file != '.' && $file != '..') { if (!is_dir($dirname .'/'. $file)) { unlink($dirname .'/'. $file); } else { $this->delete_directory($dirname .'/'. $file); } } } closedir($dir_handle); rmdir($dirname); } } }