-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The Great Backup Refactor of 2015 #936
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This initial commit makes a good start towards a major refactor of the backups class. At a high level: - Splits the actual backup logic into `Backup_Engine` with utility functions shared via base classes. - A focus on unit testing from the start, this refactor was writtin to unit tests only at this point - Multiple `Backup_Engines` are then passed into a `Backup_Director` which is responsible for waterfalling through the engines until it finds one which works - This isn't yet integrated into the main plugin, unit tests only for now. - There's still lots to figure out, error handling, the old `hmbkp_` actions, integrating with `Scheduled_Backup`, more unit testing etc.
You can't pass a method directly to `empty`
- fixes a fatal error in Database_Backup_Engine - fixes up the unreadable_files unit tests and updates get_files() so it passes - remove some dead code
…ions of WordPress
…_Engine` too it. Make `Path::get_path()` static so we don't have to do `Path->get_instance()::get_path()` Adds unit tests for `get_home_path` and refactors the methos to pass them, fixes #695
Move the root path handling to Path and update unit tests More work to integrate the backup engines into the rest of the plugin
Continues work refactoring Scheduled_Backup away from Backup.
Moves the unit tests over and updates our Finder implementation to pass them
- Moves all site size handling to a new Site_Size class and out of `Schedule`. - Move all excludes handling out of `File_Backup_Engine` into a new `Excludes` class. - Introduces a `Site_Backup` class which is responsible for the orchestration of the entire site backup. - Rounds out the `Backup_Director` class and adds unit tests. Updates all existing code to reference new classes and introduces unit tests for all of the above.
Improved unit tests around Site backups, file backups and excludes.
This was referenced Nov 30, 2015
Includes a bunch of minor changes to both unit tests and plugin based on issues discovered along the way. Mostly to do with windows paths having forward slashes instead of backslashes.
Put in a bunch of effort to get the unit tests running cleanly and passing on Windows. I'm also going to writeup a guide on how to get unit testing running on Windows as there isn't much out there. |
Includes a few minor changes to the class in response to the tests, also cleans up whitespace in the backup status class. Moves the backup path tests into root as there's no point them being in a folder on their own.
- Unit tests for the site_size class - Move list_directory_by_filesize out of the Site_Size class, it's just a function. - Allow for small byte variences when comparing filesizes in unit tests - Introduce a helper function that returns a cross OS compatible way to pipe stderr to null - Split filesize into a bunch of shorter more focused functions.
Chatted to @pdewouters, we're going to introduce back combat methods on Site_Backup so that extensions continue to work without changes. |
Ensure the API we expose to Extensions stays backwards compatible. - Renames Site_Backup back to Backup as the extensions use type hinting to ensure that the Backup object is of type `Backup`. - Introduce a back compat `Backup::get_archive_filepath()` which fires a deprecated warning and calls `Backup::get_backup_filepath()`. - Introduce a back compat `Scheduled_Backup::set_status()` which fires a deprecated warning and calls `Scheduled_Backup->status::set_status()`. - Introduce a back compat `hmbkp_add_settings_error` which fires a deprecated warning and calls `add_settings_error`. Tested the existing versions of all our extensions and they now work as intended.
In 7031a2b we're now 100% back compatible with existing extensions. |
willmot
added a commit
that referenced
this pull request
Jan 19, 2016
The Great Backup Refactor of 2015
\0/ |
This was referenced Jan 22, 2016
willmot
added a commit
that referenced
this pull request
Feb 19, 2016
…ing a backup. There were several issues contributing to this bug. 1. We weren't even running `Path::cleanup` before and after running a backup, we now are. 2. We were missing a unit test to verify that when backing up the database, no other files are included. We now have a unit test. 3. We were missing unit tests for `Path::cleanup` to ensure that all the files we'd expect to are actually cleaned up. We now have unit tests. 4. Those tests exposed the fact that `Path::cleanup` wasn't cleaning up `ZipArchive` temporary files. It now does. 5. `PATH::reset_path` wasn't correctly resetting the `Path::custom_path` meaning that `PATH::cleanup` wouldn't run in some situations. That's now fixed. So in summary, before this commit temporary files from failed backups were not correctly deleted. After this commit they will be deleted. This bug was almost certainly introduced in #936
willmot
added a commit
that referenced
this pull request
Feb 19, 2016
…ing a backup. There were several issues contributing to this bug. 1. We weren't even running `Path::cleanup` before and after running a backup, we now are. 2. We were missing a unit test to verify that when backing up the database, no other files are included. We now have a unit test. 3. We were missing unit tests for `Path::cleanup` to ensure that all the files we'd expect to are actually cleaned up. We now have unit tests. 4. Those tests exposed the fact that `Path::cleanup` wasn't cleaning up `ZipArchive` temporary files. It now does. 5. `PATH::reset_path` wasn't correctly resetting the `Path::custom_path` meaning that `PATH::cleanup` wouldn't run in some situations. That's now fixed. So in summary, before this commit temporary files from failed backups were not correctly deleted. After this commit they will be deleted. This bug was almost certainly introduced in #936
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces a major refactor of the
Backups
class with the express aim of separating concerns, reducing complexity and improving testability.This is achieved by splitting the
Backups
class into several smaller classes, each responsible for different parts of the backup process.The core backup functionality (
mysqldump
,zip
,zipArchive
) is now handled by a set ofBackup_Engine
's, one for each backup method.These
Backup_Engines
are then brought together inSite_Backup
, which takes responsibility for combining the database and file backups as well as looping through the available backup engines.The Refactor
Backup Engine
s1.
Backup_Engine
The backup engine concept has two levels of inheritance. Starting at it's base with the
Backup_Engine
class. This is both a utility class and a template and is responsible for:memory_limit
andset_timeout
settings so the backup can run uninterrupted.filename
andfilepath
.verify_backup
2.
File_Backup_Engine
&Database_Backup_Engine
The next 2 classes both extend
Backup_Engine
. These are each responsible for generic functionality related to Database and File backups.Database_Backup_Engine
is responsible for parsing database connection details and making them available to be used by the eventual backup methods. It's also defines theverify_backup
method which is used to verify that any database backup methods completed successfully.File_Backup_Engine
is responsible managing the excludes functionality including default excludes. It provides methods for dealing with the files intended for backup and provides a file specific implementation ofverify_backup
.3.
Zip_File_Backup_Engine
,Zip_Archive_File_Backup_Engine
,Mysqldump_Database_Backup_Engine
,IMysqldump_Database_Backup_Engine
.With all the shared functionality handled by the parent classes we're left with very lean final backup method implementations. At their core a backup method need only implement the
backup
method which should return$this->verify_backup
.One huge benefit to this structure is that it's now much, much easier to add new backup methods. We could easily add
Tar
support, or bring backPclZip
with much less overhead and no increase in code complexity outside of the specificBackup_Method
implementations. For exampleThis PR also splits out a bunch of other functionality from both the
Scheduled_Backup
andBackup
classes:Backup_Utilities
class.Excludes
.Site_Size
.Backup_Status
.Unit Testing
A huge driver behind this refactor was a desire to make the core backups functionality much more testable. The current implementation has been written entirely to tests.
The abstract
Backup_Engine
,File_Backup_Engine
andDatabase_Backup_Engine
classes are all tested indirectly using mock backup engine implementations.Another key aim was that we should run the same set of common backup engine unit tests across all backup method implementations without having to duplicate the tests, this is achieved with the
Common_Database_Backup_Engine_Tests
&Common_File_Backup_Engine_Tests
parent test cases. These test cases are not run directly, instead the are extended by a specific backup engine implementations tests. For example:This test case is then run directly. Any tests unique to the
Zip_File_Backup_Method
would be implemented here. The specific backup engine is then passed up to the parent by callingparent::setUp
. Again the real benefit here is that a new backup engine automatically get's a whole suit of unit tests just be implementing the above barebones test case. This hugely reduces the amount of copy paste tests that we currently have.As part of implementing this unit tests I've already discovered and fixed several bugs that are present in the current
Backup
class.The test data is now created and destroyed programatically instead of being stored on the filesystem, this ensures we can rely on the data being exactly as we expect.
TODO
There is a still a bunch of things todo to finish off the work here:
Backup
class, and in a lot of cases, updating.Backup_Engine
class currently has all the error and warning handling. This should probably be moved to a separateBackup_Errors
class and be refactored to useWP_Error
.hmbkp_
actions.Backup_Utility
class.Back compat with the old.get_archive_method
andget_mysqldump_method
methods (if they are needed)Backup
class.Backup_Engine
implementations into the list.Backup_Director
needs to be able to take arguments that need to be set on theBackup_Engine
implementations (for example setting new excludes).Scheduled_Backup
so that the main plugin uses the new code.Backup
class.PATH
shouldn't be a singleton and should instead be passed around.File_Backup_Engines
should take the directory to backup and the output filepath as constructor args.Database_Backup_Engines
should just take the output filepath.Backup_Engine
class should probably go away (error handling should be a separate class that's injected as a dependancy and upping the memory limit should be handled by the caller.Database_Backup_Engine
andFile_Backup_Engine
should maybe be implementations. The shared functionality could be passed in by the caller.Files
class which handles interactions withFinder
.Email
&Webhook
Services.Services::action
, is that an issue?.backup_errors
and.backup_warnings
files, were they used?