Loading src/daemon/backend/metadata/rocksdb_backend.cpp +3 −1 Changes for src/daemon/backend/metadata/rocksdb_backend.cpp: 3 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -798,7 +798,9 @@ RocksDBBackend::get_dirents_filtered_impl( scanned_count++; bool matched = !S_ISDIR(mode); if(use_regex && !std::regex_search(std::string(rel_name), name_regex)) { // Preserve 0.9.6 whole-path matching. Substring regex_search with // wildcard filters such as .*01.* retries nonmatching path suffixes. if(use_regex && !std::regex_match(std::string(rel_name), name_regex)) { matched = false; } if(matched && filter_size != -1 && size != (size_t) filter_size) { Loading tests/integration/directories/test_sfind_filtered.py +14 −11 Changes for tests/integration/directories/test_sfind_filtered.py: 14 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -68,12 +68,12 @@ def test_sfind_filtered(test_workspace, request, monkeypatch, buffer_size, ret = io_client.create_n_files(str(nested_dir), 10) assert ret.retval == 0 # Search for "file_5" in the scoped subdir (should be file_5) # Server filters match the entire relative path, including subdirs. log.info( f"Running recursive sfind command: {sfind_bin} {test_dir} " "-regex \"(^|/)file_5$\" ...") "-regex \"(^|.*/)file_5$\" ...") # Should find file_5 in top dir AND file_5 in subdir ret = shell.run(str(sfind_bin), str(test_dir), "-regex", "(^|/)file_5$", ret = shell.run(str(sfind_bin), str(test_dir), "-regex", "(^|.*/)file_5$", "-M", str(mount_dir), "-S", "1", "--server-side") sfind_stdout = ret.stdout.decode(errors='replace') if ret.stdout else "" Loading @@ -86,14 +86,18 @@ def test_sfind_filtered(test_workspace, request, monkeypatch, buffer_size, # Matches: 2 assert "MATCHED 2/111" in sfind_stdout # Both implementations must scan descendants, exclude directories # from matches, and report exact counts regardless of buffer size. # Both implementations scan descendants and exclude directories. # Server-side filters retain 0.9.6 whole-path matching, whereas the # client-side implementation uses substring matching. for server_side in (False, True): for count_only in (False, True): for pattern, expected in (("*file_5", 12), ("file_5", 12), ("*", 110), ("missing", 0)): for pattern, server_expected, client_expected in ( ("*file_5", 2, 12), ("file_5", 1, 12), ("*file_5*", 12, 12), ("*", 110, 110), ("missing", 0, 0)): expected = server_expected if server_side else client_expected flags = [] if server_side: flags.append("--server-side") Loading @@ -110,8 +114,7 @@ def test_sfind_filtered(test_workspace, request, monkeypatch, buffer_size, if server_side and not count_only and pattern == "*file_5": paths = {line for line in stdout.splitlines() if line.startswith(str(test_dir) + "/")} assert paths == {str(test_dir / ("file_%d" % i)) for i in [5] + list(range(50, 60))} | { assert paths == {str(test_dir / "file_5"), str(nested_dir / "file_5")} # Failed RPCs must not be presented as a successful empty scan. Loading Loading
src/daemon/backend/metadata/rocksdb_backend.cpp +3 −1 Changes for src/daemon/backend/metadata/rocksdb_backend.cpp: 3 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -798,7 +798,9 @@ RocksDBBackend::get_dirents_filtered_impl( scanned_count++; bool matched = !S_ISDIR(mode); if(use_regex && !std::regex_search(std::string(rel_name), name_regex)) { // Preserve 0.9.6 whole-path matching. Substring regex_search with // wildcard filters such as .*01.* retries nonmatching path suffixes. if(use_regex && !std::regex_match(std::string(rel_name), name_regex)) { matched = false; } if(matched && filter_size != -1 && size != (size_t) filter_size) { Loading
tests/integration/directories/test_sfind_filtered.py +14 −11 Changes for tests/integration/directories/test_sfind_filtered.py: 14 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -68,12 +68,12 @@ def test_sfind_filtered(test_workspace, request, monkeypatch, buffer_size, ret = io_client.create_n_files(str(nested_dir), 10) assert ret.retval == 0 # Search for "file_5" in the scoped subdir (should be file_5) # Server filters match the entire relative path, including subdirs. log.info( f"Running recursive sfind command: {sfind_bin} {test_dir} " "-regex \"(^|/)file_5$\" ...") "-regex \"(^|.*/)file_5$\" ...") # Should find file_5 in top dir AND file_5 in subdir ret = shell.run(str(sfind_bin), str(test_dir), "-regex", "(^|/)file_5$", ret = shell.run(str(sfind_bin), str(test_dir), "-regex", "(^|.*/)file_5$", "-M", str(mount_dir), "-S", "1", "--server-side") sfind_stdout = ret.stdout.decode(errors='replace') if ret.stdout else "" Loading @@ -86,14 +86,18 @@ def test_sfind_filtered(test_workspace, request, monkeypatch, buffer_size, # Matches: 2 assert "MATCHED 2/111" in sfind_stdout # Both implementations must scan descendants, exclude directories # from matches, and report exact counts regardless of buffer size. # Both implementations scan descendants and exclude directories. # Server-side filters retain 0.9.6 whole-path matching, whereas the # client-side implementation uses substring matching. for server_side in (False, True): for count_only in (False, True): for pattern, expected in (("*file_5", 12), ("file_5", 12), ("*", 110), ("missing", 0)): for pattern, server_expected, client_expected in ( ("*file_5", 2, 12), ("file_5", 1, 12), ("*file_5*", 12, 12), ("*", 110, 110), ("missing", 0, 0)): expected = server_expected if server_side else client_expected flags = [] if server_side: flags.append("--server-side") Loading @@ -110,8 +114,7 @@ def test_sfind_filtered(test_workspace, request, monkeypatch, buffer_size, if server_side and not count_only and pattern == "*file_5": paths = {line for line in stdout.splitlines() if line.startswith(str(test_dir) + "/")} assert paths == {str(test_dir / ("file_%d" % i)) for i in [5] + list(range(50, 60))} | { assert paths == {str(test_dir / "file_5"), str(nested_dir / "file_5")} # Failed RPCs must not be presented as a successful empty scan. Loading