20#include <boost/test/unit_test.hpp>
28#include <wx/filename.h>
31#if !defined( __WINDOWS__ )
42wxString makeTempTargetPath(
const wxString& aTag )
44 wxString tempDir = wxFileName::GetTempDir();
45 wxString leaf = wxString::Format( wxT(
"kicad-lockfile-%s-%ld.kicad_pcb" ), aTag,
46 static_cast<long>( wxGetLocalTimeMillis().GetValue() ) );
47 return tempDir + wxFileName::GetPathSeparator() + leaf;
51void writeRaw(
const wxString& aPath,
const std::string& aContent )
53 wxFFile fp( aPath, wxT(
"wb" ) );
56 if( !aContent.empty() )
57 BOOST_REQUIRE( fp.Write( aContent.data(), aContent.size() ) == aContent.size() );
63nlohmann::json readLockJson(
const wxString& aPath )
65 wxFFile fp( aPath, wxT(
"rb" ) );
71 return nlohmann::json::parse( std::string( contents.mb_str() ) );
75std::string selfOwnedLockJson()
78 j[
"username"] = std::string( wxGetUserId().mb_str() );
79 j[
"hostname"] = std::string( wxGetHostName().mb_str() );
80 j[
"token"] =
"0123456789abcdef0123456789abcdef";
86FILE_LOCK holdLockOn(
const wxString& aLockPath )
91 BOOST_REQUIRE( holder.Acquire( aLockPath, created ) == FILE_LOCK::STATE::HELD );
98bool canTestUnwritableDirs()
100#if defined( __WINDOWS__ )
103 return geteuid() != 0;
115 wxString target = makeTempTargetPath( wxT(
"fresh" ) );
122 BOOST_CHECK( lock.
Valid() );
123 BOOST_CHECK( lock.
Locked() );
124 BOOST_CHECK( wxFileName::FileExists( lockPath ) );
127 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
134 wxString target = makeTempTargetPath( wxT(
"foreign" ) );
137 writeRaw( lockPath, R
"({"username":"someone-else","hostname":"another-host"})" );
141 BOOST_CHECK( !lock.Valid() );
152 wxRemoveFile( lockPath );
159 wxString target = makeTempTargetPath( wxT(
"empty" ) );
162 writeRaw( lockPath,
"" );
166 BOOST_CHECK( lock.
Valid() );
170 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
177 wxString target = makeTempTargetPath( wxT(
"corrupt" ) );
180 writeRaw( lockPath, R
"({"username":"partia)" );
184 BOOST_CHECK( lock.Valid() );
187 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
194 wxString target = makeTempTargetPath( wxT(
"abandoned" ) );
197 writeRaw( lockPath, selfOwnedLockJson() );
201 BOOST_CHECK( lock.Valid() );
202 BOOST_CHECK( lock.Locked() );
206 BOOST_CHECK( readLockJson( lockPath ).value(
"token", std::string() )
207 !=
"0123456789abcdef0123456789abcdef" );
210 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
218 wxString target = makeTempTargetPath( wxT(
"live" ) );
221 writeRaw( lockPath, selfOwnedLockJson() );
223 FILE_LOCK owner = holdLockOn( lockPath );
227 BOOST_CHECK( !lock.Valid() );
228 BOOST_CHECK( !lock.Locked() );
234 std::string(
"0123456789abcdef0123456789abcdef" ) );
237 wxRemoveFile( lockPath );
244 wxString target = makeTempTargetPath( wxT(
"inspect" ) );
249 BOOST_CHECK( probe.
Valid() );
250 BOOST_CHECK( !probe.
Locked() );
253 BOOST_CHECK( !wxFileName::FileExists( lockPath ) );
255 writeRaw( lockPath, selfOwnedLockJson() );
259 BOOST_CHECK( probe.
Valid() );
260 BOOST_CHECK( !probe.
Locked() );
266 std::string(
"0123456789abcdef0123456789abcdef" ) );
268 FILE_LOCK owner = holdLockOn( lockPath );
272 BOOST_CHECK( !probe.
Valid() );
277 wxRemoveFile( lockPath );
284 wxString target = makeTempTargetPath( wxT(
"second" ) );
291 BOOST_CHECK( !second.Valid() );
292 BOOST_CHECK( !second.Locked() );
297 BOOST_CHECK( first.Valid() );
304 wxString target = makeTempTargetPath( wxT(
"override" ) );
307 writeRaw( lockPath, selfOwnedLockJson() );
309 FILE_LOCK owner = holdLockOn( lockPath );
315 BOOST_CHECK( lock.OverrideLock() );
316 BOOST_CHECK( lock.Valid() );
321 if( wxFileName::FileExists( lockPath ) )
322 wxRemoveFile( lockPath );
329 wxString target = makeTempTargetPath( wxT(
"taken-over" ) );
336 nlohmann::json newOwner = readLockJson( lockPath );
337 newOwner[
"token"] =
"ffffffffffffffffffffffffffffffff";
338 writeRaw( lockPath, newOwner.dump() );
341 BOOST_CHECK( wxFileName::FileExists( lockPath ) );
342 wxRemoveFile( lockPath );
349 if( !canTestUnwritableDirs() )
352 wxString target = makeTempTargetPath( wxT(
"unwritable" ) );
355 writeRaw( lockPath, R
"({"username":"someone-else","hostname":"another-host"})" );
356 BOOST_REQUIRE( wxFileName( lockPath ).SetPermissions( wxS_IRUSR ) );
360 BOOST_CHECK( !lock.Valid() );
364 wxFileName( lockPath ).SetPermissions( wxS_IRUSR | wxS_IWUSR );
365 wxRemoveFile( lockPath );
372 if( !canTestUnwritableDirs() )
375 wxString dir = wxFileName::GetTempDir() + wxFileName::GetPathSeparator()
376 + wxString::Format( wxT(
"kicad-lockfile-ro-%ld" ),
377 static_cast<long>( wxGetLocalTimeMillis().GetValue() ) );
379 BOOST_REQUIRE( wxFileName::Mkdir( dir, 0700, wxPATH_MKDIR_FULL ) );
381 wxString target = dir + wxFileName::GetPathSeparator() + wxT(
"ro.kicad_pro" );
382 writeRaw( target,
"{}" );
384 BOOST_REQUIRE( wxFileName( dir ).SetPermissions( wxS_IRUSR | wxS_IXUSR ) );
388 BOOST_CHECK( lock.Valid() );
389 BOOST_CHECK( !lock.Locked() );
393 wxFileName( dir ).SetPermissions( wxS_IRUSR | wxS_IWUSR | wxS_IXUSR );
394 wxRemoveFile( target );
395 wxFileName::Rmdir( dir );
Advisory lock over a file, taken by writing a sibling lock file and holding an exclusive lock on it f...
static wxString LockPathFor(const wxString &aFilename)
static LOCKFILE Inspect(const wxString &aFilename)
Look at a lock without taking it: nothing is created, nothing is claimed and nothing is removed on re...
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")