Chromium Code Reviews| Index: native_client_sdk/src/tests/nacl_io_test/kernel_proxy_test.cc |
| diff --git a/native_client_sdk/src/tests/nacl_io_test/kernel_proxy_test.cc b/native_client_sdk/src/tests/nacl_io_test/kernel_proxy_test.cc |
| index 62f8c6f5b3719fcec8b0f5cc9a67ebd5a8580b5a..08a966ca802c59276a033cb9cd569df987281e6b 100644 |
| --- a/native_client_sdk/src/tests/nacl_io_test/kernel_proxy_test.cc |
| +++ b/native_client_sdk/src/tests/nacl_io_test/kernel_proxy_test.cc |
| @@ -73,6 +73,8 @@ class KernelProxyTest : public ::testing::Test { |
| } // namespace |
| +// Helper function for calling ki_fcntl without having |
| +// to construct a va_list. |
| static int ki_fcntl_wrapper(int fd, int request, ...) { |
| va_list ap; |
| va_start(ap, request); |
| @@ -81,6 +83,58 @@ static int ki_fcntl_wrapper(int fd, int request, ...) { |
| return rtn; |
| } |
| +// Helper function for calling ki_ioctl without having |
| +// to construct a va_list. |
| +static int ki_ioctl_wrapper(int fd, int request, ...) { |
| + va_list ap; |
| + va_start(ap, request); |
| + int rtn = ki_ioctl(fd, request, ap); |
| + va_end(ap); |
| + return rtn; |
| +} |
| + |
| +static void check_dir_contents(const char* dirname, const char** expected, |
|
binji
2015/01/07 19:14:59
nit: use CamelCase for functions
Sam Clegg
2015/01/08 12:59:07
Done.
|
| + int count) { |
| + int dir = ki_open(dirname, O_RDONLY, 0); |
| + ASSERT_GE(dir, 0); |
| + while (1) { |
| + char buf[512]; |
| + int rtn = ki_getdents(dir, buf, sizeof(buf)); |
| + if (rtn <= 0) |
| + break; |
| + int offset = 0; |
| + while (offset < rtn) { |
| + struct dirent* entry = (struct dirent*)(buf + offset); |
| + printf("entry: %s\n", entry->d_name); |
| + offset += entry->d_reclen; |
| + if (count == -1) |
| + continue; |
| + int i; |
| + for (i = 0; i < count; i++) { |
|
binji
2015/01/07 19:14:59
this code is untested. Best to use it or remove it
Sam Clegg
2015/01/08 12:59:08
Sorry, I meant to add a getdents tests. Done that
|
| + if (expected[i] && strcmp(expected[i], entry->d_name) == 0) { |
| + expected[i] = NULL; |
|
binji
2015/01/07 19:14:59
This is a bit unexpected, probably should be docum
Sam Clegg
2015/01/08 12:59:07
Done.
|
| + break; |
| + } |
| + } |
| + if (i == count) { |
| + FAIL() << "Unexpeected entry '" << entry->d_name |
| + << "' in directory: " << dirname; |
| + } |
| + } |
| + } |
| + |
| + ASSERT_EQ(0, ki_close(dir)); |
| + |
| + if (count != -1) { |
| + for (int i = 0; i < count; i++) { |
| + if (expected[i] != NULL) { |
| + FAIL() << "Expected entry '" << expected[i] |
| + << "' not found in directory: " << dirname; |
| + } |
| + } |
| + } |
| +} |
| + |
| /** |
| * Test for fcntl commands F_SETFD and F_GETFD. This |
| * is tested here rather than in the mount_node tests |
| @@ -120,7 +174,7 @@ TEST_F(KernelProxyTest, FileLeak) { |
| for (int file_num = 0; file_num < 4096; file_num++) { |
| sprintf(filename, "/foo%i.tmp", file_num++); |
| int fd = ki_open(filename, O_WRONLY | O_CREAT, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| ASSERT_EQ(1, root->ChildCount()); |
| ASSERT_EQ(buffer_size, ki_write(fd, garbage, buffer_size)); |
| ki_close(fd); |
| @@ -236,7 +290,7 @@ TEST_F(KernelProxyTest, SignalSigwinch) { |
| TEST_F(KernelProxyTest, Rename) { |
| // Create a dummy file |
| int file1 = ki_open("/test1.txt", O_RDWR | O_CREAT, 0777); |
| - ASSERT_GT(file1, -1); |
| + ASSERT_GE(file1, 0); |
| ASSERT_EQ(0, ki_close(file1)); |
| // Test the renaming works |
| @@ -286,6 +340,31 @@ TEST_F(KernelProxyTest, WorkingDirectory) { |
| EXPECT_STREQ("/foo", text); |
| } |
| +TEST_F(KernelProxyTest, Mkdir) { |
| + ASSERT_EQ(0, ki_mkdir("/foo", S_IREAD | S_IWRITE)); |
| + ASSERT_EQ(-1, ki_mkdir("/foo", S_IREAD | S_IWRITE)); |
| + ASSERT_EQ(EEXIST, errno); |
| + |
| + // Some component of parent directory does not exist |
| + ASSERT_EQ(-1, ki_mkdir("/does_not_exist/foo", S_IREAD | S_IWRITE)); |
|
binji
2015/01/07 19:14:59
is this implemented yet?
Sam Clegg
2015/01/08 12:59:07
At least the parent must exist yes.
|
| + ASSERT_EQ(ENOENT, errno); |
| + |
| + int fd = ki_open("/filename", O_CREAT | O_RDWR, 0777); |
| + ASSERT_GE(fd, 0); |
| + |
| + // Some component of parent directory is not actually a directory |
| + ASSERT_EQ(-1, ki_mkdir("/filename/foo", S_IREAD | S_IWRITE)); |
| + ASSERT_EQ(ENOTDIR, errno); |
| +} |
| + |
| +TEST_F(KernelProxyTest, Rmdir) { |
| + ASSERT_EQ(-1, ki_rmdir("/dev/fs")); |
| + ASSERT_EQ(EPERM, errno); |
| + |
| + ASSERT_EQ(-1, ki_rmdir("/foo")); |
| + ASSERT_EQ(ENOENT, errno); |
| +} |
| + |
| TEST_F(KernelProxyTest, FDPathMapping) { |
| char text[1024]; |
| @@ -297,26 +376,27 @@ TEST_F(KernelProxyTest, FDPathMapping) { |
| ki_chdir("/foo"); |
| fd1 = ki_open("/example", O_RDONLY, 0); |
| - EXPECT_NE(-1, fd1); |
| + ASSERT_GT(fd1, 0); |
| EXPECT_EQ(ki_fchdir(fd1), 0); |
| EXPECT_EQ(text, ki_getcwd(text, sizeof(text))); |
| EXPECT_STREQ("/example", text); |
| EXPECT_EQ(0, ki_chdir("/foo")); |
| fd2 = ki_open("../example", O_RDONLY, 0); |
| - EXPECT_NE(-1, fd2); |
| + ASSERT_GE(fd2, 0); |
| EXPECT_EQ(0, ki_fchdir(fd2)); |
| EXPECT_EQ(text, ki_getcwd(text, sizeof(text))); |
| EXPECT_STREQ("/example", text); |
| EXPECT_EQ(0, ki_chdir("/foo")); |
| fd3 = ki_open("../test", O_CREAT | O_RDWR, 0777); |
| - EXPECT_NE(-1, fd3); |
| + ASSERT_GE(fd3, 0); |
| EXPECT_EQ(-1, ki_fchdir(fd3)); |
| EXPECT_EQ(ENOTDIR, errno); |
| EXPECT_EQ(0, ki_chdir("/foo")); |
| fd4 = ki_open("bar", O_RDONLY, 0); |
| + ASSERT_GE(fd4, 0); |
| EXPECT_EQ(0, ki_fchdir(fd4)); |
| EXPECT_EQ(text, ki_getcwd(text, sizeof(text))); |
| EXPECT_STREQ("/foo/bar", text); |
| @@ -327,7 +407,7 @@ TEST_F(KernelProxyTest, FDPathMapping) { |
| EXPECT_EQ(0, ki_chdir("/example")); |
| fd5 = ki_dup(fd4); |
| - ASSERT_GT(fd5, -1); |
| + ASSERT_GE(fd5, 0); |
| ASSERT_NE(fd4, fd5); |
| EXPECT_EQ(0, ki_fchdir(fd5)); |
| EXPECT_EQ(text, ki_getcwd(text, sizeof(text))); |
| @@ -464,7 +544,7 @@ TEST_F(KernelProxyTest, Truncate) { |
| TEST_F(KernelProxyTest, Lseek) { |
| int fd = ki_open("/foo", O_CREAT | O_RDWR, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| ASSERT_EQ(9, ki_write(fd, "Some text", 9)); |
| ASSERT_EQ(9, ki_lseek(fd, 0, SEEK_CUR)); |
| @@ -484,12 +564,12 @@ TEST_F(KernelProxyTest, Lseek) { |
| TEST_F(KernelProxyTest, CloseTwice) { |
| int fd = ki_open("/foo", O_CREAT | O_RDWR, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| EXPECT_EQ(9, ki_write(fd, "Some text", 9)); |
| int fd2 = ki_dup(fd); |
| - ASSERT_GT(fd2, -1); |
| + ASSERT_GE(fd2, 0); |
| EXPECT_EQ(0, ki_close(fd)); |
| EXPECT_EQ(0, ki_close(fd2)); |
| @@ -497,7 +577,7 @@ TEST_F(KernelProxyTest, CloseTwice) { |
| TEST_F(KernelProxyTest, Dup) { |
| int fd = ki_open("/foo", O_CREAT | O_RDWR, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| int dup_fd = ki_dup(fd); |
| ASSERT_NE(-1, dup_fd); |
| @@ -535,7 +615,7 @@ TEST_F(KernelProxyTest, DescriptorAllocationConsistency) { |
| // The test makes the assumption at all descriptors |
| // open by default are contiguous starting from zero. |
| int fd = ki_open("/foo", O_CREAT | O_RDWR, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| // The next descriptor allocated should follow the first. |
| int dup_fd = ki_dup(fd); |
| @@ -552,7 +632,7 @@ TEST_F(KernelProxyTest, DescriptorAllocationConsistency) { |
| TEST_F(KernelProxyTest, Lstat) { |
| int fd = ki_open("/foo", O_CREAT | O_RDWR, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| ASSERT_EQ(0, ki_mkdir("/bar", S_IREAD | S_IWRITE)); |
| struct stat buf; |
| @@ -618,7 +698,7 @@ TEST_F(KernelProxyTest, Fchmod) { |
| TEST_F(KernelProxyTest, OpenDirectory) { |
| // Opening a directory for read should succeed. |
| int fd = ki_open("/", O_RDONLY, 0); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| // Opening a directory for write should fail. |
| EXPECT_EQ(-1, ki_open("/", O_RDWR, 0)); |
| @@ -629,7 +709,7 @@ TEST_F(KernelProxyTest, OpenDirectory) { |
| TEST_F(KernelProxyTest, OpenWithMode) { |
| int fd = ki_open("/foo", O_CREAT | O_RDWR, 0723); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| struct stat buf; |
| EXPECT_EQ(0, ki_lstat("/foo", &buf)); |
| @@ -638,12 +718,12 @@ TEST_F(KernelProxyTest, OpenWithMode) { |
| TEST_F(KernelProxyTest, CreateWronlyWithReadOnlyMode) { |
| int fd = ki_open("/foo", O_CREAT | O_WRONLY, 0444); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| } |
| TEST_F(KernelProxyTest, UseAfterClose) { |
| int fd = ki_open("/dummy", O_CREAT | O_WRONLY, 0777); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| EXPECT_EQ(5, ki_write(fd, "hello", 5)); |
| EXPECT_EQ(0, ki_close(fd)); |
| EXPECT_EQ(-1, ki_write(fd, "hello", 5)); |
| @@ -658,7 +738,7 @@ TEST_F(KernelProxyTest, Utimes) { |
| times[1].tv_usec = 4000; |
| int fd = ki_open("/dummy", O_CREAT | O_WRONLY, 0222); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| EXPECT_EQ(0, ki_close(fd)); |
| // utime should work if the file is write-only. |
| @@ -697,7 +777,7 @@ TEST_F(KernelProxyTest, Utime) { |
| times.modtime = 2000; |
| int fd = ki_open("/dummy", O_CREAT | O_WRONLY, 0222); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| EXPECT_EQ(0, ki_close(fd)); |
| // utime should work if the file is write-only. |
| @@ -732,7 +812,7 @@ TEST_F(KernelProxyTest, Umask) { |
| EXPECT_EQ(0, oldmask); |
| int fd = ki_open("/foo", O_CREAT | O_RDONLY, 0666); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| ki_close(fd); |
| EXPECT_EQ(0, ki_mkdir("/dir", 0777)); |
| @@ -804,39 +884,40 @@ class KernelProxyMountTest : public ::testing::Test { |
| KernelProxyMountTest_KernelProxy kp_; |
| }; |
| -// Helper function for calling ki_ioctl without having |
| -// to construct a va_list. |
| -int ki_ioctl_wrapper(int fd, int request, ...) { |
| - va_list ap; |
| - va_start(ap, request); |
| - int rtn = ki_ioctl(fd, request, ap); |
| - va_end(ap); |
| - return rtn; |
| -} |
| - |
| } // namespace |
| TEST_F(KernelProxyMountTest, MountInit) { |
| - int res1 = ki_mount("/", "/mnt1", "initfs", 0, "false,foo=bar"); |
| + ASSERT_EQ(0, ki_mkdir("/mnt1", 0777)); |
| + int res1 = ki_mount("", "/mnt1", "initfs", 0, "false,foo=bar"); |
| EXPECT_EQ("bar", g_string_map["foo"]); |
| EXPECT_EQ(-1, res1); |
| EXPECT_EQ(EINVAL, errno); |
| - int res2 = ki_mount("/", "/mnt2", "initfs", 0, "true,bar=foo,x=y"); |
| + ASSERT_EQ(0, ki_mkdir("/mnt2", 0777)); |
| + int res2 = ki_mount("", "/mnt2", "initfs", 0, "true,bar=foo,x=y"); |
| EXPECT_NE(-1, res2); |
| EXPECT_EQ("y", g_string_map["x"]); |
| + |
| +} |
| + |
| +TEST_F(KernelProxyMountTest, Passthroughfs) { |
| + ASSERT_EQ(0, ki_mkdir("/passthrough", 0777)); |
| + int res1 = ki_mount("", "/passthrough", "passthroughfs", 0, ""); |
| + EXPECT_NE(-1, res1); |
| + check_dir_contents("/passthrough", NULL, -1); |
|
binji
2015/01/07 19:14:59
This is a manual test only?
Sam Clegg
2015/01/08 12:59:07
It verified that the directory can be read, nothin
|
| } |
| TEST_F(KernelProxyMountTest, MountAndIoctl) { |
| - ASSERT_EQ(0, ki_mount("/", "/mnt1", "initfs", 0, "")); |
| + ASSERT_EQ(0, ki_mkdir("/mnt1", 0777)); |
| + ASSERT_EQ(0, ki_mount("", "/mnt1", "initfs", 0, "")); |
| ASSERT_NE(-1, g_fs_dev); |
| char path[100]; |
| - snprintf(path, 100, "dev/fs/%d", g_fs_dev); |
| + snprintf(path, 100, "/dev/fs/%d", g_fs_dev); |
| int fd = ki_open(path, O_RDONLY, 0); |
| - ASSERT_GT(fd, -1); |
| + ASSERT_GE(fd, 0); |
| EXPECT_EQ(0, ki_ioctl_wrapper(fd, 0xdeadbeef)); |
| EXPECT_EQ(true, g_fs_ioctl_called); |
| @@ -849,7 +930,7 @@ static void mount_callback(const char* source, |
| const void* data, |
| dev_t dev, |
| void* user_data) { |
| - EXPECT_STREQ("/", source); |
| + EXPECT_STREQ("dummy", source); |
| EXPECT_STREQ("/mnt1", target); |
| EXPECT_STREQ("initfs", filesystemtype); |
| EXPECT_EQ(0, mountflags); |
| @@ -863,7 +944,8 @@ static void mount_callback(const char* source, |
| TEST_F(KernelProxyMountTest, MountCallback) { |
| bool callback_called = false; |
| kp_.SetMountCallback(&mount_callback, &callback_called); |
| - ASSERT_EQ(0, ki_mount("/", "/mnt1", "initfs", 0, "")); |
| + ASSERT_EQ(0, ki_mkdir("/mnt1", 0777)); |
| + ASSERT_EQ(0, ki_mount("dummy", "/mnt1", "initfs", 0, "")); |
| ASSERT_NE(-1, g_fs_dev); |
| EXPECT_EQ(true, callback_called); |
| } |
| @@ -954,9 +1036,9 @@ class KernelProxyMMapTest : public ::testing::Test { |
| } // namespace |
| TEST_F(KernelProxyMMapTest, MMap) { |
| - ASSERT_EQ(0, ki_umount("/")); |
| - ASSERT_EQ(0, ki_mount("", "/", "mmapfs", 0, NULL)); |
| - int fd = ki_open("/file", O_RDWR | O_CREAT, 0777); |
| + ASSERT_EQ(0, ki_mkdir("/mmap", 0777)); |
| + ASSERT_EQ(0, ki_mount("", "/mmap", "mmapfs", 0, NULL)); |
| + int fd = ki_open("/mmap/file", O_RDWR | O_CREAT, 0777); |
| ASSERT_NE(-1, fd); |
| void* addr1 = ki_mmap(NULL, 0x800, PROT_READ, MAP_PRIVATE, fd, 0); |
| @@ -1020,7 +1102,7 @@ class KernelProxyErrorTest : public ::testing::Test { |
| void SetUp() { |
| ASSERT_EQ(0, ki_push_state_for_testing()); |
| ASSERT_EQ(0, ki_init(&kp_)); |
| - // Unmount the passthrough FS and mount a testfs. |
| + // Unmount root fs and mount a testfs. |
| EXPECT_EQ(0, kp_.umount("/")); |
| EXPECT_EQ(0, kp_.mount("", "/", "testfs", 0, NULL)); |
| } |