Browse Source

Implemented unit tests for FileBackup class.


git-svn-id: https://svn.microneil.com/svn/SNFUtility/trunk@4 aa37657e-1934-4a5f-aa6d-2d8eab27ff7c
master
adeniz 13 years ago
parent
commit
a6d12a8ec2
4 changed files with 351 additions and 34 deletions
  1. 21
    14
      Common/FileBackup.cpp
  2. 9
    20
      Common/FileBackup.hpp
  3. 27
    0
      CommonTests/Makefile.am
  4. 294
    0
      CommonTests/TestFileBackup.cpp

+ 21
- 14
Common/FileBackup.cpp View File

@@ -6,7 +6,7 @@
// This file implements the common functionality for the configuration
// utilities.
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <fstream>
#include <vector>
@@ -21,15 +21,12 @@
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string FileBackup::BackupSuffix(".bak");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
FileBackup::FileBackup(std::string Suffix) :
BackupSuffix(Suffix) {
}
void
FileBackup::CopyFile(std::string From, std::string To) {
@@ -123,10 +120,11 @@ FileBackup::CreateBackupFile(std::string File) {
}
bool
void
FileBackup::RemoveAllBackupFiles() {
bool ErrorOccurred = false;
std::ostringstream ErrorMessage;
for (FilenameContainer::iterator iFile = BackedUpFile.begin();
iFile != BackedUpFile.end();
@@ -137,8 +135,8 @@ FileBackup::RemoveAllBackupFiles() {
if (0 != remove(BackupFileName.c_str())) { // Delete the backup file.
std::cerr << "Unable to remove backup file " << BackupFileName
<< ": " << strerror(errno) << "\n";
ErrorMessage << "Unable to remove backup file " << BackupFileName
<< ": " << strerror(errno) << "\n";
ErrorOccurred = true;
@@ -146,14 +144,19 @@ FileBackup::RemoveAllBackupFiles() {
}
return ErrorOccurred;
if (ErrorOccurred) {
throw std::runtime_error(ErrorMessage.str());
}
}
bool
void
FileBackup::RestoreAllFilesFromBackup() {
bool ErrorOccurred = false;
std::ostringstream ErrorMessage;
for (FilenameContainer::iterator iFile = BackedUpFile.begin();
iFile != BackedUpFile.end();
@@ -168,8 +171,8 @@ FileBackup::RestoreAllFilesFromBackup() {
} catch (std::exception &e) {
std::cerr << "Error restoring " << *iFile << " from backup "
<< BackupFileName << ": " << e.what() << " \n";
ErrorMessage << "Error restoring " << *iFile << " from backup "
<< BackupFileName << ": " << e.what() << " \n";
ErrorOccurred = true;
@@ -177,6 +180,10 @@ FileBackup::RestoreAllFilesFromBackup() {
}
return ErrorOccurred;
if (ErrorOccurred) {
throw std::runtime_error(ErrorMessage.str());
}
}

+ 9
- 20
Common/FileBackup.hpp View File

@@ -22,13 +22,6 @@ class FileBackup {
public:
/// Constructor.
//
// \param[in] Suffix is the suffix to append to create the name of
// the backup file.
//
FileBackup(std::string Suffix);
/// Create a backup of the specified file.
//
// This method creates a backup of the specified file The name of
@@ -39,7 +32,7 @@ public:
//
// \param[in] File is the file name to create a backup for.
//
// \throws std::runtime_error in case of error.
// \throws std::runtime_error if an error is encountered.
//
// \see RestoreAllFilesFromBackup().
//
@@ -50,26 +43,20 @@ public:
// This method removes the backup of the files specified by the
// CreateBackup() method.
//
// If an error is encountered, a message is output to std::cerr.
// \throws std::runtime_error if an error is encountered.
//
// \returns true if all backups were removed with no error, false otherwise.
//
bool RemoveAllBackupFiles();
void RemoveAllBackupFiles();
/// Restore the all the specified files from the backup.
//
// This method restores the backup of the files specified by the
// CreateBackupFile() method.
//
// If an error is encountered, a message is output to std::cerr.
//
// \returns true if all files were restored with no error, false otherwise.
// \throws std::runtime_error if an error is encountered.
//
// \see CreateBackupFile().
//
bool RestoreAllFilesFromBackup();
private:
void RestoreAllFilesFromBackup();
/// Get the name of the backup file.
//
@@ -77,7 +64,9 @@ private:
//
// \returns the name of the backup file.
//
std::string GetBackupFileName(std::string File);
static std::string GetBackupFileName(std::string File);
private:
/// Copy a file.
//
@@ -91,7 +80,7 @@ private:
/// Suffix to append to the file name to obtain the backup file
/// name.
std::string BackupSuffix;
static const std::string BackupSuffix;
/// Typedef for container of names of files.
typedef std::vector<std::string> FilenameContainer;

+ 27
- 0
CommonTests/Makefile.am View File

@@ -0,0 +1,27 @@
## Process this file with automake to produce Makefile.in
##
## $Id: Makefile.am,v 1.2 2007/05/29 19:06:09 adeniz Exp $
##
## automake input for the MicroNeil SNFUtility/Common tests.
##
## Author: Alban Deniz
##
##
## Copyright (C) 2012 ARM Research Labs, LLC.
## See www.armresearch.com for the copyright terms.
##

AM_CXXFLAGS = -I@top_srcdir@/SNFUtility/Common

TESTS = \
TestFileBackup

check_PROGRAMS = \
TestFileBackup

TestFileBackup_SOURCES = \
TestFileBackup.cpp \
@top_srcdir@/SNFUtility/Common/FileBackup.cpp

clean-local:
rm -f *.gcno *.gcov *.gcda *~

+ 294
- 0
CommonTests/TestFileBackup.cpp View File

@@ -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.
}

Loading…
Cancel
Save