KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_lockfile.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 along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <boost/test/unit_test.hpp>
21
22#include <lockfile.h>
24
25#include <wx/ffile.h>
26#include <wx/filefn.h>
27#include <wx/filename.h>
28#include <wx/utils.h>
29
30
31namespace
32{
33
34wxString makeTempTargetPath( const wxString& aTag )
35{
36 wxString tempDir = wxFileName::GetTempDir();
37 wxString leaf = wxString::Format( wxT( "kicad-lockfile-%s-%ld.kicad_pcb" ), aTag,
38 static_cast<long>( wxGetLocalTimeMillis().GetValue() ) );
39 return tempDir + wxFileName::GetPathSeparator() + leaf;
40}
41
42
43wxString lockPathFor( const wxString& aTargetPath )
44{
45 wxFileName fn( aTargetPath );
46 fn.SetName( FILEEXT::LockFilePrefix + fn.GetName() );
47 fn.SetExt( fn.GetExt() + '.' + FILEEXT::LockFileExtension );
48 return fn.GetFullPath();
49}
50
51
52void writeRaw( const wxString& aPath, const std::string& aContent )
53{
54 wxFFile fp( aPath, wxT( "wb" ) );
55 BOOST_REQUIRE( fp.IsOpened() );
56
57 if( !aContent.empty() )
58 BOOST_REQUIRE( fp.Write( aContent.data(), aContent.size() ) == aContent.size() );
59
60 fp.Close();
61}
62
63} // anonymous namespace
64
65
66BOOST_AUTO_TEST_SUITE( LockFileTests )
67
68
69BOOST_AUTO_TEST_CASE( AcquireFreshLock )
70{
71 wxString target = makeTempTargetPath( wxT( "fresh" ) );
72 wxString lockPath = lockPathFor( target );
73
74 BOOST_REQUIRE( !wxFileName::FileExists( lockPath ) );
75
76 {
77 LOCKFILE lock( target );
78 BOOST_CHECK( lock.Valid() );
79 BOOST_CHECK( lock.Locked() );
80 BOOST_CHECK( wxFileName::FileExists( lockPath ) );
81 }
82
83 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
84}
85
86
87BOOST_AUTO_TEST_CASE( ForeignLockNotOwned )
88{
89 wxString target = makeTempTargetPath( wxT( "foreign" ) );
90 wxString lockPath = lockPathFor( target );
91
92 writeRaw( lockPath, R"({"username":"someone-else","hostname":"another-host"})" );
93
94 {
95 LOCKFILE lock( target );
96 BOOST_CHECK( !lock.Valid() );
97 BOOST_CHECK( !lock.IsLockedByMe() );
98 BOOST_CHECK_EQUAL( lock.GetUsername(), wxString( "someone-else" ) );
99 BOOST_CHECK_EQUAL( lock.GetHostname(), wxString( "another-host" ) );
100 }
101
102 wxRemoveFile( lockPath );
103}
104
105
106// Regression: #23734 — empty lock (unfinished cloud sync) must be reclaimable, not a hard error.
107BOOST_AUTO_TEST_CASE( EmptyStaleLockIsReclaimable )
108{
109 wxString target = makeTempTargetPath( wxT( "empty" ) );
110 wxString lockPath = lockPathFor( target );
111
112 writeRaw( lockPath, "" );
113
114 {
115 LOCKFILE lock( target );
116 BOOST_CHECK( !lock.Valid() );
117 BOOST_CHECK( lock.IsLockedByMe() );
118 BOOST_CHECK( lock.OverrideLock() );
119 BOOST_CHECK( lock.Valid() );
120 }
121
122 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
123}
124
125
126// Regression: #23734 — corrupt/truncated lock (partial sync) must behave the same as an empty one.
127BOOST_AUTO_TEST_CASE( CorruptStaleLockIsReclaimable )
128{
129 wxString target = makeTempTargetPath( wxT( "corrupt" ) );
130 wxString lockPath = lockPathFor( target );
131
132 writeRaw( lockPath, R"({"username":"partia)" );
133
134 {
135 LOCKFILE lock( target );
136 BOOST_CHECK( !lock.Valid() );
137 BOOST_CHECK( lock.IsLockedByMe() );
138 BOOST_CHECK( lock.GetUsername().IsEmpty() );
139 BOOST_CHECK( lock.GetHostname().IsEmpty() );
140 }
141
142 if( wxFileName::FileExists( lockPath ) )
143 wxRemoveFile( lockPath );
144}
145
146
bool OverrideLock(bool aRemoveOnRelease=true)
Force the lock, overwriting the data that existed already.
Definition lockfile.h:183
bool Valid() const
Definition lockfile.h:268
wxString GetUsername()
Definition lockfile.h:250
wxString GetHostname()
Definition lockfile.h:256
bool Locked() const
Definition lockfile.h:263
bool IsLockedByMe()
Definition lockfile.h:236
static const std::string LockFileExtension
static const std::string LockFilePrefix
File locking utilities.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(AcquireFreshLock)
BOOST_CHECK_EQUAL(result, "25.4")
Definition of file extensions used in Kicad.