Skip to content

Commit

Permalink
[EROFS] test: enhanced testing for same-name file or dir
Browse files Browse the repository at this point in the history
Add tests for cases where file and directory have the same name.

Signed-off-by: Hongzhen Luo <hongzhen@linux.alibaba.com>
  • Loading branch information
salvete committed Dec 16, 2024
1 parent fa5d2fb commit 3752124
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 28 deletions.
50 changes: 48 additions & 2 deletions src/overlaybd/tar/erofs/test/erofs_stress_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,57 @@ static bool is_substring(const std::string& str, const std::string& substring) {
return str.find(substring) != std::string::npos;
}

static bool str_n_equal(std::string s1, std::string s2, long unsigned int n) {
if (s1.length() < n || s2.length() < n)
return false;
return s1.substr(0, n) == s2.substr(0, n);
}

bool StressFsTree::add_node(StressNode *node) {
if (!node || !node->path.size() || node->type >= NODE_TYPE_MAX)
LOG_ERRNO_RETURN(-1, false, "invalid node");

if (node->type != NODE_WHITEOUT) {
/* the upper regular file should remove the lower dir */
std::map<std::string, StressNode*>::iterator dir_it;
if (node->type == NODE_REGULAR && (dir_it = tree.find(node->path)) != tree.end() &&
dir_it->second->type == NODE_DIR)
{
tree.erase(dir_it);
std::string rm_prefix = node->path + "/";
for (auto it = tree.begin(); it != tree.end(); ) {
if (str_n_equal(rm_prefix, it->first, rm_prefix.length())) {
it = tree.erase(it);
} else {
++it;
}

}
}
tree[node->path] = node;
} else {
auto it = tree.find(node->path);
if (it == tree.end() || it->second->type == NODE_WHITEOUT)
LOG_ERROR_RETURN(-1, false, "whiteout a invalid object");
if (it->second->type == NODE_REGULAR)
tree.erase(it);
else {
std::string prefix = it->first;
for (auto p = tree.begin(); p != tree.end();) {
if (prefix.compare(0, prefix.size(), p->first) == 0)
p = tree.erase(p);
else
p ++;
}
}
}
return true;
}

std::string StressFsTree::get_same_name(int idx, int depth, std::string root_path, NODE_TYPE type) {
std::vector<std::string> vec;
for (const auto& pair : tree) {
if (pair.first == "/" || pair.second->type != type ||
!is_substring(pair.first, root_path) ||
if (pair.first == "/" || !is_substring(pair.first, root_path) ||
pair.first.length() == root_path.length())
continue;
std::string last_component = pair.first.substr(root_path.length() + 1);
Expand Down
33 changes: 7 additions & 26 deletions src/overlaybd/tar/erofs/test/erofs_stress_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,36 +166,17 @@ class StressFsTree {
}

// build process
bool add_node(StressNode *node) {
if (!node || !node->path.size() || node->type >= NODE_TYPE_MAX)
LOG_ERRNO_RETURN(-1, false, "invalid node");

if (node->type != NODE_WHITEOUT) {
tree[node->path] = node;
} else {
auto it = tree.find(node->path);
if (it == tree.end() || it->second->type == NODE_WHITEOUT)
LOG_ERROR_RETURN(-1, false, "whiteout a invalid object");
if (it->second->type == NODE_REGULAR)
tree.erase(it);
else {
std::string prefix = it->first;
for (auto p = tree.begin(); p != tree.end();) {
if (prefix.compare(0, prefix.size(), p->first) == 0)
p = tree.erase(p);
else
p ++;
}
}
}
return true;
}
bool add_node(StressNode *node);

// verify process
bool query_delete_node(StressNode *node) {
auto it = tree.find(node->path);
if (it == tree.end() || !it->second || !it->second->equal(node))
return false;
if (it == tree.end())
LOG_ERROR_RETURN(-1,false, "path ` does not exist in in-mem tree", node->path);
if (!it->second)
LOG_ERROR_RETURN(-1, false, "NULL in-mem info (`)", node->path);
if (!it->second->equal(node))
LOG_ERROR_RETURN(-1, false, "node contents mismatch");
tree.erase(it);
return true;
}
Expand Down

0 comments on commit 3752124

Please sign in to comment.