ReplicateLayout/test_replicate_layout.py

162 lines
6.7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import unittest
import pcbnew
import logging
import sys
import os
from compare_boards import compare_boards
from replicate_layout import Replicator
from replicate_layout import Settings
def update_progress(stage, percentage, message=None):
print(stage)
print(percentage)
if message is not None:
print(message)
def test_file(in_filename, test_filename, src_anchor_fp_reference, level, sheets, containing, remove, by_group):
board = pcbnew.LoadBoard(in_filename)
# get board information
replicator = Replicator(board, src_anchor_fp_reference, update_progress)
# get source footprint info
src_anchor_fp = replicator.get_fp_by_ref(src_anchor_fp_reference)
# check if there are at least two sheets pointing to same hierarchical file that the source anchor footprint belongs to
count = 0
for filename in replicator.dict_of_sheets.values():
if filename[1] in src_anchor_fp.filename:
count = count + 1
if count < 2:
raise Exception
# check if source anchor footprint is on root leve
if len(src_anchor_fp.filename) == 0:
raise Exception
# have the user select replication level
levels = src_anchor_fp.filename
# get the level index from user
index = levels.index(levels[level])
# get list of sheets
sheet_list = replicator.get_sheets_to_replicate(src_anchor_fp, src_anchor_fp.sheet_id[index])
# get anchor footprints
anchor_footprints = replicator.get_list_of_footprints_with_same_id(src_anchor_fp.fp_id)
# find matching anchors to matching sheets
ref_list = []
for sheet in sheet_list:
for fp in anchor_footprints:
a = sheet
b = fp.sheet_id
if sheet == fp.sheet_id:
ref_list.append(fp.ref)
break
# get the list selection from user
dst_sheets = [sheet_list[i] for i in sheets]
settings = Settings(rep_tracks=True, rep_zones=True, rep_text=True, rep_drawings=True,
rep_locked_tracks=True, rep_locked_zones=True, rep_locked_text=True, rep_locked_drawings=True,
intersecting=not containing,
group_items=True,
group_only=False, locked_fps=False,
remove=False)
(fps, items) = replicator.highlight_set_level(src_anchor_fp.sheet_id[0:index + 1],
settings)
replicator.highlight_clear_level(fps, items)
# now we are ready for replication
replicator.replicate_layout(src_anchor_fp, src_anchor_fp.sheet_id[0:index + 1], dst_sheets,
settings, rm_duplicates=True)
out_filename = test_filename.replace("ref", "temp")
pcbnew.SaveBoard(out_filename, board)
# test for connectivity isuues
if replicator.connectivity_issues:
report_string = ""
for item in replicator.connectivity_issues:
report_string = report_string + f"Footprint {item[0]}, pad {item[1]}\n"
print(f"Make sure that you check the connectivity around:\n" + report_string)
return compare_boards(out_filename, test_filename)
class connectivity(unittest.TestCase):
def setUp(self):
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "connectivity_test"))
def test_inner(self):
logger.info("Testing text placement")
input_filename = 'connectivity_test.kicad_pcb'
test_filename = input_filename.split('.')[0] + "_ref_inner" + ".kicad_pcb"
err = test_file(input_filename, test_filename, 'U301', level=1, sheets=(2,),
containing=False, remove=True, by_group=True)
# self.assertEqual(err, 0, "inner levels failed")
@unittest.SkipTest
class TestText(unittest.TestCase):
def setUp(self):
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "replicate_layout_fp_text"))
def test_inner(self):
logger.info("Testing text placement")
input_filename = 'replicate_layout_fp_text.kicad_pcb'
test_filename = input_filename.split('.')[0] + "_ref_inner" + ".kicad_pcb"
err = test_file(input_filename, test_filename, 'R201', level=0, sheets=(0, 1),
containing=False, remove=True, by_group=True)
# self.assertEqual(err, 0, "inner levels failed")
@unittest.SkipTest
class TestOfficial(unittest.TestCase):
def setUp(self):
os.chdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), "replicate_layout_test_project"))
def test_inner(self):
logger.info("Testing multiple hierarchy - inner levels")
input_filename = 'replicate_layout_test_project.kicad_pcb'
test_filename = input_filename.split('.')[0] + "_ref_inner" + ".kicad_pcb"
err = test_file(input_filename, test_filename, 'Q301', level=1, sheets=(1, 3),
containing=False, remove=False, by_group=True)
self.assertEqual(err, 0, "inner levels failed")
def test_inner_level(self):
logger.info("Testing multiple hierarchy - inner levels source on a different hierarchical level")
input_filename = 'replicate_layout_test_project.kicad_pcb'
test_filename = input_filename.split('.')[0] + "_ref_inner_alt" + ".kicad_pcb"
err = test_file(input_filename, test_filename, 'Q1401', level=0, sheets=(2, 3),
containing=False, remove=False, by_group=False)
self.assertEqual(err, 0, "inner levels from bottom failed")
def test_outer(self):
logger.info("Testing multiple hierarchy - outer levels")
input_filename = 'replicate_layout_test_project.kicad_pcb'
test_filename = input_filename.split('.')[0] + "_ref_outer" + ".kicad_pcb"
err = test_file(input_filename, test_filename, 'Q301', level=0, sheets=(0, 1),
containing=False, remove=False, by_group=False)
self.assertEqual(err, 0, "outer levels failed")
# for testing purposes only
if __name__ == "__main__":
file_handler = logging.FileHandler(filename='replicate_layout.log', mode='w')
stdout_handler = logging.StreamHandler(sys.stdout)
handlers = [file_handler, stdout_handler]
logging_level = logging.INFO
logging.basicConfig(level=logging_level,
format='%(asctime)s %(name)s %(lineno)d:%(message)s',
datefmt='%m-%d %H:%M:%S',
handlers=handlers
)
logger = logging.getLogger(__name__)
logger.info("Plugin executed on: " + repr(sys.platform))
logger.info("Plugin executed with python version: " + repr(sys.version))
logger.info("KiCad build version: " + str(pcbnew.GetBuildVersion()))
unittest.main()