Skip to content

removed serial testing library.#536

Open
stuartsessions wants to merge 19 commits intogit-ai-project:mainfrom
stuartsessions:main
Open

removed serial testing library.#536
stuartsessions wants to merge 19 commits intogit-ai-project:mainfrom
stuartsessions:main

Conversation

@stuartsessions
Copy link

@stuartsessions stuartsessions commented Feb 17, 2026

PR: Make tests parallel-safe and remove serial_test

Fixes #264

Summary

  • Add thread-local test environment overrides and HOME override to src/mdm/utils.rs.
  • Add per-TestRepo environment injection (env_vars, add_env, set_envs, clear_envs) to tests/repos/test_repo.rs so spawned child processes receive test-specific envs.
  • Update runtime code to consult test-aware helper (env_test_proxy) where tests previously mutated std::env (notably opencode + checkpoint presets and prompt utilities).
  • Replace in-test std::env::set_var usages in several tests with thread-local overrides (set_test_env_override) or per-repo env injection.
  • Remove the serial_test dev-dependency and #[serial] usage from tests.
  • Normalize blame output for --contents mode: map Not Committed YetExternal file (--contents) to stabilize tests.

Why

  • Many integration tests mutated the process-global environment which caused races and flakiness when tests ran in parallel. Thread-local overrides plus per-repo env injection let tests simulate environment variables without changing global std::env.

Files changed (high level)

  • src/mdm/utils.rs — added TEST_HOME_OVERRIDE, TEST_ENV_OVERRIDES, set_test_home_override, set_test_env_override, get_test_env_override, env_test_proxy.
  • src/git/test_utils/tmp_repo.rs — new file extracting TmpRepo and TmpFile structs from mod.rs with integrated unit tests for environment variable isolation.
  • src/git/test_utils/mod.rs — cleaned up to re-export TmpRepo and TmpFile from tmp_repo module; removed ~1300 lines of duplicated struct and method definitions.
  • Cargo.toml — removed serial_test dev-dependency.
  • src/commands/checkpoint_agent/opencode_preset.rs, src/commands/checkpoint_agent/agent_presets.rs, src/authorship/prompt_utils.rs — switched env reads to use env_test_proxy.
  • Tests updated: tests/github_copilot.rs, tests/opencode.rs, src/mdm/agents/codex.rs, and others to use test overrides instead of std::env::set_var.

Workflow Changes

  • .github/workflows/tests.yml - changed the testing tool to use 'cargo-nextest' for improved performance on integration tests. changed test workflow to perform unit and integration tests concurrently.

Notes & follow-ups

  • TmpRepo refactor: Extracted TmpRepo and TmpFile structs into their own file (src/git/test_utils/tmp_repo.rs) to improve code organization and added integrated unit tests (test_repo_specific_env_vars, test_env_vars_isolated_per_repo) that validate per-repo environment variable isolation. This matches the pattern of per-repo env injection used in TestRepo and supports parallel test execution.
  • These helpers are test-only; production behavior falls back to the real process environment when no override is set.

Open with Devin

stuartsessions and others added 19 commits February 15, 2026 11:53
… runs integration tests in parallel. Implemented in CI job for testing.
removed serial call from integration tests. Implemented nextest which…
…ars, run through mdm::utils::env_test_proxy, which should have no effect on actual functionality but would allow tests to run tests without setting the parent environment.
added env thread override for use by tests. Instead of checking env v…
…ons to interact with locally stored env vars. New processes also spin up with the installed env vars.
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 7 additional findings in Devin Review.

Open in Devin Review

Comment on lines +274 to +288
let mut env_vars = HashMap::new();
// Set test database path if not already set (for in-process unit tests)
// Store in local env_vars instead of global environment to avoid process-wide side effects

// Check if it's already in the process environment
if let Ok(db_path) = std::env::var("GIT_AI_TEST_DB_PATH") {
env_vars.insert("GIT_AI_TEST_DB_PATH".to_string(), db_path);
} else {
// Create a default path and store in local env_vars
let test_db_path = std::env::temp_dir().join("git-ai-unit-test-db");
env_vars.insert(
"GIT_AI_TEST_DB_PATH".to_string(),
test_db_path.to_string_lossy().to_string(),
);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 TmpRepo no longer sets GIT_AI_TEST_DB_PATH in the process environment, causing unit tests to hit the production database

The old TmpRepo::new() used unsafe { std::env::set_var("GIT_AI_TEST_DB_PATH", &test_db_path); } to set the env var in the process environment. The new code only stores it in the per-repo env_vars HashMap, which is only consumed by create_git_command() for spawning child processes.

Root Cause and Impact

TmpRepo is used for in-process unit tests (not subprocess-based integration tests). Functions called by these tests — commit_with_message()post_commit() and trigger_checkpoint_with_author()checkpoint() — invoke InternalDatabase::global() (src/authorship/internal_db.rs:349) which reads the env var via std::env::var("GIT_AI_TEST_DB_PATH"). Since the new code never sets this in the process environment, the database path falls back to the production path ~/.git-ai/internal/db.

// src/authorship/internal_db.rs:346-351
fn database_path() -> Result<PathBuf, GitAiError> {
    #[cfg(any(test, feature = "test-support"))]
    if let Ok(test_path) = std::env::var("GIT_AI_TEST_DB_PATH") {
        return Ok(PathBuf::from(test_path));
    }
    // falls back to ~/.git-ai/internal/db (production!)
}

Because InternalDatabase::global() uses OnceLock, the very first unit test to trigger it determines the path for the entire process. Every subsequent test in the same process will use that same (production) path.

There are dozens of unit tests across src/commands/checkpoint.rs, src/authorship/post_commit.rs, src/authorship/stats.rs, etc. that create a TmpRepo and call commit_with_message(), all of which depend on this env var being set.

Impact: Unit tests silently write to the real user's production database instead of an isolated test path, risking data corruption and causing non-deterministic test failures.

Prompt for agents
In src/git/test_utils/tmp_repo.rs, the TmpRepo::new() function (lines 273-313) needs to continue setting GIT_AI_TEST_DB_PATH in the process environment for in-process unit tests that call InternalDatabase::global(). The env_vars HashMap is only used for subprocess Command calls, but many unit tests call in-process functions (checkpoint, post_commit, blame) that read std::env::var("GIT_AI_TEST_DB_PATH") directly. Restore the unsafe std::env::set_var call (or use a thread-local override like the TEST_ENV_OVERRIDES approach in src/mdm/utils.rs, and update InternalDatabase::database_path() at src/authorship/internal_db.rs:349 to consult env_test_proxy instead of std::env::var). The simplest fix is to keep the original unsafe set_var behavior alongside the new env_vars storage, since unit tests already ran with that behavior.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@stuartsessions
Copy link
Author

The code comparison is functionally the same to what was pre-existing: if a process variable is found, use that. Otherwise, use temp_dir(). The unsafe variable set was in a conditional statement that only got reached if there wasn't an existing env var.

The "GIT_AI_TEST_DB_PATH" is a test var, so shouldn't be set in user's code.

@svarlamov svarlamov self-assigned this Feb 17, 2026
@svarlamov
Copy link
Member

Hey @stuartsessions thanks for the contribution! Watching the tests now -- is it possible that things actually got slower?

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.

Add test harness for setting env vars in test repo

3 participants