Skip to content

Commit

Permalink
[EROFS] test: add tests for dirs
Browse files Browse the repository at this point in the history
Signed-off-by: Hongzhen Luo <hongzhen@linux.alibaba.com>
  • Loading branch information
salvete committed Dec 21, 2024
1 parent 0c16fc7 commit c43d8f1
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 23 deletions.
176 changes: 164 additions & 12 deletions src/overlaybd/tar/erofs/test/erofs_stress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,43 @@ class StressInterImpl: public StressGenInter {
name_map[idx].insert(res);
return res;
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
std::string str_mode("755");
mode_t mode;

mode = std::stoi(str_mode, nullptr, 8);
if (host_fs->chmod(path, mode))
LOG_ERROR_RETURN(-1, false, "fail to set mode ` for dir `", str_mode, path);
node->mod = str_mode;
return true;
}

bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
uid_t uid = get_randomint(own_id_min, own_id_max);
gid_t gid = get_randomint(own_id_min, own_id_max);

if (host_fs->chown(path, uid, gid))
LOG_ERROR_RETURN(-1,false, "failt to chown of dir `", path);
node->own = std::to_string(uid) + std::to_string(gid);
return true;
}

bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
photon::fs::IFileSystemXAttr *xattr_ops = dynamic_cast<photon::fs::IFileSystemXAttr*>(host_fs);
if (xattr_ops == nullptr)
LOG_ERROR_RETURN(-1, false, "fs does not suppoert xattrs operations!");
int xattrs_count = get_randomint(xattrs_min_count, xattrs_max_count + 1);
for (int i = 0; i < xattrs_count; i ++) {
int idx = get_randomint(0, xattrs_prefix.size());
std::string key = xattrs_prefix[idx] + get_randomstr(get_randomint(xattrs_min_size, xattrs_max_size), false);
std::string value = get_randomstr(get_randomint(xattrs_min_size, xattrs_max_size), false);
if (xattr_ops->setxattr(path, key.c_str(), value.c_str(), value.size(), 0))
LOG_ERROR_RETURN(-1, -1, "fail to set xattr (key: `, value: `) for dir `", key, value, path);
node->xattrs[key] = value;
}
return true;
}
};

/*
Expand All @@ -221,10 +258,27 @@ class StressCase001: public StressBase, public StressInterImpl {
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_xattrs(StressNode *node, StressHostFile *file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, build_gen_content(StressNode *node, StressHostFile *file), true)

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

/* create empty nodes in verify phase */
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file), true)
bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type ==NODE_DIR ? StressInterImpl::verify_gen_mod(node, erofs_file) : true;
}
bool verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_own(node, erofs_file) : true;
}
bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_xattrs(node, erofs_file): true;
}

EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_content(StressNode *node, photon::fs::IFile *erofs_file), true)

/* simplely generate random dir and file names */
Expand Down Expand Up @@ -266,10 +320,26 @@ class StressCase002: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_content(node, file);
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

/* leave mod/own/xattr empty */
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file), true)
bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type ==NODE_DIR ? StressInterImpl::verify_gen_mod(node, erofs_file) : true;
}
bool verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_own(node, erofs_file) : true;
}
bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_xattrs(node, erofs_file): true;
}
bool verify_gen_content(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_content(node, erofs_file);
}
Expand Down Expand Up @@ -312,9 +382,23 @@ class StressCase003: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_xattrs(node, file);
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

/* leave mod/own/content empty */
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file), true)
bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type ==NODE_DIR ? StressInterImpl::verify_gen_mod(node, erofs_file) : true;
}
bool verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_own(node, erofs_file) : true;
}
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_content(StressNode *node, photon::fs::IFile *erofs_file), true)
bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_xattrs(node, erofs_file);
Expand Down Expand Up @@ -355,12 +439,26 @@ class StressCase004: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_mod(node, file);
}

EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file), true)
bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_content(StressNode *node, photon::fs::IFile *erofs_file), true)
bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_mod(node, erofs_file);
}
bool verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_own(node, erofs_file) : true;
}
bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_xattrs(node, erofs_file): true;
}

/* simplely generate random dir and file names */
std::string generate_name(int idx, int depth, std::string root_path, NODE_TYPE type) override {
Expand Down Expand Up @@ -396,12 +494,26 @@ class StressCase005: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_own(node, file);
}

EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file), true)
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file), true)
bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type ==NODE_DIR ? StressInterImpl::verify_gen_mod(node, erofs_file) : true;
}
EROFS_STRESS_UNIMPLEMENTED_FUNC(bool, verify_gen_content(StressNode *node, photon::fs::IFile *erofs_file), true)
bool verify_gen_own(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_own(node, erofs_file);
}
bool verify_gen_xattrs(StressNode *node, photon::fs::IFile *erofs_file) override {
return node->type == NODE_DIR ? StressInterImpl::verify_gen_xattrs(node, erofs_file): true;
}

/* simplely generate random dir and file names */
std::string generate_name(int idx, int depth, std::string root_path, NODE_TYPE type) override {
Expand Down Expand Up @@ -443,6 +555,16 @@ class StressCase006: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_content(node, file);
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_mod(node, erofs_file);
}
Expand Down Expand Up @@ -498,6 +620,16 @@ class StressCase007: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_content(node, file);
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_mod(node, erofs_file);
}
Expand Down Expand Up @@ -573,6 +705,16 @@ class StressCase008: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_content(node, file);
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_mod(node, erofs_file);
}
Expand Down Expand Up @@ -657,6 +799,16 @@ class StressCase009: public StressBase, public StressInterImpl {
return StressInterImpl::build_gen_content(node, file);
}

bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_mod(node, path, host_fs);
}
bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_own(node, path, host_fs);
}
bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) override {
return StressInterImpl::build_dir_xattrs(node, path, host_fs);
}

bool verify_gen_mod(StressNode *node, photon::fs::IFile *erofs_file) override {
return StressInterImpl::verify_gen_mod(node, erofs_file);
}
Expand Down
37 changes: 27 additions & 10 deletions src/overlaybd/tar/erofs/test/erofs_stress_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ bool StressBase::create_layer(int idx) {
std::string root_dirname = generate_name(idx, layer_tree->depth, "", NODE_DIR);
std::string root_path = prefix + "/" + root_dirname;
std::string clean_cmd = "rm -rf " + root_path;
bool res;

if (system(clean_cmd.c_str()))
LOG_ERROR_RETURN(-1, false, "fail to prepare clean dir for `", root_path);
Expand All @@ -179,11 +180,17 @@ bool StressBase::create_layer(int idx) {
StressNode *node = new StressNode(layer_tree->pwd.substr(prefix.length()), NODE_DIR);
if (host_fs->mkdir(layer_tree->pwd.c_str(), 0755) != 0)
LOG_ERROR_RETURN(-1, false, "fail to mkdir `", layer_tree->pwd);
tree->add_node(node);

res = build_dir_mod(node, layer_tree->pwd.c_str(), host_fs) &&
build_dir_own(node, layer_tree->pwd.c_str(), host_fs) &&
build_dir_xattrs(node, layer_tree->pwd.c_str(), host_fs);
if (!res)
LOG_ERROR_RETURN(-1, false, "fail to generate fields for dir `",layer_tree->pwd);
if (!tree->add_node(node))
LOG_ERROR_RETURN(-1, false, "fail to add node `",layer_tree->pwd);

// traverse the layer tree
while (q.size()) {
bool res;
LayerNode *cur = q.front();
q.erase(q.begin());

Expand Down Expand Up @@ -252,7 +259,14 @@ bool StressBase::create_layer(int idx) {
next->pwd = cur->pwd + "/" + dir_name;
if (host_fs->mkdir(next->pwd.c_str(), 0755) == 0) {
StressNode *dir_node = new StressNode(next->pwd.substr(prefix.length()), NODE_DIR);
tree->add_node(dir_node);

res = build_dir_mod(dir_node, next->pwd.c_str(), host_fs) &&
build_dir_own(dir_node, next->pwd.c_str(), host_fs) &&
build_dir_xattrs(dir_node, next->pwd.c_str(), host_fs);
if (!res)
LOG_ERROR_RETURN(-1, false, "fail to generate fields for dir `", next->pwd);
if (!tree->add_node(dir_node))
LOG_ERROR_RETURN(-1, false, "fail to add node `", next->pwd);
q.emplace_back(next);
break;
}
Expand Down Expand Up @@ -329,7 +343,6 @@ bool StressBase::verify(photon::fs::IFileSystem *erofs_fs) {
if (erofs_fs->stat(cur.c_str(), &st))
LOG_ERRNO_RETURN(-1, false, "fail to stat file `", cur);
if (S_ISDIR(st.st_mode)) {
node = new StressNode(cur, NODE_DIR);
auto dir = erofs_fs->opendir(cur.c_str());
/* the dir may be empty, so check it first */
if (dir->get() != nullptr) {
Expand All @@ -344,31 +357,35 @@ bool StressBase::verify(photon::fs::IFileSystem *erofs_fs) {
}
dir->closedir();
delete dir;
} else if (S_ISREG(st.st_mode)) {
}
node = new StressNode(cur, S_ISREG(st.st_mode) ? NODE_REGULAR : NODE_DIR);

if (!first) {
photon::fs::IFile *file;
bool ret;

file = erofs_fs->open(cur.c_str(), O_RDONLY);
node = new StressNode(cur, NODE_REGULAR);
if (!file || ! node)
LOG_ERROR_RETURN(0, false, "fail to open file or node `", cur);
ret = verify_gen_mod(node, file) &&
verify_gen_own(node, file) &&
verify_gen_xattrs(node, file) &&
verify_gen_content(node, file);
verify_gen_xattrs(node, file);
/* do not generate contents for dirs */
if (S_ISREG(st.st_mode))
ret += verify_gen_content(node, file);
if (!ret)
LOG_ERROR_RETURN(0, false, "fail to construct StressNode");
file->close();
delete file;

}

if (!tree->query_delete_node(node)) {
delete node;
LOG_ERROR_RETURN(-1, false, "file ` in erofs_fs but not in the in-mem tree", cur);
}
first = false;

if (first)
first = false;
} while (!items.empty());

if (!tree->is_emtry())
Expand Down
8 changes: 7 additions & 1 deletion src/overlaybd/tar/erofs/test/erofs_stress_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,13 @@ class StressGenInter {
virtual bool build_gen_own(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0;
virtual bool build_gen_xattrs(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0;
virtual bool build_gen_content(StressNode *node /* out */, StressHostFile *file_info /* out */) = 0;
/* generate in-mem inode according to erofs-fs file */

/* for a single dir (node) */
virtual bool build_dir_mod(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0;
virtual bool build_dir_own(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0;
virtual bool build_dir_xattrs(StressNode *node, const char *path, photon::fs::IFileSystem *host_fs) = 0;

/* generate in-mem inode according to erofs-fs file (for both files and dirs) */
virtual bool verify_gen_mod(StressNode *node /* out */, photon::fs::IFile *erofs_file /* in */) = 0;
virtual bool verify_gen_own(StressNode *node /* out */, photon::fs::IFile *erofs_file /* in */) = 0;
virtual bool verify_gen_xattrs(StressNode *node /* out */, photon::fs::IFile *erofs_file /* in */) = 0;
Expand Down

0 comments on commit c43d8f1

Please sign in to comment.