// $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. StringContainer FileName; /// Container for the file content. typedef std::map ContentContainer; /// Content of files to back up. ContentContainer FileContent; /// Random characters. const std::string RandomChar("abcdefghijklmnopqustuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+|=-"); std::string::size_type CharLen = RandomChar.length(); /// Unit under test. FileBackup TestFileBackup; /// Initialize test input. void Initialize() { 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); const char *CharPtr = RandomChar.data(); 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(); } } bool TestBackupRestore() { for (int i = 0; i < FileName.size(); i++) { // Back up and overwrite the files. TestFileBackup.CreateBackupFile(FileName[i]); std::ofstream Output; Output.open(FileName[i].c_str(), std::ios::trunc); // Overwrite the test file. if (!Output) { std::string Temp; Temp = "TestBackupRestore: Error opening the test file " + FileName[i]; 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 = "TestBackupRestore: Error overwriting the test file " + FileName[i]; Temp += ": "; Temp += strerror(errno); throw std::runtime_error(Temp); } Output.close(); } TestFileBackup.RestoreAllFilesFromBackup(); bool ResultIsPass = true; 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(); bool ResultIsPass = true; for (int i = 0; i < FileName.size(); i++) { // Check that files don't exist. std::ifstream Input; std::string BackupFileName; BackupFileName = FileBackup::GetBackupFileName(FileName[i]); Input.open(BackupFileName.c_str()); Input.close(); if (Input) { std::string Temp; Temp = "***Error--Backup file " + BackupFileName; Temp += " was not removed.\n"; Error(Temp); ResultIsPass = false; } } 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 backup/restore. if (!TestBackupRestore()) { ErrorExit("TestBackupRestore() failure.\n"); } // Test cleanup. if (!TestRemoveAllBackupFiles()) { ErrorExit("TestRemoveAllBackupFiles() failure.\n"); } Finalize(); // Remove test files. } // 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. }