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)); |
} |