-
Notifications
You must be signed in to change notification settings - Fork 25
Add transients size check #217
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
base: main
Are you sure you want to change the base?
Changes from all commits
a188f03
8b3b086
70ad1fd
efb9de8
02706d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| Feature: Check the size of autoloaded transients | ||
|
|
||
| Scenario: Verify check description | ||
| Given an empty directory | ||
|
|
||
| When I run `wp doctor list --fields=name,description` | ||
| Then STDOUT should be a table containing rows: | ||
| | name | description | | ||
| | transients-size | Warns when autoloaded transients size exceeds threshold of 900 kb. | | ||
|
|
||
| Scenario: Autoloaded transients are less than 900 kb | ||
| Given a WP install | ||
|
|
||
| When I run `wp doctor check transients-size --fields=name,status` | ||
| Then STDOUT should be a table containing rows: | ||
| | name | status | | ||
| | transients-size | success | | ||
|
|
||
| When I run `wp doctor check transients-size --fields=message` | ||
| Then STDOUT should contain: | ||
| """ | ||
| does not exceed threshold (900kb) | ||
| """ | ||
|
|
||
| Scenario: Autoloaded transients equal 900 kb | ||
| Given a WP install | ||
| And a wp-content/mu-plugins/exact-threshold-transients.php file: | ||
| """ | ||
| <?php | ||
| add_action( | ||
| 'wp_loaded', | ||
| static function () { | ||
| global $wpdb; | ||
|
|
||
| $option_names = $wpdb->get_col( "SELECT option_name FROM {$wpdb->options}" ); | ||
| foreach ( $option_names as $option_name ) { | ||
| if ( | ||
| 0 === strpos( $option_name, '_transient_' ) | ||
| || 0 === strpos( $option_name, '_site_transient_' ) | ||
| ) { | ||
| delete_option( $option_name ); | ||
| } | ||
| } | ||
|
|
||
| add_option( '_transient_doctor_exact_threshold', str_repeat( '9', 900 * 1024 ), '', true ); | ||
| }, | ||
| PHP_INT_MAX | ||
| ); | ||
| """ | ||
|
|
||
| When I run `wp option list --transients --autoload=on --format=total_bytes` | ||
| Then STDOUT should be: | ||
| """ | ||
| 921600 | ||
| """ | ||
|
|
||
| When I run `wp doctor check transients-size --fields=name,status` | ||
| Then STDOUT should be a table containing rows: | ||
| | name | status | | ||
| | transients-size | success | | ||
|
|
||
| When I run `wp doctor check transients-size --fields=message` | ||
| Then STDOUT should contain: | ||
| """ | ||
| Autoloaded transients size (900kb) does not exceed threshold (900kb). | ||
| """ | ||
|
|
||
| Scenario: Autoloaded transients are greater than 900 kb | ||
| Given a WP install | ||
| And a create-large-transients.php file: | ||
| """ | ||
| <?php | ||
| $value = str_repeat( '9', 15000 ); | ||
| for ( $i = 0; $i < 75; $i++ ) { | ||
| add_option( '_transient_doctor_big_' . $i, $value, '', true ); | ||
| } | ||
| """ | ||
| And I run `wp eval-file create-large-transients.php` | ||
|
|
||
| When I run `wp doctor check transients-size --fields=name,status` | ||
| Then STDOUT should be a table containing rows: | ||
| | name | status | | ||
| | transients-size | warning | | ||
|
|
||
| When I run `wp doctor check transients-size --fields=message` | ||
| Then STDOUT should contain: | ||
| """ | ||
| exceeds threshold (900kb) | ||
| """ | ||
|
|
||
| Scenario: Autoloaded options and expiring transients are ignored | ||
| Given a WP install | ||
| And a create-large-nonmatching-data.php file: | ||
| """ | ||
| <?php | ||
| $value = str_repeat( '9', 15000 ); | ||
| for ( $i = 0; $i < 75; $i++ ) { | ||
| update_option( 'doctor_big_option_' . $i, $value, true ); | ||
| add_option( '_transient_doctor_expiring_big_' . $i, $value, '', false ); | ||
| add_option( '_transient_timeout_doctor_expiring_big_' . $i, time() + HOUR_IN_SECONDS, '', false ); | ||
| } | ||
| """ | ||
| And I run `wp eval-file create-large-nonmatching-data.php` | ||
|
|
||
| When I run `wp doctor check transients-size --fields=name,status` | ||
| Then STDOUT should be a table containing rows: | ||
| | name | status | | ||
| | transients-size | success | | ||
|
|
||
| Scenario: Custom configuration | ||
| Given a WP install | ||
| And a custom.yml file: | ||
| """ | ||
| transients-size: | ||
| class: WP_CLI\Doctor\Check\Transients_Size | ||
| options: | ||
| threshold_kb: 800 | ||
| """ | ||
|
|
||
| When I run `wp doctor check transients-size --fields=message --config=custom.yml` | ||
| Then STDOUT should contain: | ||
| """ | ||
| does not exceed threshold (800kb) | ||
| """ | ||
|
|
||
| Scenario: Zero threshold is formatted safely | ||
| Given a WP install | ||
| And a custom.yml file: | ||
| """ | ||
| transients-size: | ||
| class: WP_CLI\Doctor\Check\Transients_Size | ||
| options: | ||
| threshold_kb: 0 | ||
| """ | ||
|
|
||
| When I run `wp doctor check transients-size --fields=message --config=custom.yml` | ||
| Then STDOUT should contain: | ||
| """ | ||
| threshold (0) | ||
| """ | ||
|
|
||
| Scenario: Very large thresholds are formatted safely | ||
| Given a WP install | ||
| And a custom.yml file: | ||
| """ | ||
| transients-size: | ||
| class: WP_CLI\Doctor\Check\Transients_Size | ||
| options: | ||
| threshold_kb: 1099511627776 | ||
| """ | ||
|
|
||
| When I run `wp doctor check transients-size --fields=message --config=custom.yml` | ||
| Then STDOUT should contain: | ||
| """ | ||
| does not exceed threshold (1024t) | ||
| """ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,24 @@ protected function set_message( $message ) { | |
| $this->_message = $message; | ||
| } | ||
|
|
||
| /** | ||
| * Format a byte count for check result messages. | ||
| * | ||
| * @param int|float $size Size in bytes. | ||
| * @param int $precision Precision. | ||
| * @return string | ||
| */ | ||
| protected static function format_bytes( $size, $precision = 2 ) { | ||
| if ( 0 >= $size ) { | ||
| return '0'; | ||
| } | ||
|
|
||
| $suffixes = array( '', 'kb', 'mb', 'g', 't' ); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suffixes. |
||
| $base = min( (int) floor( log( $size, 1024 ) ), count( $suffixes ) - 1 ); | ||
|
|
||
| return round( $size / pow( 1024, $base ), $precision ) . $suffixes[ $base ]; | ||
| } | ||
|
|
||
| /** | ||
| * Run the check. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| <?php | ||
|
|
||
| namespace WP_CLI\Doctor\Check; | ||
|
|
||
| use WP_CLI; | ||
| use WP_CLI\Doctor\Check; | ||
|
|
||
| /** | ||
| * Warns when autoloaded transients size exceeds threshold of %threshold_kb% kb. | ||
| */ | ||
| class Transients_Size extends Check { | ||
|
|
||
| /** | ||
| * Threshold in kilobytes. | ||
| * | ||
| * @var integer | ||
| */ | ||
| protected $threshold_kb = 900; | ||
|
|
||
| /** | ||
| * @return void | ||
| */ | ||
| public function run() { | ||
| ob_start(); | ||
| WP_CLI::run_command( | ||
| array( 'option', 'list' ), | ||
| array( | ||
| 'transients' => true, | ||
| 'autoload' => 'on', | ||
| 'format' => 'total_bytes', | ||
| ) | ||
| ); | ||
| $total_bytes = (int) ob_get_clean(); | ||
|
ekamran marked this conversation as resolved.
|
||
|
|
||
| $threshold_bytes = $this->threshold_kb * 1024; | ||
| $human_threshold = self::format_bytes( $threshold_bytes ); | ||
| $human_total = self::format_bytes( $total_bytes ); | ||
| if ( $threshold_bytes < $total_bytes ) { | ||
| $this->set_status( 'warning' ); | ||
| $this->set_message( "Autoloaded transients size ({$human_total}) exceeds threshold ({$human_threshold})" ); | ||
| } else { | ||
| $this->set_status( 'success' ); | ||
| $this->set_message( "Autoloaded transients size ({$human_total}) does not exceed threshold ({$human_threshold})." ); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exact-threshold scenario.
features/check-transients-size.feature:27-49installs an mu-plugin that deletes every transient and re-adds one on eachwp_loaded, so it also runs insidewp option listandwp doctor check. The other scenarios seed the data once withwp eval-file; please do the same here and drop the mu-plugin.