import json from gausse.optim.search_space import SearchBounds, genome_from_dict from gausse.optim.sweep import MODEL_VERSION, run_sweep from gausse.storage.database import count_runs, fetch_runs, open_connection def test_sweep_runs_all_seeds_and_records_everything(tmp_path): db_path = tmp_path / "runs.sqlite3" bounds = SearchBounds(max_stages=2) # маленькое пространство -> быстрый тест summary = run_sweep(db_path, n_runs=12, bounds=bounds, n_workers=2, seed=123) assert summary["n_runs"] == 12 conn = open_connection(db_path) assert count_runs(conn) == 12 # хотя бы какие-то честно попали и в успех, и в провал -- иначе тест # пространства слишком узкий/широкий, чтобы быть показательным rows = fetch_runs(conn) assert len(rows) == 12 for row in rows: assert row.search_mode == "sweep" assert row.model_version == MODEL_VERSION # genome_json должен быть валидным и декодируемым геномом genome = genome_from_dict(json.loads(row.genome_json)) assert len(genome.stages) >= 1 summary_dict = json.loads(row.decoded_summary_json) assert "stages" in summary_dict if row.feasible: assert row.efficiency is not None assert row.infeasible_reason is None else: assert row.infeasible_reason is not None assert row.efficiency is None conn.close() def test_sweep_is_deterministic_given_same_seed(tmp_path): bounds = SearchBounds(max_stages=2) db_path_a = tmp_path / "a.sqlite3" db_path_b = tmp_path / "b.sqlite3" run_sweep(db_path_a, n_runs=8, bounds=bounds, n_workers=1, seed=42) run_sweep(db_path_b, n_runs=8, bounds=bounds, n_workers=1, seed=42) conn_a = open_connection(db_path_a) conn_b = open_connection(db_path_b) rows_a = sorted(fetch_runs(conn_a), key=lambda r: r.genome_json) rows_b = sorted(fetch_runs(conn_b), key=lambda r: r.genome_json) assert [r.genome_json for r in rows_a] == [r.genome_json for r in rows_b] assert [r.efficiency for r in rows_a] == [r.efficiency for r in rows_b] conn_a.close() conn_b.close()