t('Backup and Migrate Unit Tests'), 'desc' => t('Executes the unit test suite for misc functions in backup and migrate.'), 'group' => t('Backup and Migrate module'), ); } var $directory_backup; /** * SimpleTest core method: code run before each and every test method. */ function setUp() { parent::setUp(); // 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(); } // test _backup_migrate_get_save_path() function testGetSavePath() { $this->assertEqual(_backup_migrate_get_save_path(), file_directory_path() ."/backup_migrate"); $this->assertEqual(_backup_migrate_get_save_path('manual'), file_directory_path() ."/backup_migrate/manual"); $this->assertEqual(_backup_migrate_get_save_path('scheduled'), file_directory_path() ."/backup_migrate/scheduled"); } function testFileReadableRemotely() { $filename = $this->randomName(5, 'readtest_') .".txt"; $filepath = file_directory_path() .'/'. $filename; $contents = $this->randomName(5, 'contents_'); // public file access: $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PUBLIC); $this->assertFalse(_backup_migrate_test_file_readable_remotely($filename, $contents), t('Checking false on non existant file read')); if (($fp = @fopen($filepath, 'w')) && @fputs($fp, $contents)) { fclose($fp); } else { $this->assertTrue(false, t('Need to be able to write to a file in files to complete this test')); } $this->assertTrue(_backup_migrate_test_file_readable_remotely($filename, $contents), t('Checking readable file')); unlink(realpath($filepath)); } // test the creation of the backup directories function testCreateBackupDirectory() { $directory = _backup_migrate_get_save_path(); // we try reading and writing with a root based file path (/var/www/.../files) and a relative one (sites/default/files) // this is to test for this issue: http://drupal.org/node/193862 $full_path = realpath(file_directory_path()); $relative_path = str_replace(realpath('.') ."/", '', $full_path); // public file access: $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PUBLIC); // relative path $this->drupalVariableSet('file_directory_path', $relative_path); _backup_migrate_check_destination_dir(); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate"), t('Checking for backup directory')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); $this->assertEqual(_backup_migrate_check_destination_dir('manual'), file_directory_path() ."/backup_migrate/manual", t('Checking for manual backup directory create')); $this->assertEqual(_backup_migrate_check_destination_dir('manual'), file_directory_path() ."/backup_migrate/manual", t('Checking for manual backup directory preexisting')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/manual"), t('Checking for manual backup directory')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/manual/test.txt"), t('Checking for manual backup directory test file')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that manual backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); $this->assertEqual(_backup_migrate_check_destination_dir('scheduled'), file_directory_path() ."/backup_migrate/scheduled", t('Checking for manual backup directory create')); $this->assertEqual(_backup_migrate_check_destination_dir('scheduled'), file_directory_path() ."/backup_migrate/scheduled", t('Checking for manual backup directory preexisting')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/scheduled"), t('Checking for scheduled backup directory')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/scheduled/test.txt"), t('Checking for scheduled backup directory test file')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that scheduled backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); // absolute path $this->drupalVariableSet('file_directory_path', $full_path); _backup_migrate_check_destination_dir(); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate"), t('Checking for backup directory')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); $this->assertEqual(_backup_migrate_check_destination_dir('manual'), file_directory_path() ."/backup_migrate/manual", t('Checking for manual backup directory create')); $this->assertEqual(_backup_migrate_check_destination_dir('manual'), file_directory_path() ."/backup_migrate/manual", t('Checking for manual backup directory preexisting')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/manual"), t('Checking for manual backup directory')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/manual/test.txt"), t('Checking for manual backup directory test file')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that manual backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); $this->assertEqual(_backup_migrate_check_destination_dir('scheduled'), file_directory_path() ."/backup_migrate/scheduled", t('Checking for manual backup directory create')); $this->assertEqual(_backup_migrate_check_destination_dir('scheduled'), file_directory_path() ."/backup_migrate/scheduled", t('Checking for manual backup directory preexisting')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/scheduled"), t('Checking for scheduled backup directory')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/scheduled/test.txt"), t('Checking for scheduled backup directory test file')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that scheduled backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); // private file access: $this->drupalVariableSet('file_directory_path', $relative_path); $this->drupalVariableSet('file_downloads', FILE_DOWNLOADS_PRIVATE); _backup_migrate_check_destination_dir(); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate"), t('Checking for backup directory')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); _backup_migrate_check_destination_dir('manual'); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/manual"), t('Checking for manual backup directory')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/manual/test.txt"), t('Checking for manual backup directory test file')); $check = drupal_http_request($GLOBALS['base_url'] .'/'. file_directory_path() ."/backup_migrate/manual/test.txt"); $this->assertEqual($check->code, 403, t('Checking that test file is forbidden for access')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that manual backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); _backup_migrate_check_destination_dir('scheduled'); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/scheduled"), t('Checking for scheduled backup directory')); $this->assertTrue(file_exists(file_directory_path() ."/backup_migrate/scheduled/test.txt"), t('Checking for scheduled backup directory test file')); $check = drupal_http_request($GLOBALS['base_url'] .'/'. file_directory_path() ."/backup_migrate/scheduled/test.txt"); $this->assertEqual($check->code, 403, t('Checking that test file is forbidden for access')); $this->assertTrue(is_writable(file_directory_path() ."/backup_migrate"), t('Checking that scheduled backup directory is writable')); $this->delete_directory(file_directory_path() ."/backup_migrate"); // we need to test failure to create the directory // if we create a file where the directory should be that should make the operation fail $error_message_main = t("Unable to create or write to the save directory '%directory'. Please check the file permissions on your files directory.", array('%directory' => file_directory_path() ."/backup_migrate")); $error_message_manual = t("Unable to create or write to the save directory '%directory'. Please check the file permissions on your files directory.", array('%directory' => file_directory_path() ."/backup_migrate/manual")); $error_message_scheduled = t("Unable to create or write to the save directory '%directory'. Please check the file permissions on your files directory.", array('%directory' => file_directory_path() ."/backup_migrate/scheduled")); // Add a file with the same name so that the directory create fails touch(file_directory_path() ."/backup_migrate"); $this->assertFalse(_backup_migrate_check_destination_dir(), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_main, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_main); $this->assertFalse(is_dir(file_directory_path() ."/backup_migrate"), t('Checking for lack of backup directory')); $this->assertFalse(_backup_migrate_check_destination_dir('manual'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_main, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_main); $this->assertFalse(_backup_migrate_check_destination_dir('scheduled'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_main, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_main); $this->assertFalse(is_dir(file_directory_path() ."/backup_migrate/scheduled"), t('Checking for lack of backup directory')); unlink(file_directory_path() ."/backup_migrate"); mkdir(file_directory_path() ."/backup_migrate"); touch(file_directory_path() ."/backup_migrate/manual"); touch(file_directory_path() ."/backup_migrate/scheduled"); $this->assertFalse(_backup_migrate_check_destination_dir('manual'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_manual, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_manual); $this->assertFalse(is_dir(file_directory_path() ."/backup_migrate/manual"), t('Checking for lack of backup directory')); $this->assertFalse(_backup_migrate_check_destination_dir('scheduled'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_scheduled, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_scheduled); $this->assertFalse(is_dir(file_directory_path() ."/backup_migrate/scheduled"), t('Checking for lack of backup directory')); $this->delete_directory(file_directory_path() ."/backup_migrate"); // check unwritable directory mkdir(file_directory_path() ."/backup_migrate"); chmod($directory, 0444); $this->assertFalse(_backup_migrate_check_destination_dir(), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_main, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_main); $this->assertFalse(_backup_migrate_check_destination_dir('manual'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_main, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_main); $this->assertFalse(is_dir(file_directory_path() ."/backup_migrate/manual"), t('Checking for lack of backup directory')); $this->assertFalse(_backup_migrate_check_destination_dir('scheduled'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_main, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_main); $this->assertFalse(is_dir(file_directory_path() ."/backup_migrate/scheduled"), t('Checking for lack of backup directory')); chmod(file_directory_path() ."/backup_migrate", 0777); $this->delete_directory(file_directory_path() ."/backup_migrate"); mkdir(file_directory_path() ."/backup_migrate"); mkdir(file_directory_path() ."/backup_migrate/manual"); mkdir(file_directory_path() ."/backup_migrate/scheduled"); chmod(file_directory_path() ."/backup_migrate/manual", 0444); chmod(file_directory_path() ."/backup_migrate/scheduled", 0444); $this->assertFalse(_backup_migrate_check_destination_dir('manual'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_manual, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_manual); $this->assertFalse(_backup_migrate_check_destination_dir('scheduled'), t('Checking for a negative response from the create function')); $this->assertDrupalMessage('error', $error_message_scheduled, t('Checking that the user is warned about the ability to write to the backup directory')); $this->removeDrupalMessage('error', $error_message_scheduled); chmod(file_directory_path() ."/backup_migrate/manual", 0644); chmod(file_directory_path() ."/backup_migrate/scheduled", 0644); $this->delete_directory(file_directory_path() ."/backup_migrate"); // need to check that if the directory is publicly accessible for some reason the check fails mkdir(file_directory_path() ."/backup_migrate"); mkdir(file_directory_path() ."/backup_migrate/manual"); mkdir(file_directory_path() ."/backup_migrate/scheduled"); $directory = file_directory_path() ."/backup_migrate"; // override the htaccess with an insecure version $htaccess_lines = "order allow,deny\nallow from all\n"; if (($fp = @fopen($directory .'/.htaccess', 'w')) && @fputs($fp, $htaccess_lines)) { fclose($fp); chmod($directory .'/.htaccess', 0444); } // unable to create htaccess... throw an error else { $this->assertFalse(true, t('Need to be able to write to the htaccess file to complete this test')); } $this->assertFalse(_backup_migrate_check_destination_dir('manual'), t('Checking for failure of check on insecure directory')); chmod($directory .'/.htaccess', 0644); $this->assertTrue(_backup_migrate_check_destination_dir('manual'), t('Checking that the htaccess file is overwritten if possible.')); $htaccess_lines = "order allow,deny\ndeny from all\n"; $this->assertTrue(strpos(file_get_contents($directory .'/.htaccess'), $htaccess_lines) !== FALSE, t('Checking that the htaccess file contains the right value.')); $this->delete_directory(file_directory_path() ."/backup_migrate"); } function testCleanFileName() { // for the purposes of this module, safe filenames only contain letters, numbers, dots, dashes and underscores $safe_pattern = "/[A-Za-z0-9\-\_\.]+/"; // test the cleaning power $unsafe_name = "@#/\$he*ll&o, world!"; $safe_name = _backup_migrate_clean_filename($unsafe_name); $this->assertTrue(preg_match($safe_pattern, $safe_name), t('Testing that filename does not contain unsafe characters')); $this->assertEqual($safe_name, "helloworld", t('Testing that filename is consistent with input')); // check shortening $unsafe_name = str_repeat("abc", 50); $safe_name = _backup_migrate_clean_filename($unsafe_name); $this->assertTrue(strlen($safe_name) <= 50, t('Testing that filename is not too long')); // check empty string $safe_name = _backup_migrate_clean_filename(""); $this->assertTrue(strlen($safe_name) > 1, t('Testing that filename is not non existant')); } function testDefaultFileName() { // with token $this->drupalModuleEnable('token'); $name = _backup_migrate_default_file_name(); $this->assertEqual($name, '[site-name]', t('Checking default filename is site-name token')); // without token $this->drupalModuleDisable('token'); $sitename = $this->randomName(5, 'site_'); $this->drupalVariableSet('site_name', $sitename); $name = _backup_migrate_default_file_name(); $this->assertEqual($name, $sitename, t('Checking default filename is the site name')); } function testRemoveExpiredBackups() { $dir = file_directory_path() ."/backup_migrate/scheduled/"; _backup_migrate_check_destination_dir('scheduled'); for ($i = 0; $i < 10; $i++) { touch($dir . $this->randomName(5, 'somefile_') .'.sql'); } // reality check $this->assertEqual($this->countFiles($dir), 10, t('Reality checking the initial number of files in the scheduled dir')); // check infinity setting does not delete any $this->drupalVariableSet("backup_migrate_schedule_backup_keep", 0); _backup_migrate_remove_expired_backups(); $this->assertEqual($this->countFiles($dir), 10, t('Checking the initial number of files in the scheduled dir')); $this->drupalVariableSet("backup_migrate_schedule_backup_keep", 5); _backup_migrate_remove_expired_backups(); $this->assertEqual($this->countFiles($dir), 5, t('Checking the number of files in the scheduled dir')); $this->drupalVariableSet("backup_migrate_schedule_backup_keep", 10); _backup_migrate_remove_expired_backups(); $this->assertEqual($this->countFiles($dir), 5, t('Checking the number of files in the scheduled dir')); $this->drupalVariableSet("backup_migrate_schedule_backup_keep", 1); _backup_migrate_remove_expired_backups(); $this->assertEqual($this->countFiles($dir), 1, t('Checking the number of files in the scheduled dir')); $this->delete_directory(file_directory_path() ."/backup_migrate"); // make sure the files being removed are the oldest ones _backup_migrate_check_destination_dir('scheduled'); for ($i = 0; $i < 5; $i++) { touch($dir . $this->randomName(5, 'somefile_') .'.sql', $i * 86400); } for ($i = 0; $i < 5; $i++) { $this->drupalVariableSet("backup_migrate_schedule_backup_keep", 5 - $i); _backup_migrate_remove_expired_backups(); $time = $this->getOldestFiletime($dir); $this->assertEqual($time, $i * 86400, t('Checking the oldest file in the dir')); } $this->delete_directory(file_directory_path() ."/backup_migrate"); } function testTempFileDelete() { // create some files to be deleted $dir = file_directory_path() ."/backup_migrate/manual/"; _backup_migrate_check_destination_dir('manual'); for ($i = 0; $i < 10; $i++) { $file = $dir . $this->randomName(5, 'somefile_'); $files[] = $file; touch($file); } $this->assertEqual($this->countFiles($dir), 10, t('Checking the number of files created is 10')); _backup_migrate_temp_files_delete($files); $this->assertEqual($this->countFiles($dir), 0, t('Checking the number of files created is 0')); $this->delete_directory(file_directory_path() ."/backup_migrate"); } function testTempFile() { $dir = file_directory_path() ."/backup_migrate/manual/"; _backup_migrate_check_destination_dir('manual'); for ($i = 0; $i < 5; $i++) { $ext = $this->randomName($i, ''); $files[$i] = _backup_migrate_temp_file($ext); touch($files[$i]); $this->assertTrue(file_exists($files[$i]), t('Checking that the temporary file is available for writing')); $this->assertTrue(file_check_location($files[$i], file_directory_temp()), t('Check that the file is in the temp directory')); if ($ext) { $this->assertEqual(substr($files[$i], -strlen($ext)), $ext, t('Check that the temp file has the right extension')); } else { $this->assertTrue(strpos($files[$i], '.') === false, $ext, t('Check that the temp file has no extension')); } } // delete them _backup_migrate_temp_file(NULL, $true);; for ($i = 0; $i < 5; $i++) { $this->assertFalse(file_exists($file[$i]), t('Check that the temp file has been deleted')); } } function testGetFileInfo() { // this function uses _backup_migrate_temp_file because it's easy. // is that cheating? what's the policy on relying on a previously tested function // to run a test? answers welcome at ronan =at= gortonstudios (dot) com or the issue queue $contents = $this->randomName($size, ''); $valid_extensions = array( 'sql' => 'text/x-sql', 'gz' => 'application/x-gzip', 'bz' => 'application/x-bzip', 'zip' => 'application/zip', ); $invalid_extensions = array( 'txt', 'exe', 'foo', '', ); foreach ($valid_extensions as $ext => $mime) { $file = _backup_migrate_temp_file($ext); $size = rand(10, 100); file_put_contents($file, $this->randomName($size, '')); $info = _backup_migrate_file_info($file); $this->assertTrue(is_array($info), t('Checking that info is available on the given file (!ext)', array('!ext' => $ext))); $this->assertEqual($info['filesize'], $size, t('Checking that the filesize is correct')); $this->assertEqual($info['extension'], ".$ext", t('Checking that the file extension is correct')); $this->assertEqual($info['filename'], basename($file), t('Checking that the file basename')); $this->assertEqual($info['filemtime'], filemtime($file), t('Checking that modified time is correct')); $this->assertEqual($info['filectime'], filectime($file), t('Checking that created time is correct')); $this->assertEqual($info['filepath'], $file, t('Checking that file path is correct')); $this->assertEqual($info['filemime'], $mime, t('Checking that file mime is correct')); } foreach ($invalid_extensions as $ext) { $file = _backup_migrate_temp_file($ext); $size = rand(10, 100); file_put_contents($file, $this->randomName($size, '')); $info = _backup_migrate_file_info($file); $this->assertFalse($info, t('Checking that info is not available on the given file')); } // not found file $file = file_directory_temp() . $this->randomName(10, ''); $info = _backup_migrate_file_info($path); $this->assertFalse($info, t('Checking that info is not available on the non-existent file')); _backup_migrate_temp_file(NULL, $true);; } function testFileDownloadHook() { $dir = _backup_migrate_check_destination_dir('manual'); $valid_extensions = array( 'sql' => 'text/x-sql', 'gz' => 'application/x-gzip', 'bz' => 'application/x-bzip', 'zip' => 'application/zip', ); foreach ($valid_extensions as $ext => $mime) { $name = "test.". $ext; $file = $dir ."/". $name; $size = rand(10, 100); file_put_contents($file, $this->randomName($size, '')); $headers = backup_migrate_file_download($file); $this->assertTrue(in_array("Content-Type: $mime", $headers), t('Checking the file headers for mime type')); $this->assertTrue(in_array("Content-Length: $size", $headers), t('Checking the file headers for file size')); $this->assertTrue(in_array("Content-Disposition: attachment; filename=\"$name\"", $headers), t('Checking the file headers for file size')); } // non existant file $file = file_directory_temp() .'/'. $this->randomName(10, ''); $info = _backup_migrate_file_info($path); $this->assertFalse($info, t('Checking that info is not available on the non-existent file')); $headers = backup_migrate_file_download($file); $this->assertEqual($headers, NULL, t('Checking that non-existent file is ignored')); // file not in backup dir $file = _backup_migrate_temp_file('sql'); touch($file); $info = _backup_migrate_file_info($path); $this->assertFalse($info, t('Checking that info is not available on the non-existent file')); $headers = backup_migrate_file_download($file); $this->assertEqual($headers, NULL, t('Checking that file outside of backup directory is ingored')); } function testPathinSaveDir() { // $directory = _backup_migrate_get_save_path(); $this->delete_directory(file_directory_path() ."/backup_migrate"); // should be false if directories don't exist $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory ."/test"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory ."/a/b/c"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory ."/manual", "manual"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory ."manual/a/b/c", "manual"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory ."/scheduled", "scheduled"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir($directory ."scheduled/a/b/c", "scheduled"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test/". $directory), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test/", "manual"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test/", "scheduled"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("manual", "manual"), t('Checking that non-existant directory returns false')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("scheduled", "scheduled"), t('Checking that non-existant directory returns false')); _backup_migrate_check_destination_dir('manual'); _backup_migrate_check_destination_dir('scheduled'); $this->assertTrue(_backup_migrate_path_is_in_save_dir($directory), t('Checking that valid path is confirmed')); $this->assertTrue(_backup_migrate_path_is_in_save_dir($directory ."/test"), t('Checking that valid path is confirmed')); $this->assertTrue(_backup_migrate_path_is_in_save_dir($directory ."/manual", "manual"), t('Checking that valid path is confirmed')); $this->assertTrue(_backup_migrate_path_is_in_save_dir($directory ."/scheduled", "scheduled"), t('Checking that valid path is confirmed')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test/". $directory), t('Checking that invalid path is rejected')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test"), t('Checking that invalid path is rejected')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test/", "manual"), t('Checking that invalid path is rejected')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("test/", "scheduled"), t('Checking that invalid path is rejected')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("manual", "manual"), t('Checking that invalid path is rejected')); $this->assertFalse(_backup_migrate_path_is_in_save_dir("scheduled", "scheduled"), t('Checking that invalid path is rejected')); $this->delete_directory(file_directory_path() ."/backup_migrate"); } function testGetFileTypes() { $types = _backup_migrate_filetypes(); $this->assertTrue(is_array($types), t('Checking that the function returned an array')); $this->assertTrue(count($types) > 1, t('Checking that the function returned an array')); foreach ($types as $key => $type) { $this->assertTrue(preg_match('/.[a-z0-9\.]+/', $type['extension']), t('Checking that the returned type has a valid extension')); $this->assertTrue(preg_match('/[a-z0-9\-\.]+\/[a-z0-9\-\.]+/', $type['filemime']), t('Checking that the returned type has a valid mimetype')); } } function testSaveToDisk() { $directory = file_directory_path() ."/backup_migrate"; $tempfile = file_directory_temp() ."/". $this->randomName(10, ''); $contents = $this->randomName(128, ''); $filename = $this->randomName(10, ''); // check manual $this->delete_directory($directory); file_put_contents($tempfile, $contents); _backup_migrate_save_to_disk($tempfile, $filename, 'manual'); $this->assertTrue(file_exists($directory .'/manual/'. $filename), t('Checking that the file was saved to the server')); $this->assertEqual($contents, file_get_contents($directory .'/manual/'. $filename), t('Checking that the file contains the right contents')); $this->assertFalse(file_exists($tempfile), t('Checking that the temp file is no longer there')); // check scheduled $this->delete_directory($directory); file_put_contents($tempfile, $contents); _backup_migrate_save_to_disk($tempfile, $filename, 'scheduled'); $this->assertTrue(file_exists($directory .'/scheduled/'. $filename), t('Checking that the file was saved to the server')); $this->assertEqual($contents, file_get_contents($directory .'/scheduled/'. $filename), t('Checking that the file contains the right contents')); $this->assertFalse(file_exists($tempfile), t('Checking that the temp file is no longer there')); $this->delete_directory($directory); } function testGZipEncode() { // zip a known file and compare it to a compressed zip $tempfile = file_directory_temp() ."/". $this->randomName(10, 'gztest') .'.gz'; $knownfile = drupal_get_path('module', 'backup_migrate') ."/tests/test.txt"; $knownzip = drupal_get_path('module', 'backup_migrate') ."/tests/test.gz"; _backup_migrate_gzip_encode($knownfile, $tempfile); $temp_contents = file_get_contents($tempfile); $known_contents = file_get_contents($knownfile); $knownzip_contents = file_get_contents($knownzip); $zd = gzopen($tempfile, "r"); $temp_decoded = gzread($zd, 1000); gzclose($zd); $this->assertEqual(md5($temp_contents), md5($knownzip_contents)); $this->assertEqual($temp_decoded, $known_contents); //unlink($tempfile); } function testBZipEncode() { // zip a known file and compare it to a compressed zip $tempfile = file_directory_temp() ."/". $this->randomName(10, 'bztest'); $knownfile = drupal_get_path('module', 'backup_migrate') ."/tests/test.txt"; _backup_migrate_bzip_encode($knownfile, $tempfile); $temp_contents = file_get_contents($tempfile); $known_contents = file_get_contents($knownfile); $this->assertEqual(md5($temp_contents), md5(bzcompress($known_contents, 9))); $this->assertEqual(bzdecompress($temp_contents), $known_contents); unlink($tempfile); } function testZipEncode() { // zip a known file and compare it to a known compressed zip $tempfile = file_directory_temp() ."/". $this->randomName(10, 'ziptest') .".zip"; $knownfile = drupal_get_path('module', 'backup_migrate') ."/tests/test.txt"; _backup_migrate_zip_encode($knownfile, $tempfile, 'test.txt'); $zip = zip_open($tempfile); $entry = zip_read($zip); zip_entry_open($zip, $entry); $temp_contents = zip_entry_read($entry); $known_contents = file_get_contents($knownfile); //$this->assertEqual(md5($temp_contents), md5(bzcompress($known_contents, 9))); $this->assertEqual($temp_contents, $known_contents); unlink($tempfile); } function testDefaultTables() { // not much to do here but make sure the return value is an array of plausible table names $safe_pattern = "/[a-z\_]+/"; $tables = _backup_migrate_default_exclude_tables(); $this->assertTrue(is_array($tables), t('Testing that default exclude tables is an array')); foreach ($tables as $table) { $this->assertTrue(is_string($table), t('Testing that table name is a string')); $this->assertTrue(preg_match($safe_pattern, $table), t('Testing that table name: %name is valid', array('%name' => $name))); } $tables = _backup_migrate_default_structure_only_tables(); $this->assertTrue(is_array($tables), t('Testing that default structure only tables is an array')); foreach ($tables as $table) { $this->assertTrue(is_string($table), t('Testing that table name is a string')); $this->assertTrue(preg_match($safe_pattern, $table), t('Testing that table name: %name is valid', array('%name' => $name))); } } function testRestoreFile() {} function testGetTableNames() { // Make sure the return value is an array of plausible table names $safe_pattern = "/[a-z\_]+/"; $test_table = $this->randomName(10, 'testtable_'); db_query("CREATE TABLE $test_table (testid int(10));"); $tables = _backup_migrate_get_table_names(); $this->assertTrue(is_array($tables), t('Testing that default exclude tables is an array')); $this->assertTrue(count($tables) > 0, t('Testing at least one table is present')); foreach ($tables as $table) { $this->assertTrue(is_string($table), t('Testing that table name is a string')); $this->assertTrue(preg_match($safe_pattern, $table), t('Testing that table name: %name is valid', array('%name' => $name))); } $this->assertTrue(in_array($test_table, $tables), t('Testing that the test table is present')); db_query("DROP TABLE $test_table;"); } function testGetTables() { $test_table = $this->randomName(10, 'testtable_'); db_query("CREATE TABLE $test_table (testid int(10));"); $table_names = _backup_migrate_get_table_names(); $tables = _backup_migrate_get_tables(); foreach ($table_names as $table) { $this->assertTrue(isset($tables[$table]), t('Testing that table: %name is present', array('%name' => $name))); $this->assertTrue(isset($tables[$table]['Name']), t('Testing that table name is present', array('%name' => $name))); $this->assertTrue(array_key_exists('Auto_increment', $tables[$table]), t('Testing that table auto increment is present', array('%name' => $name))); } $this->assertTrue(isset($tables[$test_table]), t('Testing that the test table is present')); db_query("DROP TABLE $test_table;"); } function testGetSQLFooter() { $footer = _backup_migrate_get_sql_file_footer(); $this->assertTrue(strpos($footer, "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;") !== false, t('Check for one of the mode reset statements')); } function testGetSQLHeader() { $footer = _backup_migrate_get_sql_file_header(); $this->assertTrue(strpos($footer, "SET NAMES utf8;") !== false, t('Check for the set names')); $this->assertTrue(strpos($footer, "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;") !== false, t('Check for one of the mode reset statements')); } function testGetTableStuctureSQL() {} function testDumpSQLToFileHandle() {} function testGetDumpSQL() {} function testSendFileToDownload() {} function testDumpTables() {} function testBackupWithDefaults() {} function testDeleteCallback() {} function testDeleteConfirm() {} function testScheduleForm() {} function testBackupForm() {} function testListFiles() {} function testHookPerm() {} function testHookMenu() {} function testHookCron() {} function testHookSimpleTest() { // nah, just kidding } // utlility functions 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); } } 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 countFiles($dir) { $out = 0; if ($res = opendir($dir)) { // read all files and sort them by modified time while ($file = readdir($res)) { if ($file != '.' && $file != '..' && $file != 'test.txt') { $out++; } } } return $out; } function getOldestFiletime($dir) { // A very high number (the highest in fact). $out = 0xFFFFFFFF; if ($res = opendir($dir)) { // read all files and sort them by modified time while ($file = readdir($res)) { if ($file != '.' && $file != '..' && $file != 'test.txt') { $out = min($out, filemtime($dir .'/'. $file)); } } } return $out; } }