Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/execution/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ pub struct Scheduler {
hook_registry: HookRegistry,
/// Project root directory for resolving hook paths
project_root: PathBuf,
/// Reuse existing test database (--reuse-db)
reuse_db: bool,
/// Force recreation of test database (--create-db)
create_db: bool,
}

impl Scheduler {
Expand All @@ -143,6 +147,8 @@ impl Scheduler {
None,
hook_registry,
project_root,
false,
false,
)
}

Expand All @@ -165,6 +171,8 @@ impl Scheduler {
None,
hook_registry,
project_root,
false,
false,
)
}

Expand All @@ -179,6 +187,8 @@ impl Scheduler {
timeout_hook: Option<String>,
hook_registry: HookRegistry,
project_root: PathBuf,
reuse_db: bool,
create_db: bool,
) -> Result<Self> {
let max_workers = log_capture.slot_count();

Expand All @@ -202,6 +212,8 @@ impl Scheduler {
timeout_hook,
hook_registry,
project_root,
reuse_db,
create_db,
})
}

Expand Down Expand Up @@ -518,8 +530,8 @@ impl Scheduler {
cached_effects,
markers: test.markers.clone(),
marker_info: test.marker_info.clone(),
reuse_db: false,
create_db: false,
reuse_db: self.reuse_db,
create_db: self.create_db,
};

// Use encode_with_length which includes protocol header
Expand Down
34 changes: 22 additions & 12 deletions src/execution/zygote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,10 @@ pub fn entrypoint(cmd_socket: UnixStream, result_socket: UnixStream) -> Result<(
}

// Django Detection & Setup (Batteries-Included)
// Initialize Django in Zygote so workers inherit the pre-warmed state
// Initialize Django in Zygote so workers inherit the pre-warmed state.
// NOTE: We do NOT warm up DB connections here. setup_databases() creates
// a test DB after init_session(), and connections are closed before fork
// so workers get fresh file descriptors.
py.run(
c_str!(r#"
import os
Expand All @@ -670,20 +673,9 @@ import sys
try:
import django

# Check if DJANGO_SETTINGS_MODULE is already set
if 'DJANGO_SETTINGS_MODULE' in os.environ:
django.setup()
print(f'[tach:zygote] Django initialized: {os.environ["DJANGO_SETTINGS_MODULE"]}', file=sys.stderr)

# CRITICAL: Warm up DB connections before forking
# File descriptors must exist in Zygote to be inherited by workers
try:
from django.db import connections
for alias in connections:
connections[alias].ensure_connection()
print(f'[tach:zygote] Django DB connections warmed up', file=sys.stderr)
except Exception as e:
print(f'[tach:zygote] Django DB warmup failed: {e}', file=sys.stderr)
except ImportError:
pass # Django not installed, skip
except Exception as e:
Expand All @@ -708,6 +700,24 @@ except Exception as e:
let target_path = std::env::var("TACH_TARGET_PATH").unwrap_or_else(|_| cwd_str.clone());
harness.getattr("init_session")?.call1((&target_path,))?;

// Django Test Database: Create test DB after pytest is configured but
// before workers fork. Reads TACH_REUSE_DB/TACH_CREATE_DB env vars.
// Connections are closed before fork so workers get fresh FDs.
py.run(
c_str!(
r#"
try:
import tach_harness
tach_harness._setup_django_test_db()
except Exception as e:
import sys
print(f'[tach:zygote] Django test DB setup error: {e}', file=sys.stderr)
"#
),
None,
None,
)?;

// HOOK EFFECT BRIDGE (v0.2.0): Retrieve session effects from Python
// After init_session(), Python has recorded effects in _SESSION_HOOK_EFFECTS.
// We retrieve them here and will send them to the Supervisor for HookRegistry population.
Expand Down
11 changes: 11 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ fn main() -> Result<()> {
// SAFETY: Same as above - called before worker threads spawn.
unsafe { std::env::set_var("TACH_TARGET_PATH", &cli.path) };

// Set Django test DB flags for Zygote to read during setup_databases()
// SAFETY: Same as above - called before worker threads spawn.
if cli.reuse_db {
unsafe { std::env::set_var("TACH_REUSE_DB", "1") };
}
if cli.create_db {
unsafe { std::env::set_var("TACH_CREATE_DB", "1") };
}

// --- LIFECYCLE SETUP ---
debugger::install_panic_hook();

Expand Down Expand Up @@ -1160,6 +1169,8 @@ fn run_tests(
timeout_hook,
hook_registry,
project_root,
std::env::var("TACH_REUSE_DB").unwrap_or_default() == "1",
std::env::var("TACH_CREATE_DB").unwrap_or_default() == "1",
)?;

let stats = scheduler.run(runnable_tests, reporter)?;
Expand Down
Loading