#[cfg(test)]
mod tests {
use std::path::PathBuf;
use gen_models::sample::Sample;
use gen_tui::{
graph_controller::{GraphConfig, GraphController},
layout::{NodeRole, VisualDetail},
partition_table::PartitionConfig,
};
use petgraph::visit::Dfs;
use crate::{
imports::gfa::import_gfa, test_helpers::setup_gen, track_database,
views::gen_graph_widget::GenGraphNodeSizer,
};
#[test]
fn test_source_to_sink_connectivity() {
let context = setup_gen();
let conn = context.graph().conn();
let op_conn = context.operations().conn();
let gfa_path = PathBuf::from("fixtures/anderson_promoters.gfa");
if !gfa_path.exists() {
println!("⚠️ Anderson GFA file not found, skipping connectivity test");
return;
}
let collection_name = "/";
track_database(conn, op_conn).expect("Failed to track database");
import_gfa(&context, &gfa_path, collection_name, Sample::DEFAULT_NAME)
.expect("GFA import failed");
let gen_graph = Sample::get_graph(conn, collection_name, Sample::DEFAULT_NAME);
let config = GraphConfig {
partition: PartitionConfig {
layer_count: 5,
node_count: usize::MAX,
},
..Default::default()
};
let node_sizer = GenGraphNodeSizer;
let mut controller = GraphController::new_with_config(gen_graph, node_sizer, config);
controller.set_anchor_partition(0).unwrap();
let total_partitions = controller
.partition_controller
.partition_table
.partitions
.len();
for i in 0..total_partitions {
let _ = controller.ensure_partition_loaded(i);
}
let unified_graph = controller
.partition_controller
.partition_table
.get_unified_layout(VisualDetail::Minimal);
println!(
"Testing source-to-sink connectivity in unified graph with {} nodes and {} edges across {} partitions",
unified_graph.node_count(),
unified_graph.edge_count(),
total_partitions
);
use petgraph::{Direction, visit::NodeIndexable};
let mut source_nodes = Vec::new(); let mut sink_nodes = Vec::new(); let mut all_data_nodes = Vec::new();
for node_idx in unified_graph.node_indices() {
if let Some(node) = unified_graph.node_weight(node_idx) {
if let NodeRole::Data(original_node_idx) = &node.role {
all_data_nodes.push((node_idx, original_node_idx));
}
}
}
for (_unified_idx, original_idx) in &all_data_nodes {
let original_node_id = gen_graph.from_index(original_idx.index());
let incoming = gen_graph
.neighbors_directed(original_node_id, Direction::Incoming)
.count();
let outgoing = gen_graph
.neighbors_directed(original_node_id, Direction::Outgoing)
.count();
if incoming == 0 {
source_nodes.push(*original_idx);
}
if outgoing == 0 {
sink_nodes.push(*original_idx);
}
}
println!("Original graph analysis:");
println!(" Total data nodes: {}", all_data_nodes.len());
println!(" Source nodes (no incoming): {}", source_nodes.len());
println!(" Sink nodes (no outgoing): {}", sink_nodes.len());
if source_nodes.is_empty() || sink_nodes.is_empty() {
println!(
"⚠️ No clear sources or sinks found - graph may be cyclic or all nodes are intermediate"
);
return;
}
let mut successful_paths = 0;
let mut total_paths_tested = 0;
for &source_original in &source_nodes {
let source_unified = all_data_nodes
.iter()
.find(|(_, orig)| *orig == source_original)
.map(|(unified, _)| *unified);
if let Some(source_node) = source_unified {
for &sink_original in &sink_nodes {
let sink_unified = all_data_nodes
.iter()
.find(|(_, orig)| *orig == sink_original)
.map(|(unified, _)| *unified);
if let Some(sink_node) = sink_unified {
total_paths_tested += 1;
let mut dfs = Dfs::new(unified_graph, source_node);
let mut found_sink = false;
while let Some(node) = dfs.next(unified_graph) {
if node == sink_node {
found_sink = true;
break;
}
}
if found_sink {
successful_paths += 1;
}
}
}
}
}
println!("Source-to-sink connectivity results:");
println!(" Paths tested: {}", total_paths_tested);
println!(" Successful paths: {}", successful_paths);
if total_paths_tested > 0 {
let success_rate = successful_paths as f64 / total_paths_tested as f64;
println!(" Success rate: {:.1}%", success_rate * 100.0);
assert!(
success_rate >= 0.8,
"Source-to-sink connectivity rate {:.1}% is too low - partition stitching may have broken connections. NOTE: This test is deprecated due to edge labeling bugs.",
success_rate * 100.0
);
println!(
"✅ Source-to-sink connectivity test passed - unified graph preserves original connectivity (DEPRECATED - see edge_label_validation_test)"
);
} else {
println!("⚠️ No source-to-sink paths could be tested");
}
}
}