Skip to content

Commit

Permalink
Add unit tests for compaction_catalog class
Browse files Browse the repository at this point in the history
  • Loading branch information
umegane committed Sep 17, 2024
1 parent a8116cc commit e60e8ca
Show file tree
Hide file tree
Showing 5 changed files with 358 additions and 72 deletions.
74 changes: 37 additions & 37 deletions src/limestone/compaction_catalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,58 +50,58 @@ void compaction_catalog::load() {
// Load the main catalog file
load_catalog_file(catalog_file_path_);
} catch (const limestone_exception& e) {
// Handle error and attempt to restore from backup
boost::system::error_code ec;

// Check if the backup file exists
if (file_ops_->exists(backup_file_path_, ec)) {
try {
// Load the backup file
load_catalog_file(backup_file_path_);

// Restore the backup file as the main catalog file
if (file_ops_->exists(catalog_file_path_, ec)) {
if (file_ops_->unlink(catalog_file_path_.c_str()) != 0) {
int error_num = errno;
LOG_AND_THROW_IO_EXCEPTION("Failed to remove existing catalog file: " + catalog_file_path_.string(), error_num);
}
} else if (ec && ec != boost::system::errc::no_such_file_or_directory) {
LOG_AND_THROW_IO_EXCEPTION("Error checking catalog file existence", ec.value());
}

// Rename the backup file to catalog file
if (file_ops_->rename(backup_file_path_.c_str(), catalog_file_path_.c_str()) != 0) {
int error_num = errno;
LOG_AND_THROW_IO_EXCEPTION("Failed to rename backup file: " + backup_file_path_.string() + " to catalog file: " + catalog_file_path_.string(), error_num);
}
} catch (const limestone_exception& backup_error) {
LOG_AND_THROW_EXCEPTION("Failed to restore from backup compaction catalog file: " + std::string(backup_error.what()));
// Handle error by trying to restore from backup
restore_from_backup();
}
}

void compaction_catalog::restore_from_backup() {
boost::system::error_code ec;

// Check if the backup file exists
if (file_ops_->exists(backup_file_path_, ec)) {
// Load the backup file
load_catalog_file(backup_file_path_);

// Restore the backup file as the main catalog file
if (file_ops_->exists(catalog_file_path_, ec)) {
if (file_ops_->unlink(catalog_file_path_.c_str()) != 0) {
int error_num = errno;
LOG_AND_THROW_IO_EXCEPTION("Failed to remove existing catalog file: " + catalog_file_path_.string(), error_num);
}
} else if (ec && ec != boost::system::errc::no_such_file_or_directory) {
LOG_AND_THROW_IO_EXCEPTION("Error checking backup file existence", ec.value());
} else {
LOG_AND_THROW_EXCEPTION("Failed to load compaction catalog file and no backup available.");
LOG_AND_THROW_IO_EXCEPTION("Error checking catalog file existence", ec.value());
}

// Rename the backup file to catalog file
if (file_ops_->rename(backup_file_path_.c_str(), catalog_file_path_.c_str()) != 0) {
int error_num = errno;
LOG_AND_THROW_IO_EXCEPTION("Failed to rename backup file: " + backup_file_path_.string() + " to catalog file: " + catalog_file_path_.string(),
error_num);
}
} else if (ec && ec != boost::system::errc::no_such_file_or_directory) {
LOG_AND_THROW_IO_EXCEPTION("Error checking backup file existence", ec.value());
} else {
LOG_AND_THROW_EXCEPTION("Failed to load compaction catalog file and no backup available.");
}
}


// Helper method to load the catalog file
void compaction_catalog::load_catalog_file(const boost::filesystem::path& path) {
// file_operations を使って ifstream を開く
auto file = file_ops_->open_ifstream(path.string());
auto strm = file_ops_->open_ifstream(path.string());
int error_num = errno;
if (!file->is_open()) {
if (!file_ops_->is_open(*strm)) {
LOG_AND_THROW_IO_EXCEPTION("Failed to open compaction catalog file: " + path.string(), error_num);
}

std::string line;
if (!file_ops_->getline(*file, line)) {
if (!file_ops_->getline(*strm, line)) {
error_num = errno;
if (file_ops_->is_eof(*file)) {
if (file_ops_->is_eof(*strm)) {
LOG_AND_THROW_EXCEPTION("Unexpected end of file while reading header line");
}
if (file_ops_->has_error(*file)) {
if (file_ops_->has_error(*strm)) {
LOG_AND_THROW_IO_EXCEPTION("Failed to read line from file", error_num);
}
}
Expand All @@ -112,9 +112,9 @@ void compaction_catalog::load_catalog_file(const boost::filesystem::path& path)

bool max_epoch_id_found = false;
while (true) {
if (!file_ops_->getline(*file, line)) {
if (!file_ops_->getline(*strm, line)) {
error_num = errno;
if (file_ops_->is_eof(*file)) {
if (file_ops_->is_eof(*strm)) {
break;
}
LOG_AND_THROW_IO_EXCEPTION("Failed to read line from file", error_num);
Expand Down
3 changes: 2 additions & 1 deletion src/limestone/compaction_catalog.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,13 @@ class compaction_catalog {
// Helper methods
protected:
void load();
void restore_from_backup();
void load_catalog_file(const boost::filesystem::path &directory_path);
void parse_catalog_entry(const std::string& line, bool& max_epoch_id_found);
[[nodiscard]] std::string create_catalog_content() const;

// for only testing
public:
protected:

Check warning on line 235 in src/limestone/compaction_catalog.h

View workflow job for this annotation

GitHub Actions / Clang-Tidy

readability-redundant-access-specifiers

redundant access specifier has the same accessibility as the previous access specifier
void set_file_operations(std::unique_ptr<file_operations> file_ops);
void reset_file_operations();
};
Expand Down
7 changes: 6 additions & 1 deletion src/limestone/file_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ int real_file_operations::fsync(int fd) {
}

int real_file_operations::rename(const char* oldname, const char* newname) {
return ::rename(oldname, newname);
int ret = ::rename(oldname, newname);
return ret;
}

int real_file_operations::unlink(const char* filename) {
Expand All @@ -86,6 +87,10 @@ bool real_file_operations::is_eof(std::ifstream& file) {
return file.eof();
}

bool real_file_operations::is_open(std::ifstream& file) {
return file.is_open();
}


// -----------------------------------------
// Boost filesystem operations
Expand Down
5 changes: 5 additions & 0 deletions src/limestone/file_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ class file_operations {
// Checks if the file stream reached EOF
virtual bool is_eof(std::ifstream& file) = 0;

// Checks if the file stream is open
virtual bool is_open(std::ifstream& file) = 0;

// Checks if there's an error in the file stream
virtual bool has_error(std::ifstream& file) = 0;


// -----------------------------------------
// Boost filesystem operations
// -----------------------------------------
Expand All @@ -112,6 +116,7 @@ class real_file_operations : public file_operations {
std::unique_ptr<std::ifstream> open_ifstream(const std::string& path) override;
bool getline(std::ifstream& file, std::string& line) override;
bool is_eof(std::ifstream& file) override;
bool is_open(std::ifstream& file) override;
bool has_error(std::ifstream& file) override;

bool exists(const boost::filesystem::path& p, boost::system::error_code& ec) override;
Expand Down
Loading

0 comments on commit e60e8ca

Please sign in to comment.