diff --git a/LibOS/shim/test/fs/.gitignore b/LibOS/shim/test/fs/.gitignore index efa23a46..3edece17 100644 --- a/LibOS/shim/test/fs/.gitignore +++ b/LibOS/shim/test/fs/.gitignore @@ -12,6 +12,7 @@ /copy_whole /delete /open_close +/open_flags /read_write /seek_tell /stat diff --git a/LibOS/shim/test/fs/Makefile b/LibOS/shim/test/fs/Makefile index 16a18d1b..820e204c 100644 --- a/LibOS/shim/test/fs/Makefile +++ b/LibOS/shim/test/fs/Makefile @@ -10,6 +10,7 @@ execs = \ $(copy_execs) \ delete \ open_close \ + open_flags \ read_write \ seek_tell \ stat \ diff --git a/LibOS/shim/test/fs/open_flags.c b/LibOS/shim/test/fs/open_flags.c new file mode 100644 index 00000000..1c22f87f --- /dev/null +++ b/LibOS/shim/test/fs/open_flags.c @@ -0,0 +1,83 @@ +#include "common.h" + +const int g_mode = 0664; +const char g_data = 'x'; + +size_t get_file_size(const char* path) { + struct stat st; + if (stat(path, &st) < 0) + fatal_error("Failed to stat file '%s': %s\n", path, strerror(errno)); + printf("size(%s) == %zu\n", path, st.st_size); + return st.st_size; +} + +void open_test__(const char* path, int flags, const char* flags_str, bool exists, + bool expect_success, bool do_write) { + const char* exists_str = exists ? "exists" : "doesn't exist"; + int fd = open(path, flags, g_mode); + if (fd < 0) { + if (expect_success) { + fatal_error("open(%s) [%s] failed!\n", flags_str, exists_str); + } else { + printf("open(%s) [%s] failed as expected\n", flags_str, exists_str); + } + } else { + if (expect_success) { + printf("open(%s) [%s] succeeded as expected\n", flags_str, exists_str); + if (do_write) + write_fd(path, fd, &g_data, sizeof(g_data)); + } else { + fatal_error("open(%s) [%s] unexpectedly succeeded\n", flags_str, exists_str); + } + close(fd); + } +} + +#define OPEN_TEST(path, flags, exists, expect_success, do_write) \ + open_test__(path, flags, #flags, exists, expect_success, do_write) + +int main(int argc, char* argv[]) { + if (argc < 2) + fatal_error("Usage: %s \n", argv[0]); + + setup(); + + // doesn't exist - should create + OPEN_TEST(argv[1], O_CREAT|O_EXCL|O_RDWR, /*exists=*/false, /*expect_success=*/true, + /*do_write=*/true); + + // exists - open should fail + OPEN_TEST(argv[1], O_CREAT|O_EXCL|O_RDWR, /*exists=*/true, /*expect_success=*/false, + /*do_write=*/false); + + // exists - should open existing and NOT truncate + OPEN_TEST(argv[1], O_CREAT|O_RDWR, /*exists=*/true, /*expect_success=*/true, + /*do_write=*/false); + if (get_file_size(argv[1]) != 1) + fatal_error("File was truncated\n"); + + if (unlink(argv[1]) < 0) + fatal_error("unlink(%s) failed: %s\n", argv[1], strerror(errno)); + + // doesn't exist - should create new + OPEN_TEST(argv[1], O_CREAT|O_RDWR, /*exists=*/false, /*expect_success=*/true, + /*do_write=*/false); + + if (unlink(argv[1]) < 0) + fatal_error("unlink(%s) failed: %s\n", argv[1], strerror(errno)); + + // doesn't exist - should create new + OPEN_TEST(argv[1], O_CREAT|O_TRUNC|O_RDWR, /*exists=*/false, /*expect_success=*/true, + /*do_write=*/true); + + // exists - should truncate + OPEN_TEST(argv[1], O_CREAT|O_TRUNC|O_RDWR, /*exists=*/true, /*expect_success=*/true, + /*do_write=*/false); + if (get_file_size(argv[1]) != 0) + fatal_error("File was not truncated\n"); + + if (unlink(argv[1]) < 0) + fatal_error("unlink(%s) failed: %s\n", argv[1], strerror(errno)); + + return 0; +} diff --git a/LibOS/shim/test/fs/test_fs.py b/LibOS/shim/test/fs/test_fs.py index 6a363422..de25f9e1 100644 --- a/LibOS/shim/test/fs/test_fs.py +++ b/LibOS/shim/test/fs/test_fs.py @@ -79,6 +79,20 @@ class TC_00_FileSystem(RegressionTestCase): stdout, stderr = self.run_binary(['open_close', input_path, output_path]) self.verify_open_close(stdout, stderr, input_path, output_path) + def verify_open_flags(self, stdout, stderr): + self.assertNotIn('ERROR: ', stderr) + self.assertIn('open(O_CREAT|O_EXCL|O_RDWR) [doesn\'t exist] succeeded as expected', stdout) + self.assertIn('open(O_CREAT|O_EXCL|O_RDWR) [exists] failed as expected', stdout) + self.assertIn('open(O_CREAT|O_RDWR) [exists] succeeded as expected', stdout) + self.assertIn('open(O_CREAT|O_RDWR) [doesn\'t exist] succeeded as expected', stdout) + self.assertIn('open(O_CREAT|O_TRUNC|O_RDWR) [doesn\'t exist] succeeded as expected', stdout) + self.assertIn('open(O_CREAT|O_TRUNC|O_RDWR) [exists] succeeded as expected', stdout) + + def test_101_open_flags(self): + file_path = os.path.join(self.OUTPUT_DIR, 'test_101') # new file to be created + stdout, stderr = self.run_binary(['open_flags', file_path]) + self.verify_open_flags(stdout, stderr) + def test_110_read_write(self): file_path = os.path.join(self.OUTPUT_DIR, 'test_110') # new file to be created stdout, stderr = self.run_binary(['read_write', file_path])