Skip to content

Windows test support — fast CI loop, analyzer green, web hang/login/store fixed#3

Draft
gamesh411 wants to merge 10 commits into
masterfrom
windows-test-support
Draft

Windows test support — fast CI loop, analyzer green, web hang/login/store fixed#3
gamesh411 wants to merge 10 commits into
masterfrom
windows-test-support

Conversation

@gamesh411

@gamesh411 gamesh411 commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Progress

Set up a tight Windows CI feedback loop and worked the failures down layer by layer. Each push now gives a Windows-only result in ~4–10 min (instead of the old 1h+ matrix that cancelled after the web job hung for 30 min).

Feedback loop

  • New .github/workflows/windows-iter.yml: runs only the two Windows jobs on pushes to this branch (+ workflow_dispatch), concurrency cancels superseded runs, actions/checkout@v4 / setup-python@v5.
  • Added pytest-timeout to the analyzer & web dev requirements and run with --timeout --timeout-method=thread, so a hanging test fails fast with a thread stack dump instead of burning the job timeout.
  • Removed the duplicate Windows jobs from test.yml (to be folded back once green).

Analyzer (Windows): ✅ GREEN (stable across 3 runs)

  • Root cause: the official LLVM Windows package ships no diagtool, so get_warnings() returns nothing and the clang-diagnostic-* based checks fail. Fixed by skipping the 3 diagtool-dependent tests when diagtool is unavailable (same pattern as the existing python-ldap skips). All other CheckerHandlingClangTidy tests pass.

Web (Windows): hang + login + store-crash fixed; structural blockers remain

Confirmed by CI, in order of how the failures peeled off:

  • 30-min hang eliminated / login works. The functional tests enable server auth and relied on HOME redirection so the client finds the throw-away credentials. On Windows os.path.expanduser("~") ignores HOME, so the client fell back to an interactive getpass() and hung forever. Fixed by redirecting CC_PASS_FILE/CC_SESSION_FILE into the test workspace and writing credentials there, plus stdin=subprocess.DEVNULL guards on the test subprocesses. CI now logs Server reported successful authentication on Windows.
  • Store crash fixed. CC_FORCE_SYNC_STORE (used by the tests) wrapped massStoreRun in a signal.SIGUSR1 watchdog; SIGUSR1 doesn't exist on Windows so even referencing it crashed the store. Now falls back to a plain synchronous store when the signal is unavailable (POSIX unchanged).

Remaining blockers (both structural, surfaced fast by the new loop)

  1. Build logging unsupported on Windows. test_garbage_file_collection builds a project via CodeChecker check -b, which uses CodeChecker log; this is explicitly unsupported on Windows (analyzer/.../buildlog/build_manager.py). The test can't produce reports on Windows as written.
  2. Forced-sync store hangs server-side. Once past the SIGUSR1 crash, the synchronous massStoreRun does not return on Windows (the test now hits the 300s pytest-timeout inside store's p.wait() rather than hanging the whole job). Needs investigation into the server-side store/background-task path on Windows.

Proposed next steps

  1. Rework the web functional path to avoid CodeChecker log on Windows: feed a pre-generated compile_commands.json and drive CodeChecker analyze + store directly. This unblocks producing reports.
  2. Investigate the synchronous massStoreRun server-side hang on Windows (or prefer the async store path the tests can also use).
  3. Expand the web job from the single test to the db_cleanup module, then the full tests/functional suite, using the fast-timeout loop.
  4. Fold the Windows jobs back into test.yml and flip continue-on-error: false once green.

Verified this iteration

  • Analyzer (Windows) CI: ✅ green (3 diagtool tests skipped, rest pass), stable across runs.
  • Web (Windows) CI: 30-min hang gone; login + store-crash fixed; now fails fast at the unsupported build-logging step / sync-store hang.
  • All changed Python validated on Linux (pycodestyle; the affected analyzer unit tests and the test_garbage_file_collection functional test still pass with diagtool/POSIX paths exercised).
Open in Web Open in Cursor 

@cursor cursor Bot changed the title WIP: Windows test support — current status and plan to get tests green Windows test support — fast CI loop, analyzer green, web hang/login/store fixed Jun 30, 2026
@gamesh411 gamesh411 force-pushed the windows-test-support branch 9 times, most recently from ed482b6 to 5250e76 Compare June 30, 2026 20:11
gamesh411 added 10 commits July 1, 2026 23:26
Replace the custom compatibility.multiprocessing shim with direct
imports from the multiprocess package. On macOS and Windows, the
default fork start method is unsafe (Obj-C runtime crashes) or
unavailable, so set spawn explicitly in cli.py:main().

Spawn workers do not inherit parent state, so analysis_manager and
pre_analysis_manager now explicitly set up logging in spawned
workers, and log_parser's _init_log_parser_worker propagates the
shared compiler_info dict to children.

Add mypy override for multiprocess (no type stubs available).
On macOS/Windows (spawn), worker processes cannot inherit the
HTTPServer instance or shared Queue/Value objects from the parent.
Reconstruct the server in spawned API workers from serializable
config (_build_worker_server) and use SyncManager.Queue() for the
task queue so it can be pickled to spawned task workers.

Spawned workers detect shutdown via SIGINT (not a shared flag),
and the cwd is validated before spawning to avoid os.getcwd()
failures if the inherited cwd was deleted.
The JSON compilation database spec allows entries to use either
'command' (string) or 'arguments' (list). The intercept-build
wrapper used on macOS (bear) produces the 'arguments' form.

Normalize 'arguments' to 'command' in tu_collector wherever the
build action command is accessed, so both formats work on all
platforms.
Add CC_TEST_API_WORKERS and CC_TEST_TASK_WORKERS env vars that
map to --api-handler-processes and --task-worker-processes server
flags. On macOS CI, spawn workers are expensive (each re-imports
the full Python stack), so constraining to 1 worker reduces
resource pressure.

Also improve wait_for_server_start with an HTTP fallback check
(port-based readiness) and fail-fast diagnostics for common
startup errors.
Analyzer tests:
- Use os.path.realpath('/tmp') to handle macOS /tmp -> /private/tmp
  symlink in log_parser and option_parser tests
- Skip LD_PRELOAD/LD_LIBRARY_PATH tests on macOS (not applicable)
- Skip gcc analyzer test when g++ is an Apple clang shim
- Skip -m32 test on macOS (not available)
- Use -fsyntax-only in buildcmd escaping tests (linking may fail
  with Homebrew clang on macOS)
- Normalize intercept-build vs ld-logger output strings
- Normalize gcc/infer diagnostic quoting and type annotations
  across versions for cross-platform comparison
- Add self.fail() in test_skip for tu_collector errors
- Guard 'command' key access for arguments-format entries

Web tests:
- OAuth mock server: bind to 127.0.0.1, poll for readiness
  instead of fixed sleep, track and terminate the process in
  teardown, use sys.executable instead of 'python3'
- blame tests: restore cwd in finally block to prevent test
  pollution on assertion failure
- task_management tests: poll for state transitions instead of
  fixed sleeps (spawn workers take ~42s to start on macOS),
  use 5s tasks to reliably observe RUNNING state
- Makefile: use $(ROOT)/build for workspace and CodeChecker cmd
  paths (consistent with __init__.py's hardcoded PKG_ROOT)
- env.py: no functional change
Add install-deps-macos.sh that installs llvm@14, gcc@13, cppcheck,
bear, and Infer (from GitHub releases, no Homebrew formula). The
script creates an intercept-build wrapper around bear (LLVM's
libear.dylib is broken on macOS ARM64 with SIP), gcc/g++ symlinks
matching Linux naming, and sets SDKROOT/MACOSX_DEPLOYMENT_TARGET/
CC/CXX to ensure correct compilation and SARIF output.

Add macOS matrix entries to the analyzer and tools jobs, and a
separate web-macos job (sqlite only, with reduced worker counts
via CC_TEST_API_WORKERS/CC_TEST_TASK_WORKERS). All macOS jobs use
continue-on-error as they are experimental.
Skip clang-diagnostic checker tests when diagtool is unavailable (the
Windows LLVM package ships no diagtool), fix an infinite loop in the
compilation-database directory walk on Windows path roots, and make the
remaining analyzer unit tests platform-portable.
Guard the Unix-only signals used for graceful shutdown and the forced
synchronous store: fall back when signal.SIGHUP / signal.SIGUSR1 are
unavailable so the background task worker and the store watchdog do not
crash on Windows. Also fix the store client's ZIP member paths for
drive-absolute paths so stored reports resolve to their source files.
Build logging (CodeChecker log / check -b) is unsupported on Windows, so
generate a compile_commands.json and run CodeChecker analyze directly.
Invoke the CodeChecker entry point via the Python interpreter, pass
stdin=DEVNULL so subprocesses cannot hang on an interactive prompt, and
redirect the credential/session files into the workspace on Windows
(where expanduser ignores HOME). Skip the LDAP unit tests when
python-ldap is not installed.
Run the analyzer unit suite, the web unit suites, and the Windows-
compatible web functional suites on Windows (continue-on-error). Build
logging (CodeChecker log / check -b) is unsupported on Windows, so only
functional tests that store results through check_and_store() (which
uses CodeChecker analyze) are enabled. LLVM and Cppcheck are cached and
pytest timeouts guard against hangs. install-deps-windows.sh installs
the toolchain.
@gamesh411 gamesh411 force-pushed the windows-test-support branch from 5250e76 to cb6240a Compare July 1, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant