| 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 24a0fd10c2de818d047e11785d567427e7f38af4..45f3f5f8cc27983c79638bbcd0ee45ddccc6ff7e 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
|
| @@ -28,6 +28,7 @@
|
| #include "nacl_io/ostime.h"
|
| #include "nacl_io/path.h"
|
| #include "nacl_io/typed_fs_factory.h"
|
| +#include "ppapi_simple/ps.h"
|
|
|
| using namespace nacl_io;
|
| using namespace sdk_util;
|
| @@ -74,6 +75,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);
|
| @@ -82,12 +85,69 @@ static int ki_fcntl_wrapper(int fd, int request, ...) {
|
| return rtn;
|
| }
|
|
|
| -/**
|
| - * Test for fcntl commands F_SETFD and F_GETFD. This
|
| - * is tested here rather than in the mount_node tests
|
| - * since the fd flags are not stored in the kernel_handle
|
| - * or the filesystem node but directly in the FD mapping.
|
| - */
|
| +// 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;
|
| +}
|
| +
|
| +// Helper to verify directory contents using ki_getdents.
|
| +// Verified that each of the 'count' elements in the 'expected' array
|
| +// are present in the directory and that no other entries are present.
|
| +// If count is -1 then no checking is done and enties are printed using
|
| +// printf.
|
| +static void CheckDirContents(const char* dirname, const char** expected,
|
| + int count) {
|
| + int dir = ki_open(dirname, O_RDONLY, 0);
|
| + ASSERT_GE(dir, 0);
|
| + while (1) {
|
| + size_t sz = sizeof(struct dirent) * 10;
|
| + char* buf = (char*)alloca(sz);
|
| + int rtn = ki_getdents(dir, (struct dirent*)buf, sz);
|
| + if (rtn <= 0)
|
| + break;
|
| + int offset = 0;
|
| + while (offset < rtn) {
|
| + struct dirent* entry = (struct dirent*)(buf + offset);
|
| + offset += entry->d_reclen;
|
| + if (count == -1) {
|
| + nacl_io_log("directory entry: %s\n", entry->d_name);
|
| + continue;
|
| + }
|
| + int j;
|
| + for (j = 0; j < count; j++) {
|
| + if (expected[j] && strcmp(expected[j], entry->d_name) == 0) {
|
| + expected[j] = NULL;
|
| + break;
|
| + }
|
| + }
|
| + if (j == 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
|
| +// since the fd flags are not stored in the kernel_handle
|
| +// or the filesystem node but directly in the FD mapping.
|
| TEST_F(KernelProxyTest, Fcntl_GETFD) {
|
| int fd = ki_open("/test", O_RDWR | O_CREAT, 0777);
|
| ASSERT_NE(-1, fd);
|
| @@ -121,7 +181,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);
|
| @@ -237,7 +297,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
|
| @@ -287,6 +347,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));
|
| + 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];
|
|
|
| @@ -298,26 +383,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);
|
| @@ -328,7 +414,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)));
|
| @@ -343,6 +429,15 @@ TEST_F(KernelProxyTest, FDPathMapping) {
|
| EXPECT_STREQ("/foo/bar", text);
|
| }
|
|
|
| +TEST_F(KernelProxyTest, Getdents) {
|
| + const char* expected[] = { "..", "." };
|
| + CheckDirContents("/", expected, 2);
|
| +
|
| + ASSERT_GE(ki_open("/foo", O_RDWR | O_CREAT, 0777), 0);
|
| + const char* expected1[] = { "foo", "..", "." };
|
| + CheckDirContents("/", expected1, 3);
|
| +}
|
| +
|
| TEST_F(KernelProxyTest, BasicReadWrite) {
|
| char text[1024];
|
| int fd1, fd2, fd3;
|
| @@ -465,7 +560,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));
|
| @@ -485,12 +580,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));
|
| @@ -498,7 +593,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);
|
| @@ -583,7 +678,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);
|
| @@ -600,7 +695,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_IRUSR | S_IWUSR));
|
|
|
| struct stat buf;
|
| @@ -666,7 +761,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));
|
| @@ -677,7 +772,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));
|
| @@ -686,12 +781,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));
|
| @@ -706,7 +801,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.
|
| @@ -745,7 +840,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.
|
| @@ -780,7 +875,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));
|
| @@ -852,39 +947,48 @@ 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"]);
|
| +
|
| +}
|
| +
|
| +// Disabled since open("/") doesn't currently work with the windows
|
| +// version of sel_ldr.
|
| +// TODO(sbc): Re-enable once this change lands:
|
| +// https://codereview.chromium.org/1356583002
|
| +TEST_F(KernelProxyMountTest, DISABLED_Passthroughfs) {
|
| + if (PSGetInstanceId()) {
|
| + /* Passthrough FS is not available under chrome */
|
| + return;
|
| + }
|
| + ASSERT_EQ(0, ki_mkdir("/passthrough", 0777));
|
| + int res1 = ki_mount("", "/passthrough", "passthroughfs", 0, "");
|
| + EXPECT_NE(-1, res1);
|
| + CheckDirContents("/passthrough", NULL, -1);
|
| }
|
|
|
| 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);
|
| @@ -897,7 +1001,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);
|
| @@ -911,7 +1015,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);
|
| }
|
| @@ -1002,9 +1107,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);
|
| @@ -1068,7 +1173,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));
|
| }
|
|
|