You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
8.3 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, you may find one here:
  18. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  19. * or you may search the http://www.gnu.org website for the version 2 license,
  20. * or you may write to the Free Software Foundation, Inc.,
  21. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  22. */
  23. #include <qa_utils/wx_utils/unit_test_utils.h>
  24. #include <qa/pcbnew/board_test_utils.h>
  25. #include <board.h>
  26. #include <board_commit.h>
  27. #include <board_design_settings.h>
  28. #include <connectivity/connectivity_data.h>
  29. #include <tracks_cleaner.h>
  30. #include <cleanup_item.h>
  31. #include <drc/drc_item.h>
  32. #include <settings/settings_manager.h>
  33. #include <tool/tool_manager.h>
  34. struct TRACK_CLEANER_TEST_FIXTURE
  35. {
  36. TRACK_CLEANER_TEST_FIXTURE() :
  37. m_settingsManager( true /* headless */ )
  38. { }
  39. SETTINGS_MANAGER m_settingsManager;
  40. std::unique_ptr<BOARD> m_board;
  41. };
  42. struct TEST_DESCRIPTION
  43. {
  44. wxString m_File;
  45. bool m_Shorts;
  46. bool m_RedundantVias;
  47. bool m_RedundantTracks;
  48. bool m_DanglingTracks;
  49. bool m_TracksInPads;
  50. bool m_DanglingVias;
  51. int m_Expected;
  52. };
  53. BOOST_FIXTURE_TEST_CASE( FailedToCleanRegressionTests, TRACK_CLEANER_TEST_FIXTURE )
  54. {
  55. /*
  56. * This one ensures that certain cleanup items are indeed found and marked for cleanup.
  57. */
  58. std::vector<TEST_DESCRIPTION> tests =
  59. {
  60. // short redundant redundant dangling tracks dangling
  61. // circuits vias tracks tracks in pads vias expected
  62. { "issue2904", false, false, false, true, false, false, 9 },
  63. { "issue5093", false, false, false, false, true, false, 118 },
  64. { "issue7004", false, true, false, false, false, true, 25 },
  65. { "issue8883", true, true, true, true, false, true, 80 }
  66. };
  67. for( const TEST_DESCRIPTION& entry : tests )
  68. {
  69. KI_TEST::LoadBoard( m_settingsManager, entry.m_File, m_board );
  70. KI_TEST::FillZones( m_board.get(), 6 );
  71. m_board->GetConnectivity()->RecalculateRatsnest();
  72. TOOL_MANAGER toolMgr;
  73. toolMgr.SetEnvironment( m_board.get(), nullptr, nullptr, nullptr, nullptr );
  74. BOARD_COMMIT commit( &toolMgr );
  75. TRACKS_CLEANER cleaner( m_board.get(), commit );
  76. std::vector< std::shared_ptr<CLEANUP_ITEM> > dryRunItems;
  77. std::vector< std::shared_ptr<CLEANUP_ITEM> > realRunItems;
  78. cleaner.CleanupBoard( true, &dryRunItems, entry.m_Shorts,
  79. entry.m_RedundantVias,
  80. entry.m_RedundantTracks,
  81. entry.m_DanglingTracks,
  82. entry.m_TracksInPads,
  83. entry.m_DanglingVias );
  84. cleaner.CleanupBoard( true, &realRunItems, entry.m_Shorts,
  85. entry.m_RedundantVias,
  86. entry.m_RedundantTracks,
  87. entry.m_DanglingTracks,
  88. entry.m_TracksInPads,
  89. entry.m_DanglingVias );
  90. if( dryRunItems.size() == entry.m_Expected && realRunItems.size() == entry.m_Expected )
  91. {
  92. BOOST_CHECK_EQUAL( 1, 1 ); // quiet "did not check any assertions" warning
  93. BOOST_TEST_MESSAGE( wxString::Format( "Track cleaner regression: %s, passed",
  94. entry.m_File ) );
  95. }
  96. else
  97. {
  98. BOOST_CHECK_EQUAL( dryRunItems.size(), entry.m_Expected );
  99. BOOST_CHECK_EQUAL( realRunItems.size(), entry.m_Expected );
  100. std::map<KIID, EDA_ITEM*> itemMap;
  101. m_board->FillItemMap( itemMap );
  102. for( const std::shared_ptr<CLEANUP_ITEM>& item : realRunItems )
  103. {
  104. BOOST_TEST_MESSAGE( item->ShowReport( EDA_UNITS::INCHES, RPT_SEVERITY_ERROR,
  105. itemMap ) );
  106. }
  107. BOOST_ERROR( wxString::Format( "Track cleaner regression: %s, failed",
  108. entry.m_File ) );
  109. }
  110. }
  111. }
  112. BOOST_FIXTURE_TEST_CASE( TrackCleanerRegressionTests, TRACK_CLEANER_TEST_FIXTURE )
  113. {
  114. /*
  115. * This one just makes sure that the dry-run counts agree with the "real" counts, and that
  116. * the cleaning doesn't produce any connectivity changes.
  117. */
  118. std::vector<wxString> tests = { "issue832",
  119. "issue4257",
  120. "issue8909" };
  121. for( const wxString& relPath : tests )
  122. {
  123. KI_TEST::LoadBoard( m_settingsManager, relPath, m_board );
  124. KI_TEST::FillZones( m_board.get(), 6 );
  125. m_board->GetConnectivity()->RecalculateRatsnest();
  126. TOOL_MANAGER toolMgr;
  127. toolMgr.SetEnvironment( m_board.get(), nullptr, nullptr, nullptr, nullptr );
  128. BOARD_COMMIT commit( &toolMgr );
  129. TRACKS_CLEANER cleaner( m_board.get(), commit );
  130. std::vector< std::shared_ptr<CLEANUP_ITEM> > dryRunItems;
  131. std::vector< std::shared_ptr<CLEANUP_ITEM> > realRunItems;
  132. cleaner.CleanupBoard( true, &dryRunItems, true, // short circuits
  133. true, // redundant vias
  134. true, // redundant tracks
  135. true, // dangling tracks
  136. true, // tracks in pads
  137. true ); // dangling vias
  138. cleaner.CleanupBoard( true, &realRunItems, true, // short circuits
  139. true, // redundant vias
  140. true, // redundant tracks
  141. true, // dangling tracks
  142. true, // tracks in pads
  143. true ); // dangling vias
  144. BOOST_CHECK_EQUAL( dryRunItems.size(), realRunItems.size() );
  145. std::vector<DRC_ITEM> violations;
  146. BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
  147. bds.m_DRCEngine->SetViolationHandler(
  148. [&]( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
  149. {
  150. if( aItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
  151. violations.push_back( *aItem );
  152. } );
  153. bds.m_DRCEngine->RunTests( EDA_UNITS::MILLIMETRES, true, false );
  154. if( violations.empty() )
  155. {
  156. BOOST_TEST_MESSAGE( wxString::Format( "Track cleaner regression: %s, passed",
  157. relPath ) );
  158. }
  159. else
  160. {
  161. std::map<KIID, EDA_ITEM*> itemMap;
  162. m_board->FillItemMap( itemMap );
  163. for( const DRC_ITEM& item : violations )
  164. {
  165. BOOST_TEST_MESSAGE( item.ShowReport( EDA_UNITS::INCHES, RPT_SEVERITY_ERROR,
  166. itemMap ) );
  167. }
  168. BOOST_ERROR( wxString::Format( "Track cleaner regression: %s, failed",
  169. relPath ) );
  170. }
  171. }
  172. }