|
|
@@ -0,0 +1,294 @@ |
|
|
|
// $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 <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <vector>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
#include <cerrno>
|
|
|
|
|
|
|
|
#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<std::string> StringContainer;
|
|
|
|
|
|
|
|
/// Names of files to back up.
|
|
|
|
StringContainer FileName;
|
|
|
|
|
|
|
|
/// Container for the file content.
|
|
|
|
typedef std::map<std::string, std::string> 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<int> 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<int>::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::size_t>(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::size_t>(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.
|
|
|
|
}
|