Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"wp-cli/checksum-command": "^2 || ^3",
"wp-cli/core-command": "^2 || ^3",
"wp-cli/cron-command": "^2 || ^3",
"wp-cli/entity-command": "^2 || ^3",
"wp-cli/entity-command": "^2.8.12 || ^3",
"wp-cli/extension-command": "^2 || ^3",
"wp-cli/language-command": "^2 || ^3",
"wp-cli/wp-cli": "^3.0"
Expand Down
2 changes: 2 additions & 0 deletions doctor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Default check configuration for `wp doctor`
autoload-options-size:
check: Autoload_Options_Size
transients-size:
check: Transients_Size
constant-savequeries-falsy:
check: Constant_Definition
options:
Expand Down
4 changes: 2 additions & 2 deletions features/check-autoload-options-size.feature
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Feature: Check the size of autoloaded options
When I run `wp doctor check autoload-options-size --fields=message`
Then STDOUT should contain:
"""
is less than threshold (900kb)
does not exceed threshold (900kb)
"""

@less-than-wp-6.5
Expand Down Expand Up @@ -59,5 +59,5 @@ Feature: Check the size of autoloaded options
When I run `wp doctor check autoload-options-size --fields=message --config=custom.yml`
Then STDOUT should contain:
"""
is less than threshold (800kb)
does not exceed threshold (800kb)
"""
156 changes: 156 additions & 0 deletions features/check-transients-size.feature
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)
"""
1 change: 1 addition & 0 deletions features/check.feature
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ Feature: Basic check usage
Then STDOUT should be a table containing rows:
| name |
| autoload-options-size |
| transients-size |
| core-update |
| core-verify-checksums |
| plugin-deactivated |
Expand Down
18 changes: 18 additions & 0 deletions src/Check.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' );
$base = min( (int) floor( log( $size, 1024 ) ), count( $suffixes ) - 1 );

return round( $size / pow( 1024, $base ), $precision ) . $suffixes[ $base ];
}

/**
* Run the check.
*
Expand Down
13 changes: 1 addition & 12 deletions src/Check/Autoload_Options_Size.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,7 @@ public function run() {
$this->set_message( "Autoloaded options size ({$human_total}) exceeds threshold ({$human_threshold})" );
} else {
$this->set_status( 'success' );
$this->set_message( "Autoloaded options size ({$human_total}) is less than threshold ({$human_threshold})." );
$this->set_message( "Autoloaded options size ({$human_total}) does not exceed threshold ({$human_threshold})." );
}
}

/**
* @param int|float $size Size in bytes.
* @param int $precision Precision.
* @return string
*/
private static function format_bytes( $size, $precision = 2 ) {
$base = log( $size, 1024 );
$suffixes = array( '', 'kb', 'mb', 'g', 't' );
return round( pow( 1024, $base - floor( $base ) ), $precision ) . $suffixes[ (int) floor( $base ) ];
}
}
46 changes: 46 additions & 0 deletions src/Check/Transients_Size.php
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();
Comment thread
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})." );
}
}
}
2 changes: 2 additions & 0 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* | name | description |
* +----------------------------+--------------------------------------------------------------------------------+
* | autoload-options-size | Warns when autoloaded options size exceeds threshold of 900 kb. |
* | transients-size | Warns when autoloaded transients size exceeds threshold of 900 kb. |
* | constant-savequeries-falsy | Confirms expected state of the SAVEQUERIES constant. |
* | constant-wp-debug-falsy | Confirms expected state of the WP_DEBUG constant. |
* | core-update | Errors when new WordPress minor release is available; warns for major release. |
Expand Down Expand Up @@ -325,6 +326,7 @@ function ( $check ) {
* | name | description |
* +----------------------------+--------------------------------------------------------------------------------+
* | autoload-options-size | Warns when autoloaded options size exceeds threshold of 900 kb. |
* | transients-size | Warns when autoloaded transients size exceeds threshold of 900 kb. |
* | constant-savequeries-falsy | Confirms expected state of the SAVEQUERIES constant. |
* | constant-wp-debug-falsy | Confirms expected state of the WP_DEBUG constant. |
* | core-update | Errors when new WordPress minor release is available; warns for major release. |
Expand Down
Loading