occlum/test/mkdir/main.c
2022-08-15 09:21:52 +08:00

223 lines
5.6 KiB
C

#include <sys/stat.h>
#include <sys/syscall.h>
#include <errno.h>
#include <fcntl.h>
#include "test_fs.h"
// ============================================================================
// Helper function
// ============================================================================
static int create_dir(const char *dir_path) {
int ret;
ret = mkdir(dir_path, 00775);
if (ret < 0) {
THROW_ERROR("failed to create the dir");
}
return 0;
}
static int remove_dir(const char *dir_path) {
int ret;
ret = rmdir(dir_path);
if (ret < 0) {
THROW_ERROR("failed to remove the created dir");
}
return 0;
}
// ============================================================================
// Test cases for mkdir
// ============================================================================
static int __test_mkdir(const char *dir_path) {
struct stat stat_buf;
mode_t mode = 00775;
if (mkdir(dir_path, mode) < 0) {
THROW_ERROR("failed to mkdir");
}
if (stat(dir_path, &stat_buf) < 0) {
THROW_ERROR("failed to stat dir");
}
if (!S_ISDIR(stat_buf.st_mode)) {
THROW_ERROR("failed to check if it is dir");
}
return 0;
}
static int __test_mkdir_with_suffix(const char *dir_path) {
struct stat stat_buf;
char new_dir_path[PATH_MAX] = { 0 };
snprintf(new_dir_path, sizeof(new_dir_path), "%s/", dir_path);
mode_t mode = 00775;
if (mkdir(new_dir_path, mode) < 0) {
THROW_ERROR("failed to mkdir");
}
if (stat(new_dir_path, &stat_buf) < 0) {
THROW_ERROR("failed to stat dir");
}
if (!S_ISDIR(stat_buf.st_mode)) {
THROW_ERROR("failed to check if it is dir");
}
return 0;
}
static int __test_mkdirat(const char *dir_path) {
struct stat stat_buf;
mode_t mode = 00775;
char dir_buf[PATH_MAX] = { 0 };
char base_buf[PATH_MAX] = { 0 };
char *dir_name, *last_name;
int dirfd;
if (fs_split_path(dir_path, dir_buf, &dir_name, base_buf, &last_name) < 0) {
THROW_ERROR("failed to split path");
}
dirfd = open(dir_name, O_RDONLY);
if (dirfd < 0) {
THROW_ERROR("failed to open dir");
}
if (mkdirat(dirfd, last_name, mode) < 0) {
THROW_ERROR("failed to mkdirat dir with dirfd");
}
close(dirfd);
if (stat(dir_path, &stat_buf) < 0) {
THROW_ERROR("failed to stat dir");
}
if (!S_ISDIR(stat_buf.st_mode)) {
THROW_ERROR("failed to check if it is dir");
}
return 0;
}
typedef int(*test_mkdir_func_t)(const char *);
static int test_mkdir_framework(test_mkdir_func_t fn) {
const char *dir_path = "/root/test_filesystem_mkdir";
if (fn(dir_path) < 0) {
return -1;
}
if (remove_dir(dir_path) < 0) {
return -1;
}
return 0;
}
static int test_mkdir() {
return test_mkdir_framework(__test_mkdir);
}
static int test_mkdir_with_suffix() {
return test_mkdir_framework(__test_mkdir_with_suffix);
}
static int test_mkdirat() {
return test_mkdir_framework(__test_mkdirat);
}
// ============================================================================
// Test cases for chdir
// ============================================================================
static int __test_chdir(const char *dir_path) {
char buf[128] = { 0 };
char *cwd;
if (chdir(dir_path) < 0) {
THROW_ERROR("failed to chdir");
}
cwd = getcwd(buf, sizeof(buf));
if (cwd != buf) {
THROW_ERROR("failed to getcwd");
}
if (strcmp(buf, dir_path)) {
THROW_ERROR("the cwd is incorrect after chdir");
}
// Check getcwd via explicit syscall
int ret = syscall(__NR_getcwd, buf, sizeof(buf));
if (ret < 0) {
THROW_ERROR("failed to call via explicit syscall");
}
if (ret != strlen(dir_path) + 1) {
THROW_ERROR("failed to check the return value from kernel");
}
return 0;
}
static int test_chdir_framework(test_mkdir_func_t fn) {
const char *dir_path = "/root/test_filesystem_chdir";
if (create_dir(dir_path) < 0) {
return -1;
}
if (fn(dir_path) < 0) {
return -1;
}
if (remove_dir(dir_path) < 0) {
return -1;
}
return 0;
}
static int test_chdir() {
return test_chdir_framework(__test_chdir);
}
// ============================================================================
// Test cases for rmdir
// ============================================================================
static int __test_rmdir_via_unlinkat(const char *dir_path) {
struct stat stat_buf;
int ret;
if (unlinkat(AT_FDCWD, dir_path, AT_REMOVEDIR) < 0) {
THROW_ERROR("failed to remove dir");
}
ret = stat(dir_path, &stat_buf);
if (!(ret < 0 && errno == ENOENT)) {
THROW_ERROR("stat on \"%s\" should return ENOENT", dir_path);
}
return 0;
}
static int test_rmdir_framework(test_mkdir_func_t fn) {
const char *dir_path = "/root/test_filesystem_rmdir";
if (create_dir(dir_path) < 0) {
return -1;
}
if (fn(dir_path) < 0) {
return -1;
}
return 0;
}
static int test_rmdir_via_unlinkat() {
return test_rmdir_framework(__test_rmdir_via_unlinkat);
}
// ============================================================================
// Test suite main
// ============================================================================
static test_case_t test_cases[] = {
TEST_CASE(test_mkdir),
TEST_CASE(test_mkdir_with_suffix),
TEST_CASE(test_mkdirat),
TEST_CASE(test_chdir),
TEST_CASE(test_rmdir_via_unlinkat),
};
int main(int argc, const char *argv[]) {
return test_suite_run(test_cases, ARRAY_SIZE(test_cases));
}