Loading tests/integration/directories/test_sfind_diagnostic.pydeleted 100644 → 0 +0 −147 Changes for tests/integration/directories/test_sfind_diagnostic.py: 0 added lines, 147 removed lines. Original line number Diff line number Diff line import logging import os import time from pathlib import Path import pytest from harness.gkfs import Client, Daemon, ShellClient, find_command log = logging.getLogger(__name__) SFIND_DIAG_TIMEOUT = 180 def _read_text(path, limit=12000): try: data = Path(path).read_text(errors="replace") except OSError as exc: return f"<could not read {path}: {exc}>" if len(data) <= limit: return data return data[-limit:] def _collect_workspace_logs(test_workspace): chunks = [] for base in (test_workspace.logdir, test_workspace.twd): if not Path(base).exists(): continue for path in sorted(Path(base).glob("**/*")): if path.is_file() and path.suffix in (".log", ".txt"): chunks.append(f"\n--- {path} ---\n{_read_text(path)}") return "".join(chunks) if chunks else "<no workspace logs found>" def _sfind_env(conf, buff_size, iteration): return { "GKFS_USE_DIRENTS_COMPRESSION": conf["compress"], "LIBGKFS_DENTRY_CACHE": conf["cache"], "LIBGKFS_DIRENTS_BUFF_SIZE": str(buff_size), "LIBGKFS_LOG": "debug", "LIBGKFS_LOG_PER_PROCESS": "ON", "MALLOC_CHECK_": "3", "MALLOC_PERTURB_": str(1 + (iteration % 254)), "SFIND_NUM_THREADS": str(conf["threads"]), } @pytest.mark.parametrize("buff_size", ["4096", "5242880"]) @pytest.mark.parametrize("conf", [ {"compress": "OFF", "cache": "OFF", "threads": 1}, {"compress": "ON", "cache": "OFF", "threads": 1}, {"compress": "OFF", "cache": "ON", "threads": 1}, {"compress": "ON", "cache": "ON", "threads": 1}, {"compress": "OFF", "cache": "OFF", "threads": 20}, {"compress": "ON", "cache": "ON", "threads": 20}, ]) def test_sfind_repeated_teardown_diagnostic(test_workspace, request, conf, buff_size): """Stress sfind until the random SIGSEGV is reproducible with logs. The observed failure exits with -11 after printing MATCHED 2000/2000, so this diagnostic repeats only the sfind phase and records whether the crash depends on compression, dentry cache, buffer size, or sfind thread count. """ repetitions = int(os.environ.get("GKFS_SFIND_DIAG_REPETITIONS", "25")) file_count = int(os.environ.get("GKFS_SFIND_DIAG_FILES", "2000")) populate_daemon = Daemon( request.config.getoption("--interface"), "rocksdb", test_workspace, env={ "GKFS_DAEMON_LOG_LEVEL": "debug", "GKFS_USE_DIRENTS_COMPRESSION": "OFF", }) populate_daemon.run() mount_dir = test_workspace.mountdir test_dir = mount_dir / "sfind_diagnostic_dir" io_client = Client(test_workspace) try: ret = io_client.mkdir(str(test_dir), 0o755) assert ret.retval == 0, f"mkdir failed: errno={ret.errno}" ret = io_client.create_n_files( str(test_dir), file_count, env={ "GKFS_USE_DIRENTS_COMPRESSION": "OFF", "LIBGKFS_DENTRY_CACHE": "OFF", "LIBGKFS_LOG": "debug", "LIBGKFS_LOG_PER_PROCESS": "ON", }) assert ret.retval == 0, f"population failed: errno={ret.errno}" assert ret.files_created == file_count finally: populate_daemon.shutdown() time.sleep(1) test_daemon = Daemon( request.config.getoption("--interface"), "rocksdb", test_workspace, env={ "GKFS_DAEMON_LOG_LEVEL": "debug", "GKFS_USE_DIRENTS_COMPRESSION": conf["compress"], }) test_daemon.run() sfind_bin = find_command("sfind", test_workspace.bindirs) assert sfind_bin, "sfind binary not found" try: shell = ShellClient(test_workspace) failures = [] for iteration in range(repetitions): env = _sfind_env(conf, buff_size, iteration) ret = shell.run( str(sfind_bin), str(test_dir), "-S", "1", "-M", str(mount_dir), timeout=SFIND_DIAG_TIMEOUT, env=env) stdout = ret.stdout.decode(errors="replace") if ret.stdout else "" stderr = ret.stderr.decode(errors="replace") if ret.stderr else "" log.info( "sfind diagnostic iteration=%s conf=%s buff_size=%s exit=%s\n" "stdout:\n%s\nstderr:\n%s", iteration, conf, buff_size, ret.exit_code, stdout, stderr) if ret.exit_code != 0 or f"MATCHED {file_count}/{file_count}" not in stdout: failures.append((iteration, ret.exit_code, stdout, stderr)) if ret.exit_code == -11: break if failures: iteration, exit_code, stdout, stderr = failures[0] pytest.fail( "sfind diagnostic reproduced failure\n" f"iteration: {iteration}\n" f"conf: {conf}\n" f"buff_size: {buff_size}\n" f"exit_code: {exit_code}\n" f"stdout:\n{stdout}\n" f"stderr:\n{stderr}\n" f"workspace logs:\n{_collect_workspace_logs(test_workspace)}") finally: test_daemon.shutdown() No newline at end of file Loading
tests/integration/directories/test_sfind_diagnostic.pydeleted 100644 → 0 +0 −147 Changes for tests/integration/directories/test_sfind_diagnostic.py: 0 added lines, 147 removed lines. Original line number Diff line number Diff line import logging import os import time from pathlib import Path import pytest from harness.gkfs import Client, Daemon, ShellClient, find_command log = logging.getLogger(__name__) SFIND_DIAG_TIMEOUT = 180 def _read_text(path, limit=12000): try: data = Path(path).read_text(errors="replace") except OSError as exc: return f"<could not read {path}: {exc}>" if len(data) <= limit: return data return data[-limit:] def _collect_workspace_logs(test_workspace): chunks = [] for base in (test_workspace.logdir, test_workspace.twd): if not Path(base).exists(): continue for path in sorted(Path(base).glob("**/*")): if path.is_file() and path.suffix in (".log", ".txt"): chunks.append(f"\n--- {path} ---\n{_read_text(path)}") return "".join(chunks) if chunks else "<no workspace logs found>" def _sfind_env(conf, buff_size, iteration): return { "GKFS_USE_DIRENTS_COMPRESSION": conf["compress"], "LIBGKFS_DENTRY_CACHE": conf["cache"], "LIBGKFS_DIRENTS_BUFF_SIZE": str(buff_size), "LIBGKFS_LOG": "debug", "LIBGKFS_LOG_PER_PROCESS": "ON", "MALLOC_CHECK_": "3", "MALLOC_PERTURB_": str(1 + (iteration % 254)), "SFIND_NUM_THREADS": str(conf["threads"]), } @pytest.mark.parametrize("buff_size", ["4096", "5242880"]) @pytest.mark.parametrize("conf", [ {"compress": "OFF", "cache": "OFF", "threads": 1}, {"compress": "ON", "cache": "OFF", "threads": 1}, {"compress": "OFF", "cache": "ON", "threads": 1}, {"compress": "ON", "cache": "ON", "threads": 1}, {"compress": "OFF", "cache": "OFF", "threads": 20}, {"compress": "ON", "cache": "ON", "threads": 20}, ]) def test_sfind_repeated_teardown_diagnostic(test_workspace, request, conf, buff_size): """Stress sfind until the random SIGSEGV is reproducible with logs. The observed failure exits with -11 after printing MATCHED 2000/2000, so this diagnostic repeats only the sfind phase and records whether the crash depends on compression, dentry cache, buffer size, or sfind thread count. """ repetitions = int(os.environ.get("GKFS_SFIND_DIAG_REPETITIONS", "25")) file_count = int(os.environ.get("GKFS_SFIND_DIAG_FILES", "2000")) populate_daemon = Daemon( request.config.getoption("--interface"), "rocksdb", test_workspace, env={ "GKFS_DAEMON_LOG_LEVEL": "debug", "GKFS_USE_DIRENTS_COMPRESSION": "OFF", }) populate_daemon.run() mount_dir = test_workspace.mountdir test_dir = mount_dir / "sfind_diagnostic_dir" io_client = Client(test_workspace) try: ret = io_client.mkdir(str(test_dir), 0o755) assert ret.retval == 0, f"mkdir failed: errno={ret.errno}" ret = io_client.create_n_files( str(test_dir), file_count, env={ "GKFS_USE_DIRENTS_COMPRESSION": "OFF", "LIBGKFS_DENTRY_CACHE": "OFF", "LIBGKFS_LOG": "debug", "LIBGKFS_LOG_PER_PROCESS": "ON", }) assert ret.retval == 0, f"population failed: errno={ret.errno}" assert ret.files_created == file_count finally: populate_daemon.shutdown() time.sleep(1) test_daemon = Daemon( request.config.getoption("--interface"), "rocksdb", test_workspace, env={ "GKFS_DAEMON_LOG_LEVEL": "debug", "GKFS_USE_DIRENTS_COMPRESSION": conf["compress"], }) test_daemon.run() sfind_bin = find_command("sfind", test_workspace.bindirs) assert sfind_bin, "sfind binary not found" try: shell = ShellClient(test_workspace) failures = [] for iteration in range(repetitions): env = _sfind_env(conf, buff_size, iteration) ret = shell.run( str(sfind_bin), str(test_dir), "-S", "1", "-M", str(mount_dir), timeout=SFIND_DIAG_TIMEOUT, env=env) stdout = ret.stdout.decode(errors="replace") if ret.stdout else "" stderr = ret.stderr.decode(errors="replace") if ret.stderr else "" log.info( "sfind diagnostic iteration=%s conf=%s buff_size=%s exit=%s\n" "stdout:\n%s\nstderr:\n%s", iteration, conf, buff_size, ret.exit_code, stdout, stderr) if ret.exit_code != 0 or f"MATCHED {file_count}/{file_count}" not in stdout: failures.append((iteration, ret.exit_code, stdout, stderr)) if ret.exit_code == -11: break if failures: iteration, exit_code, stdout, stderr = failures[0] pytest.fail( "sfind diagnostic reproduced failure\n" f"iteration: {iteration}\n" f"conf: {conf}\n" f"buff_size: {buff_size}\n" f"exit_code: {exit_code}\n" f"stdout:\n{stdout}\n" f"stderr:\n{stderr}\n" f"workspace logs:\n{_collect_workspace_logs(test_workspace)}") finally: test_daemon.shutdown() No newline at end of file