Forbid test skips and convert existing skips to hard failures
Add scripts/check-no-test-skips.sh (run from lint) which fails the lint phase on any plain SKIP() or direct tf_skip_count manipulation; only SKIP_PLATFORM() (for genuinely platform-specific tests) is tolerated. Add FAIL() and SKIP_PLATFORM() helpers to the test framework and convert the remaining SKIP()/perf-gated skips across the suite into pass-or-fail assertions, so a suite that cannot meet its preconditions reports a red failure instead of a silent skip.
This commit is contained in:
@@ -15,6 +15,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
# Tests must pass or fail — no SKIPs except genuinely platform-specific
|
||||
# ones (SKIP_PLATFORM / #ifdef). Fails the lint phase on any plain SKIP().
|
||||
- name: No-skips policy (tests pass or fail)
|
||||
run: bash scripts/check-no-test-skips.sh
|
||||
|
||||
- name: Install build deps
|
||||
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev cmake
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# check-no-test-skips.sh — Enforce the no-skips test policy in the lint phase.
|
||||
#
|
||||
# Every test must PASS or FAIL. The ONLY tolerable skip is a genuinely
|
||||
# platform-specific test that cannot run on the current OS (e.g. a Windows-only
|
||||
# test on macOS); those must use the SKIP_PLATFORM() macro (or #ifdef
|
||||
# compile-gating). A plain SKIP() — or any direct tf_skip_count manipulation —
|
||||
# in a test source means a setup/environment/resource failure is being hidden
|
||||
# instead of surfaced as a failure. That fails this check.
|
||||
#
|
||||
# Rationale: a test that cannot establish its preconditions has FAILED, not been
|
||||
# "skipped". Convert such SKIP() to FAIL("reason").
|
||||
#
|
||||
# Usage: bash scripts/check-no-test-skips.sh (exit 0 = clean, 1 = violations)
|
||||
set -uo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
violations=0
|
||||
|
||||
# 1. Plain SKIP( in test sources.
|
||||
# - SKIP_PLATFORM( never matches "SKIP(" (the char after SKIP is '_').
|
||||
# - The SKIP()/FAIL()/SKIP_PLATFORM() macro DEFINITIONS live in
|
||||
# tests/test_framework.h (a .h), which the tests/*.c glob does not scan.
|
||||
while IFS= read -r hit; do
|
||||
echo "[no-skips] FORBIDDEN SKIP(): $hit"
|
||||
violations=$((violations + 1))
|
||||
done < <(grep -rnE '(^|[^A-Za-z0-9_])SKIP\(' "$ROOT"/tests/*.c 2>/dev/null || true)
|
||||
|
||||
# 2. Direct tf_skip_count increment in a test source (only the framework's
|
||||
# SKIP_PLATFORM macro, defined in the .h, may touch it).
|
||||
while IFS= read -r hit; do
|
||||
echo "[no-skips] FORBIDDEN tf_skip_count manipulation: $hit"
|
||||
violations=$((violations + 1))
|
||||
done < <(grep -rnE 'tf_skip_count[[:space:]]*(\+\+|\+=|--)' "$ROOT"/tests/*.c 2>/dev/null || true)
|
||||
|
||||
if [ "$violations" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "[no-skips] FAIL: $violations violation(s). Tests must pass or fail."
|
||||
echo " setup / environment / resource failures -> FAIL(\"reason\")"
|
||||
echo " genuinely platform-specific tests -> SKIP_PLATFORM(\"reason\") or #ifdef"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[no-skips] OK — no forbidden skips in tests/*.c (SKIP_PLATFORM allowed for platform-only tests)"
|
||||
exit 0
|
||||
@@ -29,6 +29,11 @@ done
|
||||
|
||||
print_env "lint.sh"
|
||||
|
||||
# No-skips policy: every test must pass or fail. The only tolerable skip is a
|
||||
# genuinely platform-specific test (SKIP_PLATFORM / #ifdef). Runs in both modes.
|
||||
echo "=== no-skips policy (tests pass or fail) ==="
|
||||
bash "$ROOT/scripts/check-no-test-skips.sh"
|
||||
|
||||
if $CI_ONLY; then
|
||||
echo "=== CI mode: cppcheck + clang-format ==="
|
||||
$ARCH_PREFIX make -j2 -f Makefile.cbm lint-ci "${MAKE_ARGS[@]+"${MAKE_ARGS[@]}"}"
|
||||
|
||||
+3
-3
@@ -606,19 +606,19 @@ TEST(clsp_calls_attributed_to_function_issue220) {
|
||||
TEST(clsp_nocrash_issue355_xxhash_header) {
|
||||
FILE *fp = fopen("vendored/xxhash/xxhash.h", "rb");
|
||||
if (!fp) {
|
||||
SKIP("vendored/xxhash/xxhash.h not found (run from repo root)");
|
||||
FAIL("vendored/xxhash/xxhash.h not found (run from repo root)");
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long n = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if (n <= 0) {
|
||||
fclose(fp);
|
||||
SKIP("xxhash.h unreadable");
|
||||
FAIL("xxhash.h unreadable");
|
||||
}
|
||||
char *buf = (char *)malloc((size_t)n + 1);
|
||||
if (!buf) {
|
||||
fclose(fp);
|
||||
SKIP("oom");
|
||||
FAIL("oom");
|
||||
}
|
||||
size_t rd = fread(buf, 1, (size_t)n, fp);
|
||||
fclose(fp);
|
||||
|
||||
+79
-79
@@ -176,7 +176,7 @@ TEST(cli_detect_shell_rc_zsh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-rc-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
/* Save and override SHELL — must strdup because setenv may realloc env block */
|
||||
const char *raw = getenv("SHELL");
|
||||
@@ -200,7 +200,7 @@ TEST(cli_detect_shell_rc_bash) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-rc-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
@@ -225,7 +225,7 @@ TEST(cli_detect_shell_rc_bash_with_bashrc) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-rc-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
@@ -253,7 +253,7 @@ TEST(cli_detect_shell_rc_fish) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-rc-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
@@ -275,7 +275,7 @@ TEST(cli_detect_shell_rc_default) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-rc-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("SHELL");
|
||||
char *old_shell = raw ? strdup(raw) : NULL;
|
||||
@@ -302,7 +302,7 @@ TEST(cli_find_cli_not_found) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-find-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
const char *raw = getenv("PATH");
|
||||
char *old_path = raw ? strdup(raw) : NULL;
|
||||
@@ -324,7 +324,7 @@ TEST(cli_find_cli_on_path) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-find-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char fakecli[512];
|
||||
snprintf(fakecli, sizeof(fakecli), "%s/fakecli", tmpdir);
|
||||
@@ -333,7 +333,7 @@ TEST(cli_find_cli_on_path) {
|
||||
|
||||
#ifdef _WIN32
|
||||
rmdir(tmpdir);
|
||||
SKIP("PATH-based CLI lookup uses POSIX semantics");
|
||||
SKIP_PLATFORM("Windows: PATH-based CLI lookup uses POSIX semantics");
|
||||
#endif
|
||||
const char *raw = getenv("PATH");
|
||||
char *old_path = raw ? strdup(raw) : NULL;
|
||||
@@ -357,11 +357,11 @@ TEST(cli_find_cli_fallback_paths) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-find-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
#ifdef _WIN32
|
||||
rmdir(tmpdir);
|
||||
SKIP("fallback path lookup uses POSIX semantics");
|
||||
SKIP_PLATFORM("Windows: fallback path lookup uses POSIX semantics");
|
||||
#endif
|
||||
char localbin[512];
|
||||
snprintf(localbin, sizeof(localbin), "%s/.local/bin", tmpdir);
|
||||
@@ -415,7 +415,7 @@ TEST(cli_skill_creation) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-skill-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -446,7 +446,7 @@ TEST(cli_skill_idempotent) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-skill-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -476,7 +476,7 @@ TEST(cli_skill_force_overwrite) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-skill-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -496,7 +496,7 @@ TEST(cli_uninstall_removes_skills) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-skill-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -523,7 +523,7 @@ TEST(cli_remove_old_monolithic_skill) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-skill-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -594,7 +594,7 @@ TEST(cli_editor_mcp_install) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -617,7 +617,7 @@ TEST(cli_editor_mcp_idempotent) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -648,7 +648,7 @@ TEST(cli_editor_mcp_preserves_others) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -677,7 +677,7 @@ TEST(cli_editor_mcp_uninstall) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.cursor/mcp.json", tmpdir);
|
||||
@@ -700,7 +700,7 @@ TEST(cli_gemini_mcp_install) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.gemini/settings.json", tmpdir);
|
||||
@@ -727,7 +727,7 @@ TEST(cli_vscode_mcp_install) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/Code/User/mcp.json", tmpdir);
|
||||
@@ -752,7 +752,7 @@ TEST(cli_vscode_mcp_uninstall) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/Code/User/mcp.json", tmpdir);
|
||||
@@ -778,7 +778,7 @@ TEST(cli_zed_mcp_install) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -803,7 +803,7 @@ TEST(cli_zed_mcp_preserves_settings) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -834,7 +834,7 @@ TEST(cli_zed_mcp_uninstall) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -856,7 +856,7 @@ TEST(cli_zed_mcp_jsonc_comments) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-mcp-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/.config/zed/settings.json", tmpdir);
|
||||
@@ -898,7 +898,7 @@ TEST(cli_ensure_path_append) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-path-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/.zshrc", tmpdir);
|
||||
@@ -918,7 +918,7 @@ TEST(cli_ensure_path_already_present) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-path-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/.zshrc", tmpdir);
|
||||
@@ -935,7 +935,7 @@ TEST(cli_ensure_path_dry_run) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-path-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/.zshrc", tmpdir);
|
||||
@@ -958,7 +958,7 @@ TEST(cli_ensure_path_fish_syntax_issue319) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-path-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char rcfile[512];
|
||||
snprintf(rcfile, sizeof(rcfile), "%s/config.fish", tmpdir);
|
||||
@@ -990,7 +990,7 @@ TEST(cli_copy_file) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-copy-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char src[512], dst[512];
|
||||
snprintf(src, sizeof(src), "%s/source", tmpdir);
|
||||
@@ -1013,7 +1013,7 @@ TEST(cli_copy_file_source_not_found) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-copy-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char src[512], dst[512];
|
||||
snprintf(src, sizeof(src), "%s/nonexistent", tmpdir);
|
||||
@@ -1217,7 +1217,7 @@ TEST(cli_install_dry_run) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-dry-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -1243,7 +1243,7 @@ TEST(cli_uninstall_dry_run) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-dry-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -1274,7 +1274,7 @@ TEST(cli_install_and_uninstall) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-full-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char skills_dir[512];
|
||||
snprintf(skills_dir, sizeof(skills_dir), "%s/.claude/skills", tmpdir);
|
||||
@@ -1411,7 +1411,7 @@ TEST(cli_detect_agents_finds_claude) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
snprintf(dir, sizeof(dir), "%s/.claude", tmpdir);
|
||||
@@ -1439,7 +1439,7 @@ TEST(cli_detect_agents_finds_claude_via_env) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
/* Config dir lives OUTSIDE home_dir/.claude, pointed at by CLAUDE_CONFIG_DIR. */
|
||||
char ccd[512];
|
||||
@@ -1469,7 +1469,7 @@ TEST(cli_detect_agents_finds_codex) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
snprintf(dir, sizeof(dir), "%s/.codex", tmpdir);
|
||||
@@ -1488,7 +1488,7 @@ TEST(cli_detect_agents_finds_cursor_issue222) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
snprintf(dir, sizeof(dir), "%s/.cursor", tmpdir);
|
||||
@@ -1507,7 +1507,7 @@ TEST(cli_install_plan_receipt_no_mutation_issue388) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-plan-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
/* Make Cursor + Codex "detected". */
|
||||
char dir[512];
|
||||
@@ -1544,7 +1544,7 @@ TEST(cli_codex_session_hook_issue330) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-codexhook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cfg[512];
|
||||
snprintf(cfg, sizeof(cfg), "%s/config.toml", tmpdir);
|
||||
@@ -1578,7 +1578,7 @@ TEST(cli_gemini_session_hook_parity) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-gemhook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cfg[512];
|
||||
snprintf(cfg, sizeof(cfg), "%s/settings.json", tmpdir);
|
||||
@@ -1601,7 +1601,7 @@ TEST(cli_detect_agents_finds_gemini) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
snprintf(dir, sizeof(dir), "%s/.gemini", tmpdir);
|
||||
@@ -1618,7 +1618,7 @@ TEST(cli_detect_agents_finds_zed) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
#ifdef __APPLE__
|
||||
@@ -1641,7 +1641,7 @@ TEST(cli_detect_agents_finds_antigravity) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
/* Antigravity CLI installs under ~/.gemini/antigravity-cli/ (2026). */
|
||||
@@ -1660,7 +1660,7 @@ TEST(cli_detect_agents_finds_kilocode) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
#ifdef __APPLE__
|
||||
@@ -1685,7 +1685,7 @@ TEST(cli_detect_agents_finds_kiro) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char dir[512];
|
||||
snprintf(dir, sizeof(dir), "%s/.kiro", tmpdir);
|
||||
@@ -1702,7 +1702,7 @@ TEST(cli_detect_agents_none_found) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-detect-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
/* Empty home dir → no config dirs → no directory-based agents detected.
|
||||
* Note: opencode/aider may still be detected via system fallback paths
|
||||
@@ -1738,7 +1738,7 @@ TEST(cli_upsert_codex_mcp_fresh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-codex-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/config.toml", tmpdir);
|
||||
@@ -1759,7 +1759,7 @@ TEST(cli_upsert_codex_mcp_existing) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-codex-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/config.toml", tmpdir);
|
||||
@@ -1784,7 +1784,7 @@ TEST(cli_upsert_codex_mcp_replace) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-codex-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/config.toml", tmpdir);
|
||||
@@ -1817,7 +1817,7 @@ TEST(cli_zed_mcp_uses_args_format) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-zed-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/settings.json", tmpdir);
|
||||
@@ -1842,7 +1842,7 @@ TEST(cli_upsert_opencode_mcp_fresh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-ocode-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/opencode.json", tmpdir);
|
||||
@@ -1869,7 +1869,7 @@ TEST(cli_upsert_opencode_mcp_existing) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-ocode-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/opencode.json", tmpdir);
|
||||
@@ -1895,7 +1895,7 @@ TEST(cli_upsert_antigravity_mcp_fresh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-anti-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/mcp_config.json", tmpdir);
|
||||
@@ -1915,7 +1915,7 @@ TEST(cli_upsert_antigravity_mcp_replace) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-anti-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char configpath[512];
|
||||
snprintf(configpath, sizeof(configpath), "%s/mcp_config.json", tmpdir);
|
||||
@@ -1942,7 +1942,7 @@ TEST(cli_upsert_instructions_fresh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-instr-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char filepath[512];
|
||||
snprintf(filepath, sizeof(filepath), "%s/AGENTS.md", tmpdir);
|
||||
@@ -1964,7 +1964,7 @@ TEST(cli_upsert_instructions_existing) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-instr-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char filepath[512];
|
||||
snprintf(filepath, sizeof(filepath), "%s/AGENTS.md", tmpdir);
|
||||
@@ -1990,7 +1990,7 @@ TEST(cli_upsert_instructions_replace) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-instr-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char filepath[512];
|
||||
snprintf(filepath, sizeof(filepath), "%s/AGENTS.md", tmpdir);
|
||||
@@ -2020,7 +2020,7 @@ TEST(cli_upsert_instructions_no_duplicate) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-instr-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char filepath[512];
|
||||
snprintf(filepath, sizeof(filepath), "%s/AGENTS.md", tmpdir);
|
||||
@@ -2051,7 +2051,7 @@ TEST(cli_remove_instructions) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-instr-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char filepath[512];
|
||||
snprintf(filepath, sizeof(filepath), "%s/AGENTS.md", tmpdir);
|
||||
@@ -2092,7 +2092,7 @@ TEST(cli_upsert_claude_hook_fresh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2121,7 +2121,7 @@ TEST(cli_hook_gate_script_no_predictable_tmp_issue384) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-gate-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_install_hook_gate_script(tmpdir, "/usr/local/bin/codebase-memory-mcp");
|
||||
|
||||
@@ -2143,7 +2143,7 @@ TEST(cli_upsert_claude_hook_existing) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2172,7 +2172,7 @@ TEST(cli_upsert_claude_hook_replace) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2198,7 +2198,7 @@ TEST(cli_upsert_claude_hook_preserves_others) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2226,7 +2226,7 @@ TEST(cli_remove_claude_hooks) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2252,7 +2252,7 @@ TEST(cli_upsert_gemini_hook_fresh) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-ghook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2273,7 +2273,7 @@ TEST(cli_upsert_gemini_hook_existing) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-ghook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2299,7 +2299,7 @@ TEST(cli_upsert_gemini_hook_replace) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-ghook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2324,7 +2324,7 @@ TEST(cli_remove_gemini_hooks) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-ghook-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char settingspath[512];
|
||||
snprintf(settingspath, sizeof(settingspath), "%s/settings.json", tmpdir);
|
||||
@@ -2363,7 +2363,7 @@ TEST(cli_config_open_close) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-cfg-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -2383,7 +2383,7 @@ TEST(cli_config_get_set) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-cfg-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -2408,7 +2408,7 @@ TEST(cli_config_get_bool) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-cfg-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -2440,7 +2440,7 @@ TEST(cli_config_get_int) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-cfg-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -2463,7 +2463,7 @@ TEST(cli_config_delete) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-cfg-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -2484,7 +2484,7 @@ TEST(cli_config_persists) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-cfg-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
cbm_config_t *cfg = cbm_config_open(tmpdir);
|
||||
ASSERT_NOT_NULL(cfg);
|
||||
@@ -2513,7 +2513,7 @@ TEST(replace_binary_overwrites_readonly) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-replace-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
}
|
||||
|
||||
char path[512];
|
||||
@@ -2554,7 +2554,7 @@ TEST(replace_binary_creates_new_file) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-replace2-XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
}
|
||||
|
||||
char path[512];
|
||||
|
||||
@@ -187,13 +187,9 @@ static double elapsed_ms(struct timespec t0, struct timespec t1) {
|
||||
}
|
||||
|
||||
TEST(cslsp_bench_resolution_ratio) {
|
||||
/* Perf benchmark: time-budgeted, so skip under CBM_SKIP_PERF (set by the
|
||||
* CI dry-run). Under ASan+UBSan the budget is unattainable and an early
|
||||
* assert-bail would leak the result; runs normally when perf is enabled. */
|
||||
const char *skip = getenv("CBM_SKIP_PERF");
|
||||
if (skip && skip[0] && skip[0] != '0') {
|
||||
SKIP("CBM_SKIP_PERF=1 (perf benchmark)");
|
||||
}
|
||||
/* Perf benchmark: time-budgeted. Under ASan+UBSan the budget is scaled
|
||||
* (see the sanitizer-aware time-budget assert below); the benchmark always
|
||||
* runs so regressions surface in every configuration. */
|
||||
int slen = (int)strlen(bench_source);
|
||||
|
||||
struct timespec t0;
|
||||
|
||||
@@ -502,7 +502,7 @@ TEST(discover_symlink_skipped) {
|
||||
#ifdef _WIN32
|
||||
/* Symlinks require elevated privileges on Windows — skip.
|
||||
* Guard the entire body: symlink() doesn't exist on Windows. */
|
||||
SKIP("symlinks need admin on Windows");
|
||||
SKIP_PLATFORM("Windows: symlinks need admin / symlink() unavailable");
|
||||
#else
|
||||
char *base = th_mktempdir("cbm_disc_sym");
|
||||
ASSERT(base != NULL);
|
||||
|
||||
@@ -66,6 +66,27 @@ static inline const char *tf_reset(void) {
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
/* Hard failure with a message — for setup/environment failures that must NOT be
|
||||
* silently skipped (a test that cannot establish its preconditions has FAILED,
|
||||
* not "skipped"). Mirrors the ASSERT failure path (red FAIL + file:line). */
|
||||
#define FAIL(reason) \
|
||||
do { \
|
||||
printf(" %sFAIL%s %s:%d: %s\n", tf_red(), tf_reset(), __FILE__, __LINE__, (reason)); \
|
||||
return 1; \
|
||||
} while (0)
|
||||
|
||||
/* The ONLY tolerable skip: a test that is inherently platform-specific and does
|
||||
* not apply on the current OS (e.g. a Windows-only test running on macOS).
|
||||
* Distinct from SKIP() so the no-skips linter (scripts/check-no-test-skips.sh)
|
||||
* can allow these and reject every other skip. Use sparingly + with a reason
|
||||
* that names the platform. Prefer compile-gating (#ifdef) where practical. */
|
||||
#define SKIP_PLATFORM(reason) \
|
||||
do { \
|
||||
printf("%sSKIP%s (platform: %s)\n", tf_dim(), tf_reset(), reason); \
|
||||
tf_skip_count++; \
|
||||
return -1; \
|
||||
} while (0)
|
||||
|
||||
/* ── Assertions ────────────────────────────────────────────────── */
|
||||
|
||||
#define ASSERT(cond) \
|
||||
|
||||
+24
-32
@@ -2824,10 +2824,6 @@ SUITE(incremental) {
|
||||
return;
|
||||
}
|
||||
|
||||
int skip_perf = (getenv("CBM_SKIP_PERF") != NULL &&
|
||||
getenv("CBM_SKIP_PERF")[0] != '0' &&
|
||||
getenv("CBM_SKIP_PERF")[0] != '\0');
|
||||
|
||||
/* Phase 1: Full index baseline (needed for tool tests below) */
|
||||
RUN_TEST(incr_full_index);
|
||||
RUN_TEST(incr_full_has_functions);
|
||||
@@ -2855,39 +2851,35 @@ SUITE(incremental) {
|
||||
g_full_imports = get_edge_count_by_type("IMPORTS");
|
||||
}
|
||||
|
||||
if (!skip_perf) {
|
||||
/* Phase 2: Noop */
|
||||
RUN_TEST(incr_noop_reindex);
|
||||
/* Phase 2: Noop */
|
||||
RUN_TEST(incr_noop_reindex);
|
||||
|
||||
/* Phase 3: Incremental deltas */
|
||||
RUN_TEST(incr_modify_file);
|
||||
RUN_TEST(incr_formatter_run);
|
||||
RUN_TEST(incr_add_file);
|
||||
RUN_TEST(incr_delete_file);
|
||||
RUN_TEST(incr_simultaneous_changes);
|
||||
/* Phase 3: Incremental deltas */
|
||||
RUN_TEST(incr_modify_file);
|
||||
RUN_TEST(incr_formatter_run);
|
||||
RUN_TEST(incr_add_file);
|
||||
RUN_TEST(incr_delete_file);
|
||||
RUN_TEST(incr_simultaneous_changes);
|
||||
|
||||
/* Phase 4: Adversarial */
|
||||
RUN_TEST(incr_empty_file);
|
||||
RUN_TEST(incr_syntax_error);
|
||||
RUN_TEST(incr_huge_single_function);
|
||||
RUN_TEST(incr_binary_content);
|
||||
RUN_TEST(incr_large_generated);
|
||||
RUN_TEST(incr_new_subdir);
|
||||
/* Phase 4: Adversarial */
|
||||
RUN_TEST(incr_empty_file);
|
||||
RUN_TEST(incr_syntax_error);
|
||||
RUN_TEST(incr_huge_single_function);
|
||||
RUN_TEST(incr_binary_content);
|
||||
RUN_TEST(incr_large_generated);
|
||||
RUN_TEST(incr_new_subdir);
|
||||
|
||||
/* Phase 5: Stress */
|
||||
RUN_TEST(incr_rapid_reindex);
|
||||
RUN_TEST(incr_replace_file_content);
|
||||
RUN_TEST(incr_batch_add_delete);
|
||||
/* Phase 5: Stress */
|
||||
RUN_TEST(incr_rapid_reindex);
|
||||
RUN_TEST(incr_replace_file_content);
|
||||
RUN_TEST(incr_batch_add_delete);
|
||||
|
||||
/* Phase 6: Recovery + accuracy */
|
||||
RUN_TEST(incr_db_deleted_recovery);
|
||||
RUN_TEST(incr_accuracy_vs_full);
|
||||
/* Phase 6: Recovery + accuracy */
|
||||
RUN_TEST(incr_db_deleted_recovery);
|
||||
RUN_TEST(incr_accuracy_vs_full);
|
||||
|
||||
/* Phase 7: Performance regression */
|
||||
RUN_TEST(incr_perf_single_file_fast);
|
||||
} else {
|
||||
printf(" [phases 2-7 SKIPPED — CBM_SKIP_PERF=1]\n");
|
||||
}
|
||||
/* Phase 7: Performance regression */
|
||||
RUN_TEST(incr_perf_single_file_fast);
|
||||
|
||||
/* Phase 8: list_projects + index_status + schema */
|
||||
RUN_TEST(tool_list_projects_basic);
|
||||
|
||||
@@ -531,9 +531,11 @@ TEST(integ_store_bfs_traversal) {
|
||||
SUITE(integration) {
|
||||
/* Set up: create temp project and index it */
|
||||
if (integration_setup() != 0) {
|
||||
printf(" %-50s", "integration_setup");
|
||||
printf("SKIP (setup failed)\n");
|
||||
tf_skip_count += 16; /* skip all integration tests */
|
||||
/* A suite that cannot establish its preconditions has FAILED, not
|
||||
* "skipped" — surface it as a single red failure (no-skips policy). */
|
||||
printf(" %sFAIL%s %s:%d: %s\n", tf_red(), tf_reset(), __FILE__, __LINE__,
|
||||
"integration_setup failed");
|
||||
tf_fail_count++;
|
||||
integration_teardown();
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-2
@@ -569,7 +569,7 @@ TEST(parallel_extract_with_slab) {
|
||||
cbm_mem_init(0.5);
|
||||
|
||||
if (setup_mem_test_repo() != 0) {
|
||||
SKIP("tmpdir setup failed");
|
||||
FAIL("tmpdir setup failed");
|
||||
}
|
||||
|
||||
cbm_discover_opts_t opts = {.mode = CBM_MODE_FULL};
|
||||
@@ -577,7 +577,7 @@ TEST(parallel_extract_with_slab) {
|
||||
int file_count = 0;
|
||||
if (cbm_discover(g_mem_tmpdir, &opts, &files, &file_count) != 0) {
|
||||
teardown_mem_test_repo();
|
||||
SKIP("discover failed");
|
||||
FAIL("discover failed");
|
||||
}
|
||||
|
||||
ASSERT_GTE(file_count, 5);
|
||||
|
||||
+14
-14
@@ -225,7 +225,7 @@ static void parity_teardown(void) {
|
||||
/* Node count parity */
|
||||
TEST(parallel_node_count) {
|
||||
if (ensure_parity_setup() != 0)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
int seq = cbm_gbuf_node_count(g_seq_gbuf);
|
||||
int par = cbm_gbuf_node_count(g_par_gbuf);
|
||||
ASSERT_GT(seq, 0);
|
||||
@@ -249,7 +249,7 @@ static int assert_edge_type_parity(const char *type) {
|
||||
TEST(parallel_calls_parity) {
|
||||
int rc = assert_edge_type_parity("CALLS");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
@@ -257,7 +257,7 @@ TEST(parallel_calls_parity) {
|
||||
TEST(parallel_defines_parity) {
|
||||
int rc = assert_edge_type_parity("DEFINES");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
@@ -265,7 +265,7 @@ TEST(parallel_defines_parity) {
|
||||
TEST(parallel_defines_method_parity) {
|
||||
int rc = assert_edge_type_parity("DEFINES_METHOD");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
@@ -273,7 +273,7 @@ TEST(parallel_defines_method_parity) {
|
||||
TEST(parallel_imports_parity) {
|
||||
int rc = assert_edge_type_parity("IMPORTS");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
@@ -281,7 +281,7 @@ TEST(parallel_imports_parity) {
|
||||
TEST(parallel_usage_parity) {
|
||||
int rc = assert_edge_type_parity("USAGE");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
@@ -289,7 +289,7 @@ TEST(parallel_usage_parity) {
|
||||
TEST(parallel_inherits_parity) {
|
||||
int rc = assert_edge_type_parity("INHERITS");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
@@ -297,14 +297,14 @@ TEST(parallel_inherits_parity) {
|
||||
TEST(parallel_implements_parity) {
|
||||
int rc = assert_edge_type_parity("IMPLEMENTS");
|
||||
if (rc == -1)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
ASSERT_EQ(rc, 0);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(parallel_total_edges) {
|
||||
if (ensure_parity_setup() != 0)
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
int seq = cbm_gbuf_edge_count(g_seq_gbuf);
|
||||
int par = cbm_gbuf_edge_count(g_par_gbuf);
|
||||
ASSERT_GT(seq, 0);
|
||||
@@ -485,7 +485,7 @@ TEST(parallel_python_lsp_override_emits_lsp_strategy_edges) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_par_pylsp_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("mkdtemp failed");
|
||||
FAIL("mkdtemp failed");
|
||||
}
|
||||
|
||||
/* Single-file scenario: pins the in-file LSP path where py_lsp
|
||||
@@ -500,7 +500,7 @@ TEST(parallel_python_lsp_override_emits_lsp_strategy_edges) {
|
||||
snprintf(fpath0, sizeof(fpath0), "%s/app.py", tmpdir);
|
||||
FILE *f = fopen(fpath0, "w");
|
||||
if (!f) {
|
||||
SKIP("fopen app.py failed");
|
||||
FAIL("fopen app.py failed");
|
||||
}
|
||||
fprintf(f, "class Greeter:\n"
|
||||
" def hello(self):\n"
|
||||
@@ -555,14 +555,14 @@ TEST(parallel_python_lsp_override_cross_file_emits_lsp_strategy_edges) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_par_pylsp_xf_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("mkdtemp failed");
|
||||
FAIL("mkdtemp failed");
|
||||
}
|
||||
|
||||
char gpath[512];
|
||||
snprintf(gpath, sizeof(gpath), "%s/greeter.py", tmpdir);
|
||||
FILE *gf = fopen(gpath, "w");
|
||||
if (!gf) {
|
||||
SKIP("fopen greeter.py failed");
|
||||
FAIL("fopen greeter.py failed");
|
||||
}
|
||||
fprintf(gf, "class Greeter:\n"
|
||||
" def hello(self):\n"
|
||||
@@ -575,7 +575,7 @@ TEST(parallel_python_lsp_override_cross_file_emits_lsp_strategy_edges) {
|
||||
if (!af) {
|
||||
unlink(gpath);
|
||||
rmdir(tmpdir);
|
||||
SKIP("fopen app.py failed");
|
||||
FAIL("fopen app.py failed");
|
||||
}
|
||||
fprintf(af, "from greeter import Greeter\n"
|
||||
"\n"
|
||||
|
||||
+57
-57
@@ -144,7 +144,7 @@ TEST(pipeline_run_null) {
|
||||
|
||||
TEST(store_file_persistence) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
char db_path[512];
|
||||
snprintf(db_path, sizeof(db_path), "%s/persist_test.db", g_tmpdir);
|
||||
@@ -178,7 +178,7 @@ TEST(store_file_persistence) {
|
||||
|
||||
TEST(store_bulk_persistence) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
char db_path[512];
|
||||
snprintf(db_path, sizeof(db_path), "%s/bulk_test.db", g_tmpdir);
|
||||
@@ -216,7 +216,7 @@ TEST(store_bulk_persistence) {
|
||||
|
||||
TEST(pipeline_structure_nodes) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -273,7 +273,7 @@ TEST(pipeline_structure_nodes) {
|
||||
|
||||
TEST(pipeline_structure_edges) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -305,7 +305,7 @@ TEST(pipeline_structure_edges) {
|
||||
|
||||
TEST(pipeline_project_name_derived) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_tmpdir, NULL, CBM_MODE_FULL);
|
||||
@@ -323,7 +323,7 @@ TEST(pipeline_project_name_derived) {
|
||||
|
||||
TEST(pipeline_fast_mode) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -352,7 +352,7 @@ TEST(pipeline_fast_mode) {
|
||||
|
||||
TEST(pipeline_definitions_function_nodes) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -397,7 +397,7 @@ TEST(pipeline_definitions_function_nodes) {
|
||||
|
||||
TEST(pipeline_definitions_defines_edges) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -428,7 +428,7 @@ TEST(pipeline_definitions_defines_edges) {
|
||||
|
||||
TEST(pipeline_definitions_properties) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -471,7 +471,7 @@ TEST(pipeline_definitions_properties) {
|
||||
|
||||
TEST(pipeline_calls_resolution) {
|
||||
if (setup_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -914,7 +914,7 @@ TEST(usages_creates_edges) {
|
||||
"}\n";
|
||||
|
||||
if (setup_usages_repo("mypkg/main.go", go_source, "go.mod", "module testmod\ngo 1.21\n") != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -968,7 +968,7 @@ TEST(usages_no_duplicate_calls) {
|
||||
"}\n";
|
||||
|
||||
if (setup_usages_repo("mypkg/main.go", go_source, "go.mod", "module testmod\ngo 1.21\n") != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -1038,7 +1038,7 @@ TEST(usages_kotlin_creates_edges) {
|
||||
"}\n";
|
||||
|
||||
if (setup_usages_repo("Main.kt", kt_source, NULL, NULL) != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -1080,7 +1080,7 @@ TEST(usages_kotlin_no_duplicate_calls) {
|
||||
"}\n";
|
||||
|
||||
if (setup_usages_repo("Main.kt", kt_source, NULL, NULL) != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -1189,7 +1189,7 @@ TEST(pipeline_python_project) {
|
||||
"class DataProcessor:\n def transform(self, data):\n return data\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1235,7 +1235,7 @@ TEST(pipeline_go_cross_package_call) {
|
||||
"package svc\n\nfunc ProcessOrder(id string) error {\n\treturn nil\n}\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1290,7 +1290,7 @@ TEST(pipeline_python_cross_module_call) {
|
||||
"def process():\n result = fetch_data(\"https://example.com\")\n return result\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1342,7 +1342,7 @@ TEST(pipeline_go_type_classification) {
|
||||
"type ID = string\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1394,7 +1394,7 @@ TEST(pipeline_go_grouped_types) {
|
||||
")\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1438,7 +1438,7 @@ TEST(pipeline_kotlin_project) {
|
||||
"object Config {\n val API_URL = \"https://example.com/api\"\n}\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1492,7 +1492,7 @@ TEST(pipeline_lua_anonymous_functions) {
|
||||
"end\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1543,7 +1543,7 @@ TEST(pipeline_csharp_modern) {
|
||||
"}\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1583,7 +1583,7 @@ TEST(pipeline_bom_stripping) {
|
||||
/* Port of TestBOMStripping — UTF-8 BOM prefix should be handled */
|
||||
snprintf(g_lang_tmpdir, sizeof(g_lang_tmpdir), "/tmp/cbm_bom_XXXXXX");
|
||||
if (!cbm_mkdtemp(g_lang_tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
char path[512];
|
||||
snprintf(path, sizeof(path), "%s/bom.go", g_lang_tmpdir);
|
||||
@@ -1629,7 +1629,7 @@ TEST(pipeline_form_call_resolution) {
|
||||
"#endprocedure\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1683,7 +1683,7 @@ TEST(pipeline_python_type_inference) {
|
||||
" return result\n"};
|
||||
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
|
||||
@@ -1742,7 +1742,7 @@ TEST(pipeline_docstring_go_function) {
|
||||
"// Compute does something.\n"
|
||||
"func Compute() {}\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -1783,7 +1783,7 @@ TEST(pipeline_docstring_python_function) {
|
||||
"\t\"\"\"Does something.\"\"\"\n"
|
||||
"\tpass\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -1824,7 +1824,7 @@ TEST(pipeline_docstring_java_method) {
|
||||
"\tvoid compute() {}\n"
|
||||
"}\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -1863,7 +1863,7 @@ TEST(pipeline_docstring_kotlin_function) {
|
||||
const char *contents[] = {"/** Computes result. */\n"
|
||||
"fun compute() {}\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -1903,7 +1903,7 @@ TEST(pipeline_docstring_go_class) {
|
||||
"// MyStruct is documented.\n"
|
||||
"type MyStruct struct{}\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -2220,7 +2220,7 @@ TEST(configures_env_var_in_config) {
|
||||
"\t_ = url\n"
|
||||
"}\n"};
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -2253,7 +2253,7 @@ TEST(configures_lowercase_key_skipped) {
|
||||
|
||||
"package main\n\nfunc main() {}\n"};
|
||||
if (setup_lang_repo(files, contents, 2) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -2277,7 +2277,7 @@ TEST(configures_non_config_file_skipped) {
|
||||
"var API_URL = \"https://api.example.com\"\n\n"
|
||||
"func main() {}\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -2322,7 +2322,7 @@ TEST(configures_full_pipeline_integration) {
|
||||
"}\n\n"
|
||||
"func readFile(path string) string { return \"\" }\n"};
|
||||
if (setup_lang_repo(files, contents, 4) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -2567,7 +2567,7 @@ TEST(decorator_tags_python_auto_discovery) {
|
||||
"def special():\n"
|
||||
" pass\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -2641,7 +2641,7 @@ TEST(decorator_tags_java_class_methods) {
|
||||
" public void updateOwner() {}\n"
|
||||
"}\n"};
|
||||
if (setup_lang_repo(files, contents, 1) != 0)
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
|
||||
@@ -3868,7 +3868,7 @@ TEST(envscan_dockerfile_env_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_dock_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "Dockerfile",
|
||||
"FROM python:3.9-slim\n"
|
||||
@@ -3896,7 +3896,7 @@ TEST(envscan_shell_env_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_sh_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "setup.sh",
|
||||
"#!/bin/bash\n"
|
||||
@@ -3922,7 +3922,7 @@ TEST(envscan_env_file_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_env_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, ".env",
|
||||
"\nAPI_URL=https://api.example.com/v1\n"
|
||||
@@ -3947,7 +3947,7 @@ TEST(envscan_toml_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_toml_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "config.toml",
|
||||
"[service]\n"
|
||||
@@ -3973,7 +3973,7 @@ TEST(envscan_yaml_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_yaml_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "config.yaml",
|
||||
"service:\n"
|
||||
@@ -3997,7 +3997,7 @@ TEST(envscan_terraform_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_tf_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "variables.tf",
|
||||
"variable \"webhook_url\" {\n"
|
||||
@@ -4022,7 +4022,7 @@ TEST(envscan_properties_urls) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_prop_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "app.properties",
|
||||
"api.url=https://api.example.com/health\n"
|
||||
@@ -4043,7 +4043,7 @@ TEST(envscan_secret_key_exclusion) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_skey_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "Dockerfile",
|
||||
"FROM node:18\n"
|
||||
@@ -4070,7 +4070,7 @@ TEST(envscan_secret_value_exclusion) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_sval_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(
|
||||
tmpdir, "deploy.sh",
|
||||
@@ -4094,7 +4094,7 @@ TEST(envscan_secret_file_exclusion) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_sfile_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
/* Secret file should be skipped */
|
||||
write_temp_file(tmpdir, "credentials.sh",
|
||||
@@ -4126,7 +4126,7 @@ TEST(envscan_skips_ignored_dirs) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_ign_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
/* File inside .git should be skipped */
|
||||
char gitdir[512];
|
||||
@@ -4173,7 +4173,7 @@ TEST(envscan_non_url_values_skipped) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_envscan_nurl_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "Dockerfile",
|
||||
"FROM python:3.9\n"
|
||||
@@ -4432,7 +4432,7 @@ TEST(pipeline_fastapi_depends_edges) {
|
||||
"def get_profile(user = Depends(get_current_user)):\n"
|
||||
" return {\"user\": user}\n"};
|
||||
if (setup_lang_repo(files, contents, 2) != 0) {
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
}
|
||||
char db[512];
|
||||
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
|
||||
@@ -4477,7 +4477,7 @@ TEST(pipeline_fastapi_depends_edges) {
|
||||
TEST(incremental_full_then_noop) {
|
||||
/* Full index, then re-run → should detect no changes and skip */
|
||||
if (setup_incremental_repo() != 0) {
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
}
|
||||
|
||||
/* First: full index */
|
||||
@@ -4515,7 +4515,7 @@ TEST(incremental_full_then_noop) {
|
||||
TEST(incremental_detects_changed_file) {
|
||||
/* Full index, modify one file, re-index → changed file re-parsed */
|
||||
if (setup_incremental_repo() != 0) {
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
}
|
||||
|
||||
/* First: full index */
|
||||
@@ -4556,7 +4556,7 @@ TEST(incremental_detects_changed_file) {
|
||||
TEST(incremental_detects_deleted_file) {
|
||||
/* Full index, delete a file, re-index → deleted file's nodes removed */
|
||||
if (setup_incremental_repo() != 0) {
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
}
|
||||
|
||||
/* First: full index */
|
||||
@@ -4592,7 +4592,7 @@ TEST(incremental_detects_deleted_file) {
|
||||
TEST(incremental_new_file_added) {
|
||||
/* Full index, add a new file, re-index → new file's nodes appear */
|
||||
if (setup_incremental_repo() != 0) {
|
||||
SKIP("setup failed");
|
||||
FAIL("setup failed");
|
||||
}
|
||||
|
||||
/* First: full index */
|
||||
@@ -4642,7 +4642,7 @@ TEST(incremental_fast_preserves_mode_skipped_tools_dir) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_modeskip_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
}
|
||||
char dbpath[512];
|
||||
snprintf(dbpath, sizeof(dbpath), "%s/test.db", tmpdir);
|
||||
@@ -4783,7 +4783,7 @@ TEST(incremental_k8s_manifest_indexed) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_k8s_incr_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
}
|
||||
char dbpath[512];
|
||||
snprintf(dbpath, sizeof(dbpath), "%s/test.db", tmpdir);
|
||||
@@ -4848,7 +4848,7 @@ TEST(incremental_kustomize_module_indexed) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_kust_incr_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir)) {
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
}
|
||||
char dbpath[512];
|
||||
snprintf(dbpath, sizeof(dbpath), "%s/test.db", tmpdir);
|
||||
@@ -5441,7 +5441,7 @@ TEST(pipeline_complexity_transitive_loop_depth) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_cx_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("tmpdir");
|
||||
FAIL("tmpdir");
|
||||
|
||||
write_temp_file(tmpdir, "cx.go",
|
||||
"package p\n\n"
|
||||
|
||||
@@ -218,13 +218,9 @@ static double elapsed_ms(struct timespec t0, struct timespec t1) {
|
||||
}
|
||||
|
||||
TEST(pylsp_bench_resolution_ratio) {
|
||||
/* Perf benchmark: time-budgeted, so skip under CBM_SKIP_PERF (set by the
|
||||
* CI dry-run). Under ASan+UBSan the budget is unattainable and an early
|
||||
* assert-bail would leak the result; runs normally when perf is enabled. */
|
||||
const char *skip = getenv("CBM_SKIP_PERF");
|
||||
if (skip && skip[0] && skip[0] != '0') {
|
||||
SKIP("CBM_SKIP_PERF=1 (perf benchmark)");
|
||||
}
|
||||
/* Perf benchmark: time-budgeted. Under ASan+UBSan the budget is scaled up
|
||||
* (see the sanitizer-aware budget below) and the result is freed before
|
||||
* asserting so a budget miss doesn't leak. */
|
||||
int slen = (int)strlen(bench_source);
|
||||
|
||||
struct timespec t0;
|
||||
|
||||
@@ -879,7 +879,7 @@ static void teardown_sim_test_repo(void) {
|
||||
|
||||
TEST(pipeline_minhash_end_to_end) {
|
||||
if (setup_sim_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -930,7 +930,7 @@ TEST(pipeline_minhash_end_to_end) {
|
||||
TEST(pipeline_minhash_no_false_positives) {
|
||||
snprintf(g_sim_tmpdir, sizeof(g_sim_tmpdir), "/tmp/cbm_sim_nofp_XXXXXX");
|
||||
if (!cbm_mkdtemp(g_sim_tmpdir)) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
/* 5 diverse functions — no clones */
|
||||
@@ -1003,7 +1003,7 @@ TEST(pipeline_minhash_no_false_positives) {
|
||||
|
||||
TEST(pipeline_minhash_incremental) {
|
||||
if (setup_sim_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
@@ -1066,7 +1066,7 @@ TEST(pipeline_minhash_incremental) {
|
||||
|
||||
TEST(pipeline_minhash_incremental_new_clone) {
|
||||
if (setup_sim_test_repo() != 0) {
|
||||
SKIP("failed to create temp dir");
|
||||
FAIL("failed to create temp dir");
|
||||
}
|
||||
|
||||
char db_path[512];
|
||||
|
||||
+2
-2
@@ -706,7 +706,7 @@ TEST(vmem_parallel_extract_with_slab) {
|
||||
cbm_vmem_init(0.5);
|
||||
|
||||
if (setup_vmem_test_repo() != 0) {
|
||||
SKIP("tmpdir setup failed");
|
||||
FAIL("tmpdir setup failed");
|
||||
}
|
||||
|
||||
cbm_discover_opts_t opts = {.mode = CBM_MODE_FULL};
|
||||
@@ -714,7 +714,7 @@ TEST(vmem_parallel_extract_with_slab) {
|
||||
int file_count = 0;
|
||||
if (cbm_discover(g_vmem_tmpdir, &opts, &files, &file_count) != 0) {
|
||||
teardown_vmem_test_repo();
|
||||
SKIP("discover failed");
|
||||
FAIL("discover failed");
|
||||
}
|
||||
|
||||
ASSERT_GTE(file_count, 5);
|
||||
|
||||
+43
-43
@@ -183,7 +183,7 @@ TEST(watcher_poll_this_repo) {
|
||||
if (!getcwd(cwd, sizeof(cwd))) {
|
||||
cbm_watcher_free(w);
|
||||
cbm_store_close(store);
|
||||
SKIP("getcwd failed");
|
||||
FAIL("getcwd failed");
|
||||
}
|
||||
|
||||
cbm_watcher_watch(w, "self", cwd);
|
||||
@@ -233,7 +233,7 @@ TEST(watcher_detects_git_commit) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_test_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -243,7 +243,7 @@ TEST(watcher_detects_git_commit) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -286,7 +286,7 @@ TEST(watcher_detects_dirty_worktree) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_dirty_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -296,7 +296,7 @@ TEST(watcher_detects_dirty_worktree) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -332,7 +332,7 @@ TEST(watcher_detects_new_file) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_newf_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -342,7 +342,7 @@ TEST(watcher_detects_new_file) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -379,7 +379,7 @@ TEST(watcher_no_change_no_reindex) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_nochg_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -389,7 +389,7 @@ TEST(watcher_no_change_no_reindex) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -423,7 +423,7 @@ TEST(watcher_multiple_projects) {
|
||||
char tmpdirB[256];
|
||||
snprintf(tmpdirB, sizeof(tmpdirB), "/tmp/cbm_watcher_mB_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdirA) || !cbm_mkdtemp(tmpdirB))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -432,7 +432,7 @@ TEST(watcher_multiple_projects) {
|
||||
"git add a.txt && git commit -q -m 'init'",
|
||||
tmpdirA);
|
||||
if (system(cmd) != 0) {
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -441,7 +441,7 @@ TEST(watcher_multiple_projects) {
|
||||
"git add b.txt && git commit -q -m 'init'",
|
||||
tmpdirB);
|
||||
if (system(cmd) != 0) {
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -487,7 +487,7 @@ TEST(watcher_non_git_skips) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_nongit_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
/* Create a file so it's not empty */
|
||||
{
|
||||
@@ -544,7 +544,7 @@ TEST(watcher_interval_blocks_repoll) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_intv_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -554,7 +554,7 @@ TEST(watcher_interval_blocks_repoll) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -620,7 +620,7 @@ TEST(watcher_git_removed_no_crash) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_rmgit_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -630,7 +630,7 @@ TEST(watcher_git_removed_no_crash) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -667,7 +667,7 @@ TEST(watcher_continued_dirty) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_cont_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -677,7 +677,7 @@ TEST(watcher_continued_dirty) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -738,7 +738,7 @@ TEST(watcher_baseline_dirty_repo) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_bld_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -748,7 +748,7 @@ TEST(watcher_baseline_dirty_repo) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
/* Make dirty BEFORE baseline */
|
||||
@@ -784,7 +784,7 @@ TEST(watcher_unwatch_prunes_state) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_prune_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -794,7 +794,7 @@ TEST(watcher_unwatch_prunes_state) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -832,7 +832,7 @@ TEST(watcher_watch_after_unwatch) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_rewatch_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -842,7 +842,7 @@ TEST(watcher_watch_after_unwatch) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -895,7 +895,7 @@ TEST(watcher_detects_file_delete) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_del_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -906,7 +906,7 @@ TEST(watcher_detects_file_delete) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -942,7 +942,7 @@ TEST(watcher_detects_subdir_file) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_sub_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -952,7 +952,7 @@ TEST(watcher_detects_subdir_file) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -1014,7 +1014,7 @@ TEST(watcher_full_flow_new_file) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_ffnf_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1024,7 +1024,7 @@ TEST(watcher_full_flow_new_file) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -1066,7 +1066,7 @@ TEST(watcher_fallback_still_detects) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_fb_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1076,7 +1076,7 @@ TEST(watcher_fallback_still_detects) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -1128,7 +1128,7 @@ TEST(watcher_poll_only_watched_projects) {
|
||||
char tmpdirB[256];
|
||||
snprintf(tmpdirB, sizeof(tmpdirB), "/tmp/cbm_watcher_owB_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdirA) || !cbm_mkdtemp(tmpdirB))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
/* Init both repos */
|
||||
@@ -1138,7 +1138,7 @@ TEST(watcher_poll_only_watched_projects) {
|
||||
"git add a.txt && git commit -q -m 'init'",
|
||||
tmpdirA);
|
||||
if (system(cmd) != 0) {
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1147,7 +1147,7 @@ TEST(watcher_poll_only_watched_projects) {
|
||||
"git add b.txt && git commit -q -m 'init'",
|
||||
tmpdirB);
|
||||
if (system(cmd) != 0) {
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -1193,7 +1193,7 @@ TEST(watcher_touch_resets_immediate) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_tch_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1203,7 +1203,7 @@ TEST(watcher_touch_resets_immediate) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -1245,7 +1245,7 @@ TEST(watcher_modify_tracked_file) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_mod_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1255,7 +1255,7 @@ TEST(watcher_modify_tracked_file) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
@@ -1455,7 +1455,7 @@ TEST(watcher_poll_non_git_dir) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_ng2_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
/* Create a regular file so directory is not empty */
|
||||
{
|
||||
@@ -1541,7 +1541,7 @@ TEST(watcher_callback_data_passed) {
|
||||
char tmpdir[256];
|
||||
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cbm_watcher_cbdata_XXXXXX");
|
||||
if (!cbm_mkdtemp(tmpdir))
|
||||
SKIP("cbm_mkdtemp failed");
|
||||
FAIL("cbm_mkdtemp failed");
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
@@ -1551,7 +1551,7 @@ TEST(watcher_callback_data_passed) {
|
||||
tmpdir);
|
||||
if (system(cmd) != 0) {
|
||||
th_rmtree(tmpdir);
|
||||
SKIP("git not available");
|
||||
FAIL("git not available");
|
||||
}
|
||||
|
||||
cbm_store_t *store = cbm_store_open_memory();
|
||||
|
||||
@@ -194,10 +194,10 @@ TEST(parallel_for_actually_parallel) {
|
||||
atomic_init(&cc.concurrent_now, 0);
|
||||
cbm_parallel_for_opts_t opts = {.max_workers = 4, .force_pthreads = false};
|
||||
cbm_parallel_for(100, concurrency_worker, &cc, opts);
|
||||
/* At least 2 threads ran concurrently (skip on single-core CI runners) */
|
||||
if (atomic_load(&cc.concurrent_max) < 2) {
|
||||
SKIP("single-core runner — cannot verify parallelism");
|
||||
}
|
||||
/* At least 2 of the 4 workers must have run concurrently. No skip: every CI
|
||||
* runner is multi-core, so failing to demonstrate parallelism here is a real
|
||||
* failure of the invariant, not an environment we silently pass over. */
|
||||
ASSERT_GTE(atomic_load(&cc.concurrent_max), 2);
|
||||
PASS();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user