| 260 | } |
| 261 | |
| 262 | async fn start_fixture(seed_durable_events: bool) -> Fixture { |
| 263 | let tmp = TempDir::new().expect("temp dir"); |
| 264 | let project_root = tmp.path().join("project"); |
| 265 | std::fs::create_dir_all(&project_root).expect("project dir"); |
| 266 | std::fs::write( |
| 267 | project_root.join("lib.rs"), |
| 268 | "pub fn analytics_fixture() {}\n", |
| 269 | ) |
| 270 | .expect("seed source file"); |
| 271 | |
| 272 | let global_db_path = tmp.path().join("global").join("global.db"); |
| 273 | let env_guard = EnvVarGuard::set("TRACEDECAY_GLOBAL_DB", &global_db_path); |
| 274 | // Pre-create both GlobalDb-schema stores from the cached empty template |
| 275 | // so seeding and dashboard startup open existing DBs instead of paying a |
| 276 | // full schema creation each (slow on Windows). |
| 277 | write_empty_global_db_schema(&global_db_path).await; |
| 278 | let cg = TraceDecay::init(&project_root) |
| 279 | .await |
| 280 | .expect("tracedecay init"); |
| 281 | let session_db_path = project_session_db_path(&project_root); |
| 282 | write_empty_global_db_schema(&session_db_path).await; |
| 283 | seed_session_store(&session_db_path, &project_root).await; |
| 284 | if seed_durable_events { |
| 285 | seed_durable_analytics(&global_db_path, &project_root).await; |
| 286 | } |
| 287 | |
| 288 | let port = pick_free_port(); |
| 289 | let base_url = format!("http://127.0.0.1:{port}"); |
| 290 | let server = tokio::spawn(async move { |
| 291 | let _ = dashboard::run(&cg, "127.0.0.1", port, false).await; |
| 292 | }); |
| 293 | wait_for_dashboard(&http_agent(), &base_url).await; |
| 294 | |
| 295 | Fixture { |
| 296 | _tmp: tmp, |
| 297 | _env_guard: env_guard, |
| 298 | base_url, |
| 299 | server, |
| 300 | project_root, |
| 301 | global_db_path, |
| 302 | session_db_path, |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | fn find_row<'a>(rows: &'a Value, key: &str, value: &str) -> &'a Value { |
| 307 | rows.as_array() |