// $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()); 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(); } } void OverwriteFile(std::string File) { std::ofstream Output; 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++) { Output << RandomChar[static_cast(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * CharLen)]; } 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); } } bool TestBackupRestore() { for (int i = 0; i < NoFileName.size(); i++) { // Backup and overwrite files that don't exist. TestFileBackup.CreateBackupFile(NoFileName[i]); OverwriteFile(NoFileName[i]); } for (int i = 0; i < FileName.size(); i++) { // Back up and overwrite the files that exist. TestFileBackup.CreateBackupFile(FileName[i]); OverwriteFile(FileName[i]); } TestFileBackup.RestoreAllFilesFromBackup(); bool ResultIsPass = true; for (int i = 0; i < NoFileName.size(); i++) { // Check that files don't exist. if (FileBackup::FileExists(NoFileName[i])) { std::string Temp; Temp = "TestBackupRestore: File " + NoFileName[i]; Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; throw std::runtime_error(Temp); } } for (int i = 0; i < FileName.size(); i++) { // Check content of restored files. std::ifstream Input; Input.open(FileName[i].c_str()); if (!Input) { std::string Temp; Temp = "TestBackupRestore: Error opening the restored file " + FileName[i]; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } std::string RestoredContent; Input >> RestoredContent; Input.close(); if (!Input) { std::string Temp; Temp = "TestBackupRestore: Error closing the restored file " + FileName[i]; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } if (RestoredContent != FileContent[FileName[i]]) { std::string Temp; Temp = "***Error--File " + FileName[i]; Temp += " was not restored correctly.\n"; Error(Temp); ResultIsPass = false; } } return ResultIsPass; } bool TestRemoveAllBackupFiles() { TestFileBackup.RemoveAllBackupFiles(); std::string BackupFileName; bool ResultIsPass = true; for (int i = 0; i < NoFileName.size(); i++) { // Check that files don't exist. BackupFileName = FileBackup::GetBackupFileName(NoFileName[i]); if (FileBackup::FileExists(BackupFileName)) { std::string Temp; Temp = "***Error--Backup file " + BackupFileName; Temp += " was not removed.\n"; Error(Temp); ResultIsPass = false; } } for (int i = 0; i < FileName.size(); i++) { // Check that files don't exist. BackupFileName = FileBackup::GetBackupFileName(FileName[i]); if (FileBackup::FileExists(BackupFileName)) { std::string Temp; Temp = "***Error--Backup file " + BackupFileName; Temp += " was not removed.\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() { /// 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]); OverwriteFile(NoFileName[i]); } TestNoFileBackup.RestoreAllFilesFromBackup(); bool ResultIsPass = true; for (int i = 0; i < NoFileName.size(); i++) { // Check that files don't exist. if (FileBackup::FileExists(NoFileName[i])) { std::string Temp; Temp = "TestBackupRestoreWithNoFiles: File " + NoFileName[i]; Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; throw std::runtime_error(Temp); } } 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; for (int i = 0; i < NoFileName.size(); i++) { // Check that files don't exist. if (FileBackup::FileExists(NoFileName[i])) { std::string Temp; Temp = "TestBackupRestoreWithNoFilesNoOverwrite: File " + NoFileName[i]; Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; Temp += "but was determined to exist.\n"; throw std::runtime_error(Temp); } } return ResultIsPass; } void Finalize() { for (int i = 0; i < FileName.size(); i++) { remove(FileName[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"); } } // 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. }