// $Id$ // // \file TestFileBackup.cpp // // Copyright (C) 2012, ARM Research Labs, LLC. // See www.armresearch.com for the copyright terms. // // This is the unit test for the class FileBackup. // #include #include #include #include #include #include #include #include #include #include "FileBackup.hpp" /// Output error. #define Error(msg) \ { \ std::cerr << "In file " << __FILE__ << ":" << __LINE__ << ": "; \ std::cerr << msg; \ } /// Exit with error. #define ErrorExit(msg) \ { \ Error(msg) \ std::exit(-1); \ } /// Vector of strings typedef std::vector StringContainer; /// Names of files to back up that exist. StringContainer FileName; /// Container for the file content. typedef std::map ContentContainer; /// Content of files to back up. ContentContainer FileContent; /// Names of files to back up that don't exist. StringContainer NoFileName; /// Random characters. const std::string RandomChar("abcdefghijklmnopqustuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+|=-"); std::string::size_type CharLen = RandomChar.length(); /// Unit under test. FileBackup TestFileBackup; /// Initialize test input. void Initialize() { NoFileName.push_back("NoFile1.txt"); NoFileName.push_back("NoFile2.txt"); NoFileName.push_back("NoFile3.txt"); NoFileName.push_back("NoFile4.txt"); for (int i = 0; i < NoFileName.size(); i++) { remove(NoFileName[i].c_str()); } std::vector FileSize; FileName.push_back("File1.txt"); FileSize.push_back(1024); FileName.push_back("File2.txt"); FileSize.push_back(4000); FileName.push_back("File3.txt"); FileSize.push_back(493); FileName.push_back("File4.txt"); FileSize.push_back(203043); std::vector::iterator iSize = FileSize.begin(); for (StringContainer::iterator iFile = FileName.begin(); // Create random data. iFile != FileName.end(); iFile++, iSize++) { for (int iChar = 0; iChar < *iSize; iChar++) { FileContent[*iFile].push_back(RandomChar[static_cast(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * CharLen)]); } remove(iFile->c_str()); remove(FileBackup::GetBackupFileName(*iFile).c_str()); remove(FileBackup::GetFailedFileName(*iFile).c_str()); std::ofstream Output; // Write the test file. Output.open(iFile->c_str(), std::ios::trunc); if (!Output) { std::string Temp; Temp = "Initialize: Error opening the test file " + *iFile; Temp += " to copy to: "; Temp += strerror(errno); throw std::runtime_error(Temp); } Output << FileContent[*iFile]; if (Output.bad() || Output.fail()) { std::string Temp; Temp = "Initialize: Error writing the test file " + *iFile; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } Output.close(); } } std::string OverwriteFile(std::string File) { std::ofstream Output; std::string NewContent; Output.open(File.c_str(), std::ios::trunc); // Overwrite the test file. if (!Output) { std::string Temp; Temp = "OverwriteFile: Error opening the file " + File; Temp += " to overwrite: "; Temp += strerror(errno); throw std::runtime_error(Temp); } for (int j = 0; j < 223; j++) { NewContent.push_back(RandomChar[static_cast(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * CharLen)]); } Output << NewContent; // Overwrite the test file. if (Output.bad() || Output.fail()) { std::string Temp; Temp = "OverwriteFile: Error overwriting the file " + File; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } Output.close(); if (!FileBackup::FileExists(File)) { std::string Temp; Temp = "OverwriteFile: File " + File; Temp += " was created but was determined to not exist.\n"; throw std::runtime_error(Temp); } return NewContent; } bool CompareContent(std::string FileName, std::string ExpectedContent) { std::ifstream Input; Input.open(FileName.c_str()); if (!Input) { std::string Temp; Temp = "CompareContent: Error opening " + FileName; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } std::string ReadContent; Input >> ReadContent; Input.close(); if (!Input) { std::string Temp; Temp = "CompareContent: Error closing " + FileName; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } if (ReadContent != ExpectedContent) { std::string Temp; Temp = "***Error--File " + FileName; Temp += " did not have the correct content.\n"; Error(Temp); return false; } return true; } bool TestBackupRestore() { ContentContainer NewContent; ContentContainer OverwrittenContent; std::string Content; bool ResultIsPass = true; for (int i = 0; i < NoFileName.size(); i++) { // Backup and overwrite files that don't exist. TestFileBackup.CreateBackupFile(NoFileName[i]); Content = OverwriteFile(NoFileName[i]); // Overwrite the file. NewContent[NoFileName[i]] = Content; // Save the new content. } for (int i = 0; i < FileName.size(); i++) { // Back up and overwrite the files that exist. TestFileBackup.CreateBackupFile(FileName[i]); Content = OverwriteFile(FileName[i]); // Overwrite the file. OverwrittenContent[FileName[i]] = Content; // Save the new contents. } TestFileBackup.RestoreAllFilesFromBackup(); for (int i = 0; i < NoFileName.size(); i++) { if (FileBackup::FileExists(NoFileName[i])) { // Check that files don't exist. std::string Temp; Temp = "TestBackupRestore: File " + NoFileName[i]; Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; Error(Temp); ResultIsPass = false; } if (!CompareContent(FileBackup::GetFailedFileName(NoFileName[i]), // Check the .failed file content. NewContent[NoFileName[i]])) { std::string Temp; Temp = "TestBackupRestore: RestoreAllFilesFromBackup() did not correctly"; Temp += " create the .failed file.\n"; Error(Temp); ResultIsPass = false; } } for (int i = 0; i < FileName.size(); i++) { if (!CompareContent(FileName[i], FileContent[FileName[i]])) { // Check content of restored files. std::string Temp; Temp = "TestBackupRestore: RestoreAllFilesFromBackup() did not correctly"; Temp += " restore the file.\n"; Error(Temp); ResultIsPass = false; } if (!CompareContent(FileBackup::GetFailedFileName(FileName[i]), // Check the .failed file content. OverwrittenContent[FileName[i]])) { std::string Temp; Temp = "TestBackupRestore: RestoreAllFilesFromBackup() did not correctly"; Temp += " create the .failed file.\n"; Error(Temp); ResultIsPass = false; } } return ResultIsPass; } bool TestRemoveAllBackupFiles() { TestFileBackup.RemoveAllBackupFiles(); std::string BackupFileName; std::string FailedFileName; bool ResultIsPass = true; for (int i = 0; i < NoFileName.size(); i++) { BackupFileName = FileBackup::GetBackupFileName(NoFileName[i]); if (FileBackup::FileExists(BackupFileName)) { // Check that backup files don't exist. std::string Temp; Temp = "***Error--Backup file " + BackupFileName; Temp += " was not removed.\n"; Error(Temp); ResultIsPass = false; } FailedFileName = FileBackup::GetFailedFileName(NoFileName[i]); if (!FileBackup::FileExists(FailedFileName)) { // Check that .failed files exist. std::string Temp; Temp = "***Error--Failed file " + FailedFileName; Temp += " does not exist.\n"; Error(Temp); ResultIsPass = false; } } for (int i = 0; i < FileName.size(); i++) { BackupFileName = FileBackup::GetBackupFileName(FileName[i]); if (FileBackup::FileExists(BackupFileName)) { // Check that backup files don't exist. std::string Temp; Temp = "***Error--Backup file " + BackupFileName; Temp += " was not removed.\n"; Error(Temp); ResultIsPass = false; } FailedFileName = FileBackup::GetFailedFileName(FileName[i]); if (!FileBackup::FileExists(FailedFileName)) { // Check that .failed files exist. std::string Temp; Temp = "***Error--Failed file " + FailedFileName; Temp += " does not exist.\n"; Error(Temp); ResultIsPass = false; } } return ResultIsPass; } bool TestFileExists() { bool ResultIsPass = true; for (int i = 0; i < FileName.size(); i++) { // Check that files don't exist. std::string BackupFileName; BackupFileName = FileBackup::GetBackupFileName(FileName[i]); if (FileBackup::FileExists(BackupFileName)) { std::string Temp; Temp = "***Error--File " + BackupFileName; Temp += " incorrectly determined to exist.\n"; Error(Temp); ResultIsPass = false; } if (!FileBackup::FileExists(FileName[i])) { std::string Temp; Temp = "***Error--File " + FileName[i]; Temp += " incorrectly determined to not exist.\n"; Error(Temp); ResultIsPass = false; } } return ResultIsPass; } bool TestBackupRestoreWithNoFiles() { ContentContainer NewContent; std::string Content; std::string BackupFileName; /// Unit under test. FileBackup TestNoFileBackup; for (int i = 0; i < NoFileName.size(); i++) { // Backup and overwrite files that don't exist. TestNoFileBackup.CreateBackupFile(NoFileName[i]); Content = OverwriteFile(NoFileName[i]); // Overwrite the file. NewContent[NoFileName[i]] = Content; // Save the new content. } TestNoFileBackup.RestoreAllFilesFromBackup(); bool ResultIsPass = true; for (int i = 0; i < NoFileName.size(); i++) { if (FileBackup::FileExists(NoFileName[i])) { // Check that file doesn't exist. std::string Temp; Temp = "TestBackupRestoreWithNoFiles: File " + NoFileName[i]; Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; Error(Temp); ResultIsPass = false; } BackupFileName = FileBackup::GetBackupFileName(NoFileName[i]); if (FileBackup::FileExists(BackupFileName)) { // Check that backup file doesn't exist. std::string Temp; Temp = "TestBackupRestoreWithNoFilesNoOverwrite: File " + BackupFileName; Temp += " was not supposed to be created by CreateBackupFile, "; Temp += "but was determined to exist.\n"; Error(Temp); ResultIsPass = false; } if (!CompareContent(FileBackup::GetFailedFileName(NoFileName[i]), // Check the .failed file content. NewContent[NoFileName[i]])) { std::string Temp; Temp = "TestBackupRestoreWithNoFilesNoOverwrite: RestoreAllFilesFromBackup() did not correctly"; Temp += " create the .failed file.\n"; Error(Temp); ResultIsPass = false; } } return ResultIsPass; } bool TestBackupRestoreWithNoFilesNoOverwrite() { /// Unit under test. FileBackup TestNoFileBackup; for (int i = 0; i < NoFileName.size(); i++) { // Backup and overwrite files that don't exist. TestNoFileBackup.CreateBackupFile(NoFileName[i]); } TestNoFileBackup.RestoreAllFilesFromBackup(); bool ResultIsPass = true; std::string BackupFileName; std::string FailedFileName; for (int i = 0; i < NoFileName.size(); i++) { if (FileBackup::FileExists(NoFileName[i])) { // Check that file don't exist. std::string Temp; Temp = "TestBackupRestoreWithNoFilesNoOverwrite: File " + NoFileName[i]; Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; Error(Temp); ResultIsPass = false; } BackupFileName = FileBackup::GetBackupFileName(NoFileName[i]); if (FileBackup::FileExists(BackupFileName)) { // Check that backup file doesn't exist. std::string Temp; Temp = "TestBackupRestoreWithNoFilesNoOverwrite: File " + BackupFileName; Temp += " was not supposed to be created by CreateBackupFile, "; Temp += "but was determined to exist.\n"; Error(Temp); ResultIsPass = false; } FailedFileName = FileBackup::GetFailedFileName(NoFileName[i]); if (FileBackup::FileExists(FailedFileName)) { // Check that failed file doesn't exist. std::string Temp; Temp = "TestBackupRestoreWithNoFilesNoOverwrite: File " + FailedFileName; Temp += " was not supposed to be created by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; Error(Temp); ResultIsPass = false; } } return ResultIsPass; } void Finalize() { for (int i = 0; i < FileName.size(); i++) { remove(FileName[i].c_str()); remove((FileBackup::GetBackupFileName(FileName[i]).c_str())); remove((FileBackup::GetFailedFileName(FileName[i]).c_str())); } for (int i = 0; i < NoFileName.size(); i++) { remove(NoFileName[i].c_str()); remove((FileBackup::GetBackupFileName(NoFileName[i]).c_str())); remove((FileBackup::GetFailedFileName(NoFileName[i]).c_str())); } } /// Unit tests for FileBackup. // // This function creates several files of varying size, and verifies // the functionality of the FileBackup backup, restore, and delete // functions. // int main(int argc, char* argv[]) { try { // Catch anything that breaks loose. Initialize(); // Create test files. // Test FileExists. if (!TestFileExists()) { ErrorExit("TestFileExists() failure.\n"); } // Test backup/restore. if (!TestBackupRestore()) { ErrorExit("TestBackupRestore() failure.\n"); } // Test cleanup. if (!TestRemoveAllBackupFiles()) { ErrorExit("TestRemoveAllBackupFiles() failure.\n"); } Finalize(); // Remove test files. // Test backup/restore with no files. if (!TestBackupRestoreWithNoFiles()) { ErrorExit("TestBackupRestoreWithNoFiles() failure.\n"); } // Test backup/restore with no files and no overwriting of files. if (!TestBackupRestoreWithNoFilesNoOverwrite()) { ErrorExit("TestBackupRestoreWithNoFilesNoOverwrite() failure.\n"); } Finalize(); } // That's all folks. catch(std::exception& e) { // Report any normal exceptions. std::cerr << "FileBackup exception: " << e.what() << std::endl; return -1; } catch(...) { // Report any unexpected exceptions. std::cerr << "Panic! Unknown Exception!" << std::endl; return -1; } return 0; // Normally we return zero. }