Skip to content

Commit

Permalink
Further testing of file access mode. Got rid of 'rw'
Browse files Browse the repository at this point in the history
  • Loading branch information
frs69wq committed May 23, 2024
1 parent 9921c47 commit f282e98
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 29 deletions.
6 changes: 3 additions & 3 deletions src/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace simgrid::module::fs {
* @return A smart pointer on the corresponding I/O activity
*/
s4u::IoPtr File::read_async(sg_size_t num_bytes) {
if (access_mode_ != "r" && access_mode_ != "rw")
if (access_mode_ != "r")
throw std::invalid_argument("Invalid access mode '" + access_mode_ + "'. Cannot read in 'w' or 'a' mode'");
// if the current position is close to the end of the file, we may not be able to read the requested size
sg_size_t num_bytes_to_read = std::min(num_bytes, metadata_->get_current_size() - current_position_);
Expand All @@ -54,7 +54,7 @@ namespace simgrid::module::fs {
* @return the actual number of bytes read in the file
*/
sg_size_t File::read(sg_size_t num_bytes, bool simulate_it) {
if (access_mode_ != "r" && access_mode_ != "rw")
if (access_mode_ != "r")
throw std::invalid_argument("Invalid access mode '" + this->access_mode_ + "'. Cannot read in 'w' or 'a' mode'");
if (num_bytes == 0) /* Nothing to read, return */
return 0;
Expand All @@ -78,7 +78,7 @@ namespace simgrid::module::fs {
int File::write_init_checks(sg_size_t num_bytes) {
static int sequence_number = -1;
int my_sequence_number = ++sequence_number;
if (access_mode_ != "w" && access_mode_ != "rw" && access_mode_ != "a")
if (access_mode_ != "w" && access_mode_ != "a")
throw std::invalid_argument("Invalid access mode. Cannot write in 'r' mode'");

//TODO: Would be good to move some of the code below to FileMetadata, but that requires
Expand Down
15 changes: 11 additions & 4 deletions src/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "fsmod/PartitionLRUCaching.hpp"
#include "fsmod/FileSystemException.hpp"

XBT_LOG_NEW_DEFAULT_CATEGORY(fsmod_filesystem, "File System module: File system management related logs");

namespace simgrid::module::fs {

/**
Expand Down Expand Up @@ -135,16 +137,16 @@ namespace simgrid::module::fs {
/**
* @brief Open a file. If no file corresponds to the given fullpath, a new file of size 0 is created.
* @param full_path: an absolute file path
* @param access_mode: access mode ("r", "w", "a", or "rw")
* @param access_mode: access mode ("r", "w", or "a")
* @return
*/
std::shared_ptr<File> FileSystem::open(const std::string &full_path, const std::string& access_mode) {
// "Get a file descriptor"
if (this->num_open_files_ >= this->max_num_open_files_) {
throw FileSystemException(XBT_THROW_POINT, "Too many open file descriptors");
}
if (access_mode != "r" && access_mode != "w" && access_mode != "a" && access_mode != "rw") {
throw std::invalid_argument("Invalid access mode. Authorized values are: 'r', 'w', 'a' or 'rw'");
if (access_mode != "r" && access_mode != "w" && access_mode != "a") {
throw std::invalid_argument("Invalid access mode. Authorized values are: 'r', 'w', or 'a'");
}

// Get the partition and path
Expand All @@ -161,6 +163,10 @@ namespace simgrid::module::fs {
throw FileSystemException(XBT_THROW_POINT, "File not found. Cannot be opened in 'r' mode");
create_file(full_path, 0);
metadata = partition->get_file_metadata(dir, file_name);
} else {
if (access_mode == "w") {
//TODO update metadata to reset size to 0
}
}

// Increase the refcount
Expand All @@ -169,8 +175,9 @@ namespace simgrid::module::fs {
// Create the file object
auto file = std::shared_ptr<File>(new File(simplified_path, access_mode, metadata, partition.get()));

XBT_INFO("%s %d", access_mode.c_str(), SEEK_END);
if (access_mode == "a")
file->current_position_ = SEEK_END;
file->current_position_ = metadata->get_current_size();

this->num_open_files_++;
return file;
Expand Down
33 changes: 32 additions & 1 deletion test/file_system_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,38 @@ TEST_F(FileSystemTest, TooManyFilesOpened) {
XBT_INFO("Close the first file");
ASSERT_NO_THROW(limited_fs->close(file));
XBT_INFO("Opening a third file should now work");
ASSERT_NO_THROW(file3 = limited_fs->open("/dev/a/stuff/baz.txt", "rw"));
ASSERT_NO_THROW(file3 = limited_fs->open("/dev/a/stuff/baz.txt", "w"));
});

// Run the simulation
ASSERT_NO_THROW(sg4::Engine::get_instance()->run());
});
}

TEST_F(FileSystemTest, BadAccessMode) {
DO_TEST_WITH_FORK([this]() {
this->setup_platform();
// Create one actor (for this test we could likely do it all in the maestro but what the hell)
sg4::Actor::create("TestActor", host_, [this]() {
std::shared_ptr<sgfs::File> file;
XBT_INFO("Create a 10kB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10kB"));
XBT_INFO("Open the file in read mode ('r')");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
XBT_INFO("Try to write in a file opened in read mode, which should fail");
ASSERT_THROW(file->write("5kB"), std::invalid_argument);
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open the file in write mode ('w')");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Try to read from a file opened in write mode, which should fail");
ASSERT_THROW(file->read("5kB"), std::invalid_argument);
XBT_INFO("Asynchronous read from a file opened in write mode should also fail");
ASSERT_THROW(file->read_async("5kB"), std::invalid_argument);
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open the file in unsupported mode ('w+'), which should fail");
ASSERT_THROW(file = fs_->open("/dev/a/foo.txt", "w+"), std::invalid_argument);
});

// Run the simulation
Expand Down
54 changes: 35 additions & 19 deletions test/jbod_storage_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,14 @@ TEST_F(JBODStorageTest, ReadWriteUnsupportedRAID) {
ASSERT_NO_THROW(jds_->set_raid_level(sgfs::JBODStorage::RAID::RAID2));
XBT_INFO("Create a 10MB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10MB"));
XBT_INFO("Open File '/dev/a/foo.txt'");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "rw"));
XBT_INFO("Open File '/dev/a/foo.txt' in write mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Write 2MB at /dev/a/foo.txt, which should fail");
ASSERT_THROW(file->write("12MB"), std::runtime_error);
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open File '/dev/a/foo.txt' in read mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
XBT_INFO("Read 12MB at /dev/a/foo.txt, which should fail too");
ASSERT_THROW(file->read("12MB"), std::runtime_error);
XBT_INFO("Close the file");
Expand All @@ -230,14 +234,16 @@ TEST_F(JBODStorageTest, ReadWriteRAID0) {
ASSERT_NO_THROW(jds_->set_raid_level(sgfs::JBODStorage::RAID::RAID0));
XBT_INFO("Create a 10MB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10MB"));
XBT_INFO("Open File '/dev/a/foo.txt'");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "rw"));
XBT_INFO("Open File '/dev/a/foo.txt' in write mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Write 2MB at /dev/a/foo.txt");
ASSERT_DOUBLE_EQ(file->write("12MB"), 12000000);
XBT_INFO("Write complete. Clock is at 3.1s (.1s to transfer, 3s to write)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 3.1);
XBT_INFO("Seek back to SEEK_SET and read 12MB at /dev/a/foo.txt");
ASSERT_NO_THROW(file->seek(SEEK_SET));
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open File '/dev/a/foo.txt' in read mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
ASSERT_DOUBLE_EQ(file->read("12MB"), 12000000);
XBT_INFO("Read complete. Clock is at 4.7s (1.5s to read, .1s to transfer)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 4.7);
Expand All @@ -257,14 +263,16 @@ TEST_F(JBODStorageTest, ReadWriteRAID1) {
ASSERT_NO_THROW(jds_->set_raid_level(sgfs::JBODStorage::RAID::RAID1));
XBT_INFO("Create a 10MB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10MB"));
XBT_INFO("Open File '/dev/a/foo.txt'");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "rw"));
XBT_INFO("Open File '/dev/a/foo.txt' in write mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Write 6MB at /dev/a/foo.txt");
ASSERT_DOUBLE_EQ(file->write("6MB"), 6000000);
XBT_INFO("Write complete. Clock is at 6.05s (.05s to transfer, 6s to write)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 6.05);
XBT_INFO("Seek back to SEEK_SET and read 6MB at /dev/a/foo.txt");
ASSERT_NO_THROW(file->seek(SEEK_SET));
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open File '/dev/a/foo.txt' in read mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
ASSERT_DOUBLE_EQ(file->read("6MB"), 6000000);
XBT_INFO("Read complete. Clock is at 9.1s (3s to read, .05s to transfer)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 9.1);
Expand All @@ -284,14 +292,16 @@ TEST_F(JBODStorageTest, ReadWriteRAID4) {
ASSERT_NO_THROW(jds_->set_raid_level(sgfs::JBODStorage::RAID::RAID4));
XBT_INFO("Create a 10MB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10MB"));
XBT_INFO("Open File '/dev/a/foo.txt'");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "rw"));
XBT_INFO("Open File '/dev/a/foo.txt' in write mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Write 4MB at /dev/a/foo.txt");
ASSERT_DOUBLE_EQ(file->write("6MB"), 6000000);
XBT_INFO("Write complete. Clock is at 2.06s (.05s to transfer, 0.01 to compute parity, 2s to write)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 2.06);
XBT_INFO("Seek back to SEEK_SET and read 6MB at /dev/a/foo.txt");
ASSERT_NO_THROW(file->seek(SEEK_SET));
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open File '/dev/a/foo.txt' in read mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
ASSERT_DOUBLE_EQ(file->read("6MB"), 6000000);
XBT_INFO("Read complete. Clock is at 3.11s (1s to read, .05s to transfer)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 3.11);
Expand All @@ -317,23 +327,29 @@ TEST_F(JBODStorageTest, ReadWriteRAID6) {
ASSERT_NO_THROW(jds_->set_raid_level(sgfs::JBODStorage::RAID::RAID6));
XBT_INFO("Create a 10MB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10MB"));
XBT_INFO("Open File '/dev/a/foo.txt'");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "rw"));
XBT_INFO("Open File '/dev/a/foo.txt' in write mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Write 6MB at /dev/a/foo.txt");
ASSERT_DOUBLE_EQ(file->write("6MB"), 6000000);
XBT_INFO("Write complete. Clock is at 3.08s (.05s to transfer, 0.02 to compute parity, 3s to write)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 3.08);
XBT_INFO("Seek back to SEEK_SET and read 6MB at /dev/a/foo.txt");
ASSERT_NO_THROW(file->seek(SEEK_SET));
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Open File '/dev/a/foo.txt' in read mode");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
ASSERT_DOUBLE_EQ(file->read("6MB"), 6000000);
XBT_INFO("Read complete. Clock is at 4.63s (1.5s to read, .05s to transfer)");
ASSERT_DOUBLE_EQ(sg4::Engine::get_clock(), 4.63);
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
XBT_INFO("Test the evolution of parity disks ");
xbt_log_control_set("fsmod_jbod.thresh:debug fsmod_jbod.fmt:'%m'");
for (int i = 0; i < 3; i++ ){
xbt_log_control_set("no_loc");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
ASSERT_NO_THROW(file->write("6MB"));
ASSERT_NO_THROW(file->seek(SEEK_SET));
ASSERT_NO_THROW(fs_->close(file));
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "r"));
ASSERT_NO_THROW(testing::internal::CaptureStderr());
ASSERT_NO_THROW(file->read("6MB"));
ASSERT_NO_THROW(captured_debug_output = testing::internal::GetCapturedStderr());
Expand Down
24 changes: 24 additions & 0 deletions test/one_disk_storage_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,27 @@ TEST_F(OneDiskStorageTest, SingleAsyncWrite) {
ASSERT_NO_THROW(sg4::Engine::get_instance()->run());
});
}

TEST_F(OneDiskStorageTest, SingleAppendWrite) {
DO_TEST_WITH_FORK([this]() {
this->setup_platform();
xbt_log_control_set("root.thresh:info");
sg4::Actor::create("TestActor", host_, [this]() {
std::shared_ptr<sgfs::File> file;
sg4::IoPtr my_write;
sg_size_t num_bytes_written = 0;
XBT_INFO("Create a 10MB file at /dev/a/foo.txt");
ASSERT_NO_THROW(fs_->create_file("/dev/a/foo.txt", "10MB"));
XBT_INFO("Open File '/dev/a/foo.txt' in append mode ('a')");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "a"));
XBT_INFO("Write 2MB at /dev/a/foo.txt");
ASSERT_NO_THROW(file->write("2MB"));
XBT_INFO("Check file size, it should still be 12MB");
ASSERT_DOUBLE_EQ(fs_->file_size("/dev/a/foo.txt"), 12*1000*1000);
XBT_INFO("Close the file");
ASSERT_NO_THROW(fs_->close(file));
});
// Run the simulation
ASSERT_NO_THROW(sg4::Engine::get_instance()->run());
});
}
2 changes: 1 addition & 1 deletion test/seek_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ TEST_F(SeekTest, SeekandTell) {
XBT_INFO("Create a 100kB file at /dev/a/foo.txt");
ASSERT_NO_THROW(this->fs_->create_file("/dev/a/foo.txt", "100kB"));
XBT_INFO("Open File '/dev/a/foo.txt'");
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "rw"));
ASSERT_NO_THROW(file = fs_->open("/dev/a/foo.txt", "w"));
XBT_INFO("Check current position, should be 0");
ASSERT_DOUBLE_EQ(file->tell(), 0);
XBT_INFO("Seek 1kB forward");
Expand Down
4 changes: 3 additions & 1 deletion test/stat_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@ TEST_F(StatTest, Stat) {
ASSERT_EQ(stat_struct->refcount, 1);
XBT_INFO("Modifying file state");
std::shared_ptr<sgfs::File> file2;
ASSERT_NO_THROW(file2 = fs_->open("/dev/a/foo.txt", "rw"));
ASSERT_NO_THROW(file2 = fs_->open("/dev/a/foo.txt", "w"));
ASSERT_NO_THROW(file2->seek(100*1000));
ASSERT_NO_THROW(file2->write(12*1000, false));
ASSERT_NO_THROW(fs_->close(file));
ASSERT_NO_THROW(sg4::this_actor::sleep_for(10));
ASSERT_NO_THROW(file2 = fs_->open("/dev/a/foo.txt", "r"));
ASSERT_NO_THROW(file->seek(0));
ASSERT_NO_THROW(file->read(1000, false));
XBT_INFO("Calling stat() again");
Expand Down

0 comments on commit f282e98

Please sign in to comment.