|
KiCad PCB EDA Suite
|
#include <qa_utils/wx_utils/unit_test_utils.h>#include <qa_utils/file_utils.h>#include <board.h>#include <board_design_settings.h>#include <local_history.h>#include <pgm_base.h>#include <project.h>#include <project/project_file.h>#include <settings/common_settings.h>#include <settings/settings_manager.h>#include <git2.h>#include <algorithm>#include <memory>#include <vector>#include <wx/datetime.h>#include <wx/dir.h>#include <wx/ffile.h>#include <wx/filefn.h>#include <wx/filename.h>#include <wx/stdpaths.h>Go to the source code of this file.
Functions | |
| BOOST_AUTO_TEST_CASE (SaveToHistoryWithNullProjectDoesNotCrash) | |
| Regression test for https://gitlab.com/kicad/code/kicad/-/issues/23737. | |
| BOOST_AUTO_TEST_CASE (SaveToHistoryUnsavedBoardProducesNothing) | |
| SaveToHistory with a real project but no board filename should not produce any file data (the board is unsaved). | |
| BOOST_AUTO_TEST_CASE (NoSnapshotWithoutProjectFile) | |
| When pcbnew runs standalone with no project loaded, saving a board can land anywhere on the filesystem. | |
| BOOST_AUTO_TEST_CASE (CommitFullProjectSnapshotHandlesSubdirectories) | |
| CommitFullProjectSnapshot collects files recursively. | |
| BOOST_AUTO_TEST_CASE (RestoreCommitPreservesZipBackupsDirectory) | |
| BOOST_AUTO_TEST_CASE (RestoreCommitPreservesNestedProject) | |
| Regression test: a user reported that opening a project containing a nested project and accepting "restore previous version" deleted the entire nested project. | |
| BOOST_AUTO_TEST_CASE (RestoreCommitRetainsTimestampedBackup) | |
| The retained backup directory must be timestamped (Windows-safe, no colons) and survive the success path of RestoreCommit so the user can recover any displaced file. | |
| BOOST_AUTO_TEST_CASE (CommitFullProjectSnapshotExcludesNonKiCadFiles) | |
| Snapshots must only commit KiCad managed files and user files in the project dir stay out. | |
| BOOST_AUTO_TEST_CASE (FirstAutosaveSkipsCommitWhenStagedMatchesDisk) | |
| Idle autosave on a fresh project (saver output == disk) must not create an untagged HEAD. | |
| BOOST_AUTO_TEST_CASE (SaverSkippedAfterOwningDocumentDestroyed) | |
| A saver tied to a document's lifetime token must be skipped, and dropped, once the document is destroyed. | |
| BOOST_AUTO_TEST_CASE (FirstManualSaveAlwaysCommitsOnFreshProject) | |
| Manual save on a fresh project (saver output == disk) must still commit, so the user's first explicit save shows up in the history dialog. | |
| BOOST_AUTO_TEST_CASE (ZipFormatSkipsIncrementalAutosave) | |
| BOOST_AUTO_TEST_CASE (ZipFormatWritesRecoveryFiles) | |
| BOOST_AUTO_TEST_CASE (CloudSyncTouchedAutosaveFalselyFlaggedStale) | |
| BOOST_AUTO_TEST_CASE (DivergentAutosaveStillFlaggedStale) | |
| BOOST_AUTO_TEST_CASE (EnforceSizeLimitKeepsUnstagedFilesInNextSnapshot) | |
| BOOST_AUTO_TEST_CASE (ProjectSnapshotCarriesUnsavedSettings) | |
| BOOST_AUTO_TEST_CASE (ProjectSaveStillWritesAfterSnapshot) | |
| BOOST_AUTO_TEST_CASE (ProjectSnapshotDoesNotDirtyACleanProject) | |
| BOOST_AUTO_TEST_CASE | ( | CloudSyncTouchedAutosaveFalselyFlaggedStale | ) |
Definition at line 858 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), COMMON_SETTINGS::AUTO_BACKUP::enabled, LOCAL_HISTORY::FindStaleAutosaveFiles(), PGM_BASE::GetCommonSettings(), PGM_BASE::GetSettingsManager(), COMMON_SETTINGS::AUTO_BACKUP::location, location, COMMON_SETTINGS::m_Backup, path, Pgm(), project, and PROJECT_DIR.
| BOOST_AUTO_TEST_CASE | ( | CommitFullProjectSnapshotExcludesNonKiCadFiles | ) |
Snapshots must only commit KiCad managed files and user files in the project dir stay out.
Definition at line 532 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), LOCAL_HISTORY::CommitFullProjectSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), COMMON_SETTINGS::m_Backup, path, Pgm(), and project.
| BOOST_AUTO_TEST_CASE | ( | CommitFullProjectSnapshotHandlesSubdirectories | ) |
CommitFullProjectSnapshot collects files recursively.
CommitSnapshot's legacy path derives the project root from aFiles[0], so when the first file ends up in a subdirectory the project root would be misidentified. CommitFullProjectSnapshot must commit using the explicitly supplied project path regardless of what the recursive walk happens to return first.
Definition at line 287 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), LOCAL_HISTORY::CommitFullProjectSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, path, Pgm(), and project.
| BOOST_AUTO_TEST_CASE | ( | DivergentAutosaveStillFlaggedStale | ) |
Definition at line 905 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), COMMON_SETTINGS::AUTO_BACKUP::enabled, LOCAL_HISTORY::FindStaleAutosaveFiles(), PGM_BASE::GetCommonSettings(), PGM_BASE::GetSettingsManager(), COMMON_SETTINGS::AUTO_BACKUP::location, location, COMMON_SETTINGS::m_Backup, path, Pgm(), project, and PROJECT_DIR.
| BOOST_AUTO_TEST_CASE | ( | EnforceSizeLimitKeepsUnstagedFilesInNextSnapshot | ) |
Definition at line 945 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), LOCAL_HISTORY::CommitFullProjectSnapshot(), LOCAL_HISTORY::CommitSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, LOCAL_HISTORY::EnforceSizeLimit(), PGM_BASE::GetCommonSettings(), COMMON_SETTINGS::m_Backup, path, Pgm(), and project.
| BOOST_AUTO_TEST_CASE | ( | FirstAutosaveSkipsCommitWhenStagedMatchesDisk | ) |
Idle autosave on a fresh project (saver output == disk) must not create an untagged HEAD.
Real edits (saver output != disk) must commit.
Definition at line 611 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), HISTORY_FILE_DATA::content, COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, path, Pgm(), project, LOCAL_HISTORY::RegisterSaver(), HISTORY_FILE_DATA::relativePath, LOCAL_HISTORY::RunRegisteredSaversAndCommit(), LOCAL_HISTORY::UnregisterSaver(), and LOCAL_HISTORY::WaitForPendingSave().
| BOOST_AUTO_TEST_CASE | ( | FirstManualSaveAlwaysCommitsOnFreshProject | ) |
Manual save on a fresh project (saver output == disk) must still commit, so the user's first explicit save shows up in the history dialog.
Counterpart to FirstAutosaveSkipsCommitWhenStagedMatchesDisk.
Definition at line 726 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), HISTORY_FILE_DATA::content, COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, path, Pgm(), project, LOCAL_HISTORY::RegisterSaver(), HISTORY_FILE_DATA::relativePath, LOCAL_HISTORY::RunRegisteredSaversAndCommit(), and LOCAL_HISTORY::UnregisterSaver().
| BOOST_AUTO_TEST_CASE | ( | NoSnapshotWithoutProjectFile | ) |
When pcbnew runs standalone with no project loaded, saving a board can land anywhere on the filesystem.
CommitFullProjectSnapshot used to recursively walk that directory and call git_status_file on every entry. If the user saved into /tmp (or any directory with millions of files), pcbnew would peg a CPU for hours. Verify that LOCAL_HISTORY refuses to do any work for a directory that is not a real KiCad project.
Definition at line 252 of file test_history_autosave.cpp.
References LOCAL_HISTORY::CommitFullProjectSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::Init(), COMMON_SETTINGS::m_Backup, path, KI_TEST::SCOPED_TEMP_DIR::PathStr(), Pgm(), and LOCAL_HISTORY::TagSave().
| BOOST_AUTO_TEST_CASE | ( | ProjectSaveStillWritesAfterSnapshot | ) |
Definition at line 1012 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), PROJECT_FILE::m_TextVars, KI_TEST::SCOPED_TEMP_DIR::PathStr(), SETTINGS_MANAGER::SaveProject(), and PROJECT_FILE::SaveToFile().
| BOOST_AUTO_TEST_CASE | ( | ProjectSnapshotCarriesUnsavedSettings | ) |
Definition at line 996 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), and SETTINGS_MANAGER::SaveProject().
| BOOST_AUTO_TEST_CASE | ( | ProjectSnapshotDoesNotDirtyACleanProject | ) |
Definition at line 1038 of file test_history_autosave.cpp.
References BOOST_CHECK_EQUAL(), BOOST_REQUIRE(), KI_TEST::SCOPED_TEMP_DIR::PathStr(), SETTINGS_MANAGER::SaveProject(), and PROJECT_FILE::SaveToFile().
| BOOST_AUTO_TEST_CASE | ( | RestoreCommitPreservesNestedProject | ) |
Regression test: a user reported that opening a project containing a nested project and accepting "restore previous version" deleted the entire nested project.
The data-loss path was that LOCAL_HISTORY treated the nested project's files as ordinary subtree contents, captured them in the parent's snapshot, then on restore proposed them for deletion and (because backupCurrentFiles renamed whole top-level entries) wiped the nested directory.
The fix: collectProjectFiles() and findFilesToDelete() must skip subtrees that contain their own .kicad_pro file, and the restore confirmation dialog must enter the non-destructive "Keep All Files" path automatically when a nested project is at risk.
This test exercises the simple reported scenario - nested project as a top-level subdir.
Definition at line 397 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), LOCAL_HISTORY::CommitFullProjectSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, KI_TEST::SCOPED_TEMP_DIR::PathStr(), Pgm(), and LOCAL_HISTORY::RestoreCommit().
| BOOST_AUTO_TEST_CASE | ( | RestoreCommitPreservesZipBackupsDirectory | ) |
Definition at line 335 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), LOCAL_HISTORY::CommitFullProjectSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, KI_TEST::SCOPED_TEMP_DIR::PathStr(), Pgm(), and LOCAL_HISTORY::RestoreCommit().
| BOOST_AUTO_TEST_CASE | ( | RestoreCommitRetainsTimestampedBackup | ) |
The retained backup directory must be timestamped (Windows-safe, no colons) and survive the success path of RestoreCommit so the user can recover any displaced file.
Replaces the old behavior where _restore_backup/ was unconditionally rmdir'd on success.
Definition at line 459 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), LOCAL_HISTORY::CommitFullProjectSnapshot(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, name, KI_TEST::SCOPED_TEMP_DIR::PathStr(), Pgm(), and LOCAL_HISTORY::RestoreCommit().
| BOOST_AUTO_TEST_CASE | ( | SaverSkippedAfterOwningDocumentDestroyed | ) |
A saver tied to a document's lifetime token must be skipped, and dropped, once the document is destroyed.
The autosave timer is shared across editor frames, so a saver that outlives its BOARD/SCHEMATIC would serialize freed memory – the autosave-saver use-after-free behind the crashes in EDA_BASE_FRAME::doAutoSave (Sentry KICAD-159V PCB, KICAD-17F5 SCH).
Definition at line 670 of file test_history_autosave.cpp.
References BOOST_CHECK_EQUAL(), COMMON_SETTINGS::AUTO_BACKUP::enabled, PGM_BASE::GetCommonSettings(), COMMON_SETTINGS::m_Backup, path, Pgm(), project, LOCAL_HISTORY::RegisterSaver(), LOCAL_HISTORY::RunRegisteredSaversAndCommit(), LOCAL_HISTORY::RunRegisteredSaversAsAutosaveFiles(), and LOCAL_HISTORY::WaitForPendingSave().
| BOOST_AUTO_TEST_CASE | ( | SaveToHistoryUnsavedBoardProducesNothing | ) |
SaveToHistory with a real project but no board filename should not produce any file data (the board is unsaved).
It must also not crash.
Definition at line 221 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), BOARD::ClearProject(), BOARD::GetFileName(), PROJECT::GetProjectPath(), SETTINGS_MANAGER::LoadProject(), SETTINGS_MANAGER::Prj(), BOARD::SaveToHistory(), BOARD::SetProject(), and SETTINGS_MANAGER::UnloadProject().
| BOOST_AUTO_TEST_CASE | ( | SaveToHistoryWithNullProjectDoesNotCrash | ) |
Regression test for https://gitlab.com/kicad/code/kicad/-/issues/23737.
After importing a non-KiCad board, BOARD::SaveToHistory could be invoked from the autosave timer while the board's project pointer was transiently null (between unloading the previous project and linking the new one). The function then dereferenced GetProject() and crashed with EXCEPTION_ACCESS_VIOLATION_READ. SaveToHistory must tolerate a null project and bail out cleanly without crashing.
Definition at line 205 of file test_history_autosave.cpp.
References BOOST_AUTO_TEST_CASE(), BOOST_REQUIRE(), BOARD::GetProject(), and BOARD::SaveToHistory().
| BOOST_AUTO_TEST_CASE | ( | ZipFormatSkipsIncrementalAutosave | ) |
Definition at line 768 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), HISTORY_FILE_DATA::content, COMMON_SETTINGS::AUTO_BACKUP::enabled, COMMON_SETTINGS::AUTO_BACKUP::format, PGM_BASE::GetCommonSettings(), LOCAL_HISTORY::GetHeadHash(), COMMON_SETTINGS::m_Backup, path, Pgm(), project, LOCAL_HISTORY::RegisterSaver(), HISTORY_FILE_DATA::relativePath, LOCAL_HISTORY::RunRegisteredSaversAndCommit(), LOCAL_HISTORY::UnregisterSaver(), LOCAL_HISTORY::WaitForPendingSave(), and ZIP.
| BOOST_AUTO_TEST_CASE | ( | ZipFormatWritesRecoveryFiles | ) |
Definition at line 811 of file test_history_autosave.cpp.
References BOOST_REQUIRE(), HISTORY_FILE_DATA::content, COMMON_SETTINGS::AUTO_BACKUP::enabled, COMMON_SETTINGS::AUTO_BACKUP::format, PGM_BASE::GetCommonSettings(), PGM_BASE::GetSettingsManager(), COMMON_SETTINGS::AUTO_BACKUP::location, location, COMMON_SETTINGS::m_Backup, path, Pgm(), project, PROJECT_DIR, LOCAL_HISTORY::RegisterSaver(), HISTORY_FILE_DATA::relativePath, LOCAL_HISTORY::RunRegisteredSaversAsAutosaveFiles(), LOCAL_HISTORY::UnregisterSaver(), and ZIP.