tests: keep single-layer and multilayer test data in separate dirs

This commit is contained in:
Mikolaj Wielgus 2024-06-06 14:49:50 +02:00
parent e574043c2f
commit eea1da604f
47 changed files with 250 additions and 163 deletions

View File

@ -1,78 +0,0 @@
use petgraph::{
unionfind::UnionFind,
visit::{EdgeRef, IntoEdgeReferences, NodeIndexable},
};
use std::{
fs::File,
sync::{Arc, Mutex},
};
use topola::{
autorouter::{invoker::Invoker, Autorouter},
dsn::design::DsnDesign,
graph::GetNodeIndex,
router::EmptyRouterObserver,
triangulation::GetTrianvertexIndex,
};
#[test]
fn test() {
let design = DsnDesign::load_from_file("tests/data/0603_breakout/0603_breakout.dsn").unwrap();
let mut invoker = Invoker::new(Autorouter::new(design.make_board()).unwrap());
let file = File::open("tests/data/0603_breakout/autoroute_all.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let mut unionfind = UnionFind::new(
invoker
.autorouter()
.board()
.layout()
.drawing()
.geometry()
.graph()
.node_bound(),
);
for edge in invoker
.autorouter()
.board()
.layout()
.drawing()
.geometry()
.graph()
.edge_references()
{
unionfind.union(edge.source(), edge.target());
}
assert_eq!(
invoker
.autorouter()
.ratsnest()
.graph()
.edge_indices()
.collect::<Vec<_>>()
.len(),
2
);
for ratline in invoker.autorouter().ratsnest().graph().edge_references() {
let from_index = invoker
.autorouter()
.ratsnest()
.graph()
.node_weight(ratline.source())
.unwrap()
.trianvertex_index()
.node_index();
let to_index = invoker
.autorouter()
.ratsnest()
.graph()
.node_weight(ratline.target())
.unwrap()
.trianvertex_index()
.node_index();
assert_eq!(unionfind.find(from_index), unionfind.find(to_index));
}
}

114
tests/common/mod.rs Normal file
View File

@ -0,0 +1,114 @@
use petgraph::{unionfind::UnionFind, visit::NodeIndexable};
use topola::{
autorouter::{board::Board, Autorouter},
drawing::{
graph::{GetLayer, GetMaybeNet},
rules::RulesTrait,
},
graph::GetNodeIndex,
};
pub fn assert_single_layer_groundless_autoroute(
autorouter: &mut Autorouter<impl RulesTrait>,
layername: &str,
) {
for ratline in autorouter.ratsnest().graph().edge_indices() {
// Accessing endpoints may create new dots because apex construction is lazy, so we access
// tem all before starting unionfind, as it requires a constant index bound.
let _ = autorouter.ratline_endpoints(ratline);
}
let mut unionfind = UnionFind::new(
autorouter
.board()
.layout()
.drawing()
.geometry()
.graph()
.node_bound(),
);
for primitive in autorouter.board().layout().drawing().primitive_nodes() {
for joined in autorouter
.board()
.layout()
.drawing()
.geometry()
.joineds(primitive)
{
unionfind.union(primitive.node_index(), joined.node_index());
}
}
for ratline in autorouter.ratsnest().graph().edge_indices() {
let (source_dot, target_dot) = autorouter.ratline_endpoints(ratline);
let source_layer = autorouter
.board()
.layout()
.drawing()
.primitive(source_dot)
.layer();
let target_layer = autorouter
.board()
.layout()
.drawing()
.primitive(target_dot)
.layer();
if let (Some(source_layername), Some(target_layername)) = (
autorouter.board().layername(source_layer),
autorouter.board().layername(target_layer),
) {
dbg!(source_layername, target_layername);
assert_eq!(source_layername, target_layername);
if source_layername != layername {
continue;
}
} else {
assert!(false);
}
let source_net = autorouter
.board()
.layout()
.drawing()
.primitive(source_dot)
.maybe_net();
let target_net = autorouter
.board()
.layout()
.drawing()
.primitive(target_dot)
.maybe_net();
dbg!(source_net, target_net);
assert_eq!(source_net, target_net);
let net = source_net.unwrap();
if let Some(netname) = autorouter.board().netname(net) {
// We don't route ground.
if netname != "GND" {
dbg!(source_dot, target_dot);
assert_eq!(
unionfind.find(source_dot.node_index()),
unionfind.find(target_dot.node_index())
);
}
}
}
}
pub fn assert_band_length(
board: &Board<impl RulesTrait>,
source: &str,
target: &str,
length: f64,
epsilon: f64,
) {
let band = board.band_between_pins(source, target).unwrap();
let band_length = board.layout().band_length(band);
dbg!(band_length);
assert!((band_length - length).abs() < epsilon);
}

View File

@ -1,32 +0,0 @@
use std::fs::File;
use petgraph::{
unionfind::UnionFind,
visit::{EdgeRef, IntoEdgeReferences, NodeIndexable},
};
use topola::{
autorouter::{invoker::Invoker, Autorouter},
drawing::graph::GetMaybeNet,
dsn::design::DsnDesign,
graph::GetNodeIndex,
triangulation::GetTrianvertexIndex,
};
mod common;
#[test]
fn test() {
let design = DsnDesign::load_from_file(
"tests/data/four_3rd_order_smd_lc_filters/four_3rd_order_smd_lc_filters.dsn",
);
let board = design.unwrap().make_board();
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
let file =
File::open("tests/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let (mut autorouter, ..) = invoker.destruct();
common::assert_single_layer_groundless_autoroute(&mut autorouter, "F.Cu");
}

119
tests/single_layer.rs Normal file
View File

@ -0,0 +1,119 @@
use std::fs::File;
use petgraph::{
unionfind::UnionFind,
visit::{EdgeRef, IntoEdgeReferences, NodeIndexable},
};
use topola::{
autorouter::{invoker::Invoker, Autorouter},
drawing::{
graph::{GetLayer, GetMaybeNet},
primitive::GetInnerOuter,
},
dsn::design::DsnDesign,
graph::GetNodeIndex,
layout::NodeIndex,
triangulation::GetTrianvertexIndex,
};
mod common;
#[test]
fn test_0603_breakout() {
let design =
DsnDesign::load_from_file("tests/single_layer/data/0603_breakout/0603_breakout.dsn")
.unwrap();
let mut invoker = Invoker::new(Autorouter::new(design.make_board()).unwrap());
let file = File::open("tests/single_layer/data/0603_breakout/autoroute_all.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let mut unionfind = UnionFind::new(
invoker
.autorouter()
.board()
.layout()
.drawing()
.geometry()
.graph()
.node_bound(),
);
for edge in invoker
.autorouter()
.board()
.layout()
.drawing()
.geometry()
.graph()
.edge_references()
{
unionfind.union(edge.source(), edge.target());
}
assert_eq!(
invoker
.autorouter()
.ratsnest()
.graph()
.edge_indices()
.collect::<Vec<_>>()
.len(),
2
);
for ratline in invoker.autorouter().ratsnest().graph().edge_references() {
let from_index = invoker
.autorouter()
.ratsnest()
.graph()
.node_weight(ratline.source())
.unwrap()
.trianvertex_index()
.node_index();
let to_index = invoker
.autorouter()
.ratsnest()
.graph()
.node_weight(ratline.target())
.unwrap()
.trianvertex_index()
.node_index();
assert_eq!(unionfind.find(from_index), unionfind.find(to_index));
}
}
#[test]
fn test_tht_diode_bridge_rectifier() {
let design = DsnDesign::load_from_file(
"tests/single_layer/data/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn",
);
let board = design.unwrap().make_board();
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
let file =
File::open("tests/single_layer/data/tht_diode_bridge_rectifier/autoroute_all.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let (mut autorouter, ..) = invoker.destruct();
common::assert_single_layer_groundless_autoroute(&mut autorouter, "F.Cu");
common::assert_band_length(autorouter.board(), "J2-2", "D4-2", 15511.0, 0.5);
}
#[test]
fn test_four_3rd_order_smd_lc_filters() {
let design = DsnDesign::load_from_file(
"tests/single_layer/data/four_3rd_order_smd_lc_filters/four_3rd_order_smd_lc_filters.dsn",
);
let board = design.unwrap().make_board();
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
let file =
File::open("tests/single_layer/data/four_3rd_order_smd_lc_filters/autoroute_signals.cmd")
.unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let (mut autorouter, ..) = invoker.destruct();
common::assert_single_layer_groundless_autoroute(&mut autorouter, "F.Cu");
}

View File

@ -0,0 +1 @@
{"hostname":"luckmann","username":"mikolaj"}

View File

@ -1,4 +1,4 @@
(pcb /home/mikolaj/proj/topola/tests/data/single_layer_tht_diode_bridge_rectifier/single_layer_tht_diode_bridge_rectifier.dsn
(pcb /home/mikolaj/proj/topola/tests/data/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn
(parser
(string_quote ")
(space_in_quoted_tokens on)

View File

@ -177,7 +177,7 @@
(property ki_fp_filters "D*Bridge* D*Rectifier*")
(path "/43ab64df-926a-4e01-8a98-67d2c800c849")
(sheetname "Root")
(sheetfile "single_layer_tht_diode_bridge_rectifier.kicad_sch")
(sheetfile "tht_diode_bridge_rectifier.kicad_sch")
(attr through_hole)
(fp_line
(start 9 1.92)
@ -559,7 +559,7 @@
(property ki_fp_filters "D*Bridge* D*Rectifier*")
(path "/aae449ee-03c9-4537-996f-100e098107e1")
(sheetname "Root")
(sheetfile "single_layer_tht_diode_bridge_rectifier.kicad_sch")
(sheetfile "tht_diode_bridge_rectifier.kicad_sch")
(attr through_hole)
(fp_line
(start 1.16 -1.92)
@ -915,7 +915,7 @@
(property ki_fp_filters "TerminalBlock*:*")
(path "/33bb9157-e6b0-4858-a7ac-9a21f6b6b928")
(sheetname "Root")
(sheetfile "single_layer_tht_diode_bridge_rectifier.kicad_sch")
(sheetfile "tht_diode_bridge_rectifier.kicad_sch")
(attr through_hole)
(fp_line
(start 7.62 -3.81)
@ -1169,7 +1169,7 @@
(property ki_fp_filters "TerminalBlock*:*")
(path "/ae531f5f-c43e-4c22-8182-faed35881b46")
(sheetname "Root")
(sheetfile "single_layer_tht_diode_bridge_rectifier.kicad_sch")
(sheetfile "tht_diode_bridge_rectifier.kicad_sch")
(attr through_hole)
(fp_line
(start -2.54 3.81)
@ -1449,7 +1449,7 @@
(property ki_fp_filters "D*Bridge* D*Rectifier*")
(path "/12bc0990-5e61-4c01-a094-e653d3a60893")
(sheetname "Root")
(sheetfile "single_layer_tht_diode_bridge_rectifier.kicad_sch")
(sheetfile "tht_diode_bridge_rectifier.kicad_sch")
(attr through_hole)
(fp_line
(start 1.16 -1.92)
@ -1831,7 +1831,7 @@
(property ki_fp_filters "D*Bridge* D*Rectifier*")
(path "/1f9b7479-94b6-46d1-90eb-c315c0b77b34")
(sheetname "Root")
(sheetfile "single_layer_tht_diode_bridge_rectifier.kicad_sch")
(sheetfile "tht_diode_bridge_rectifier.kicad_sch")
(attr through_hole)
(fp_line
(start 9 1.92)

View File

@ -74,7 +74,7 @@
"ssh_key": ""
},
"meta": {
"filename": "single_layer_tht_diode_bridge_rectifier.kicad_prl",
"filename": "tht_diode_bridge_rectifier.kicad_prl",
"version": 3
},
"project": {

View File

@ -430,7 +430,7 @@
"pinned_symbol_libs": []
},
"meta": {
"filename": "single_layer_tht_diode_bridge_rectifier.kicad_pro",
"filename": "tht_diode_bridge_rectifier.kicad_pro",
"version": 1
},
"net_settings": {
@ -467,7 +467,7 @@
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "single_layer_tht_diode_bridge_rectifier.dsn",
"specctra_dsn": "tht_diode_bridge_rectifier.dsn",
"step": "",
"svg": "",
"vrml": ""

View File

@ -622,7 +622,7 @@
(uuid "eb13c935-c65a-4af4-91d0-e1c7f144534f")
)
(instances
(project "single_layer_tht_diode_bridge_rectifier"
(project "tht_diode_bridge_rectifier"
(path "/71099ece-09c5-443c-9dd7-b57178821ade"
(reference "D4")
(unit 1)
@ -708,7 +708,7 @@
(uuid "55798640-e0b9-4318-88ae-05a588dcc8de")
)
(instances
(project "single_layer_tht_diode_bridge_rectifier"
(project "tht_diode_bridge_rectifier"
(path "/71099ece-09c5-443c-9dd7-b57178821ade"
(reference "D2")
(unit 1)
@ -775,7 +775,7 @@
(uuid "76873a01-09a0-41b5-a565-c34fa72949b4")
)
(instances
(project "single_layer_tht_diode_bridge_rectifier"
(project "tht_diode_bridge_rectifier"
(path "/71099ece-09c5-443c-9dd7-b57178821ade"
(reference "J2")
(unit 1)
@ -863,7 +863,7 @@
(uuid "b88d0fbd-eb5d-4478-bc85-190a180d8763")
)
(instances
(project "single_layer_tht_diode_bridge_rectifier"
(project "tht_diode_bridge_rectifier"
(path "/71099ece-09c5-443c-9dd7-b57178821ade"
(reference "D3")
(unit 1)
@ -950,7 +950,7 @@
(uuid "0215e937-8c55-4ec8-aadd-547f2b1cb992")
)
(instances
(project "single_layer_tht_diode_bridge_rectifier"
(project "tht_diode_bridge_rectifier"
(path "/71099ece-09c5-443c-9dd7-b57178821ade"
(reference "D1")
(unit 1)
@ -1019,7 +1019,7 @@
(uuid "3fa85bee-cae3-47ab-a12d-2dccf43e2d48")
)
(instances
(project "single_layer_tht_diode_bridge_rectifier"
(project "tht_diode_bridge_rectifier"
(path "/71099ece-09c5-443c-9dd7-b57178821ade"
(reference "J1")
(unit 1)

View File

@ -1,37 +0,0 @@
use std::fs::File;
use petgraph::{
unionfind::UnionFind,
visit::{EdgeRef, IntoEdgeReferences, NodeIndexable},
};
use topola::{
autorouter::{invoker::Invoker, Autorouter},
drawing::{
graph::{GetLayer, GetMaybeNet},
primitive::GetInnerOuter,
},
dsn::design::DsnDesign,
graph::GetNodeIndex,
layout::NodeIndex,
triangulation::GetTrianvertexIndex,
};
mod common;
#[test]
fn test() {
let design = DsnDesign::load_from_file(
"tests/data/single_layer_tht_diode_bridge_rectifier/single_layer_tht_diode_bridge_rectifier.dsn",
);
let board = design.unwrap().make_board();
let mut invoker = Invoker::new(Autorouter::new(board).unwrap());
let file =
File::open("tests/data/single_layer_tht_diode_bridge_rectifier/autoroute_all.cmd").unwrap();
invoker.replay(serde_json::from_reader(file).unwrap());
let (mut autorouter, ..) = invoker.destruct();
common::assert_single_layer_groundless_autoroute(&mut autorouter, "F.Cu");
common::assert_band_length(autorouter.board(), "J2-2", "D4-2", 15511.0, 0.5);
}