KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_footprint_library_adapter.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <filesystem>
21#include <memory>
22
23#ifdef __unix__
24#include <unistd.h>
25#endif
26
29
30#include <board.h>
31#include <footprint.h>
36
37
38namespace
39{
40
46class TEST_FOOTPRINT_LIBRARY_ADAPTER : public FOOTPRINT_LIBRARY_ADAPTER
47{
48public:
50
51 void SeedLoadError( const wxString& aNickname )
52 {
53 m_libraries[aNickname].status.load_status = LOAD_STATUS::LOAD_ERROR;
54 }
55
61 void SeedLoadedLibrary( const wxString& aNickname, const wxString& aUri )
62 {
63 m_row = std::make_unique<LIBRARY_TABLE_ROW>();
64 m_row->SetNickname( aNickname );
65 m_row->SetType( wxS( "KiCad" ) );
66 m_row->SetURI( aUri );
67
68 LIB_DATA& data = m_libraries[aNickname];
70 data.plugin = std::make_unique<PCB_IO_KICAD_SEXPR>();
71 data.row = m_row.get();
72 }
73
74private:
75 std::unique_ptr<LIBRARY_TABLE_ROW> m_row;
76};
77
78} // namespace
79
80
81BOOST_AUTO_TEST_SUITE( FootprintLibraryAdapter )
82
83
84
92BOOST_AUTO_TEST_CASE( IsFootprintLibWritableHandlesFailedLoad )
93{
94 LIBRARY_MANAGER manager;
95 TEST_FOOTPRINT_LIBRARY_ADAPTER adapter( manager );
96
97 adapter.SeedLoadError( wxS( "BadLib" ) );
98
99 BOOST_CHECK_EQUAL( adapter.IsFootprintLibWritable( wxS( "BadLib" ) ), false );
100
101 // A library that was never even attempted must also be safe.
102 BOOST_CHECK_EQUAL( adapter.IsFootprintLibWritable( wxS( "NeverSeen" ) ), false );
103}
104
105
113BOOST_AUTO_TEST_CASE( SaveFootprintReadOnlyFilePropagatesError )
114{
115#ifdef __unix__
116 // The superuser ignores mode bits, so a read-only file stays writable and this path
117 // cannot be exercised.
118 if( ::geteuid() == 0 )
119 {
120 BOOST_TEST_MESSAGE( "Skipping read-only footprint save test when running as root." );
121 return;
122 }
123#endif
124
125 // FootprintSave validates the whole containing directory as a library, so it needs a
126 // private directory no unrelated .kicad_mod can pollute.
127 KI_TEST::TEMPORARY_DIRECTORY tmpLib( "kicad_qa_adapter_save_readonly", ".pretty" );
128
129 LIBRARY_MANAGER manager;
130 TEST_FOOTPRINT_LIBRARY_ADAPTER adapter( manager );
131
132 const wxString nickname = wxS( "scratch" );
133 adapter.SeedLoadedLibrary( nickname, tmpLib.GetPath().string() );
134
135 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
136
137 FOOTPRINT* fp = new FOOTPRINT( board.get() );
138 board->Add( fp );
139 fp->SetFPID( LIB_ID( nickname, wxS( "readonly_fp" ) ) );
140
141 BOOST_REQUIRE( adapter.SaveFootprint( nickname, fp ) == FOOTPRINT_LIBRARY_ADAPTER::SAVE_OK );
142
143 auto savedFile = tmpLib.GetPath() / "readonly_fp.kicad_mod";
144 BOOST_REQUIRE( std::filesystem::exists( savedFile ) );
145
146 // Mark only the file read-only, mirroring the issue; the directory stays writable so the
147 // writability gate still passes and TEMPORARY_DIRECTORY can unlink it.
148 std::filesystem::permissions( savedFile,
149 std::filesystem::perms::owner_write | std::filesystem::perms::group_write
150 | std::filesystem::perms::others_write,
151 std::filesystem::perm_options::remove );
152
153 BOOST_CHECK_THROW( adapter.SaveFootprint( nickname, fp ), IO_ERROR );
154}
155
156
An interface to the global shared library manager that is schematic-specific and linked to one projec...
FOOTPRINT_LIBRARY_ADAPTER(LIBRARY_MANAGER &aManager)
void SetFPID(const LIB_ID &aFPID)
Definition footprint.h:442
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
A temporary directory that will be deleted when it goes out of scope.
const std::filesystem::path & GetPath() const
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
LIB_STATUS status
std::unique_ptr< IO_BASE > plugin
const LIBRARY_TABLE_ROW * row
LOAD_STATUS load_status
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(IsFootprintLibWritableHandlesFailedLoad)
Regression test for a null-plugin dereference crash.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
BOOST_CHECK_EQUAL(result, "25.4")