mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 22:30:04 +00:00
Site Health: Introduce page cache check.
This changeset adds a new `page_cache` check which determines whether the site uses a full page cache, and in addition assesses the server response time. If no page cache is present and the server response time is slow, the check will suggest use of a page cache. A few filters are included for customization of the check: * `site_status_good_response_time_threshold` filters the number of milliseconds below which the server response time is considered good. The default value is based on the `server-response-time` Lighthouse audit and can be altered using this filter. * `site_status_page_cache_supported_cache_headers` filters the map of supported cache headers and their callback to determine whether it was a cache hit. The default list includes commonly used cache headers, and it is filterable to support e.g. additional cache headers used by specific vendors. Note that due to the nature of this check it is only run in production environments. Props furi3r, westonruter, spacedmonkey, swissspidy, Clorith. Fixes #56041. git-svn-id: https://develop.svn.wordpress.org/trunk@54043 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -183,6 +183,7 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
|
||||
'/wp-site-health/v1/tests/https-status',
|
||||
'/wp-site-health/v1/tests/dotorg-communication',
|
||||
'/wp-site-health/v1/tests/authorization-header',
|
||||
'/wp-site-health/v1/tests/page-cache',
|
||||
'/wp-site-health/v1/directory-sizes',
|
||||
);
|
||||
|
||||
|
||||
@@ -99,4 +99,49 @@ class WP_Test_REST_Site_Health_Controller extends WP_Test_REST_TestCase {
|
||||
$response = rest_do_request( '/wp-site-health/v1/tests/dotorg-communication' );
|
||||
$this->assertSame( 'dotorg_communication', $response->get_data()['test'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests Page Cache Rest endpoint registration.
|
||||
*
|
||||
* @ticket 56041
|
||||
*/
|
||||
public function test_page_cache_endpoint() {
|
||||
$server = rest_get_server();
|
||||
$routes = $server->get_routes();
|
||||
|
||||
$endpoint = '/wp-site-health/v1/tests/page-cache';
|
||||
$this->assertArrayHasKey( $endpoint, $routes );
|
||||
|
||||
$route = $routes[ $endpoint ];
|
||||
$this->assertCount( 1, $route );
|
||||
|
||||
$route = current( $route );
|
||||
$this->assertEquals(
|
||||
array( WP_REST_Server::READABLE => true ),
|
||||
$route['methods']
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'test_page_cache',
|
||||
$route['callback'][1]
|
||||
);
|
||||
|
||||
$this->assertIsCallable( $route['permission_callback'] );
|
||||
|
||||
if ( current_user_can( 'view_site_health_checks' ) ) {
|
||||
$this->assertTrue( call_user_func( $route['permission_callback'] ) );
|
||||
} else {
|
||||
$this->assertFalse( call_user_func( $route['permission_callback'] ) );
|
||||
}
|
||||
|
||||
wp_set_current_user( self::factory()->user->create( array( 'role' => 'author' ) ) );
|
||||
$this->assertFalse( call_user_func( $route['permission_callback'] ) );
|
||||
|
||||
$user = wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
|
||||
if ( is_multisite() ) {
|
||||
// Site health cap is only available for super admins in Multi sites.
|
||||
grant_super_admin( $user->ID );
|
||||
}
|
||||
$this->assertTrue( call_user_func( $route['permission_callback'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,99 @@ class Tests_Site_Health extends WP_UnitTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 56041
|
||||
* @dataProvider data_page_cache_test
|
||||
* @covers ::get_test_page_cache()
|
||||
* @covers ::get_page_cache_detail()
|
||||
* @covers ::get_page_cache_headers()
|
||||
* @covers ::check_for_page_caching()
|
||||
*/
|
||||
public function test_get_page_cache( $responses, $expected_status, $expected_label, $good_basic_auth = null, $delay_the_response = false ) {
|
||||
$wp_site_health = new WP_Site_Health();
|
||||
|
||||
$expected_props = array(
|
||||
'badge' => array(
|
||||
'label' => __( 'Performance' ),
|
||||
'color' => 'blue',
|
||||
),
|
||||
'test' => 'page_cache',
|
||||
'status' => $expected_status,
|
||||
'label' => $expected_label,
|
||||
);
|
||||
|
||||
if ( null !== $good_basic_auth ) {
|
||||
$_SERVER['PHP_AUTH_USER'] = 'admin';
|
||||
$_SERVER['PHP_AUTH_PW'] = 'password';
|
||||
}
|
||||
|
||||
$threshold = 10;
|
||||
if ( $delay_the_response ) {
|
||||
add_filter(
|
||||
'site_status_good_response_time_threshold',
|
||||
static function () use ( $threshold ) {
|
||||
return $threshold;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
add_filter(
|
||||
'pre_http_request',
|
||||
function ( $r, $parsed_args ) use ( &$responses, &$is_unauthorized, $good_basic_auth, $delay_the_response, $threshold ) {
|
||||
|
||||
$expected_response = array_shift( $responses );
|
||||
|
||||
if ( $delay_the_response ) {
|
||||
usleep( $threshold * 1000 + 1 );
|
||||
}
|
||||
|
||||
if ( 'unauthorized' === $expected_response ) {
|
||||
$is_unauthorized = true;
|
||||
|
||||
return array(
|
||||
'response' => array(
|
||||
'code' => 401,
|
||||
'message' => 'Unauthorized',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if ( null !== $good_basic_auth ) {
|
||||
$this->assertArrayHasKey(
|
||||
'Authorization',
|
||||
$parsed_args['headers']
|
||||
);
|
||||
}
|
||||
|
||||
$this->assertIsArray( $expected_response );
|
||||
|
||||
return array(
|
||||
'headers' => $expected_response,
|
||||
'response' => array(
|
||||
'code' => 200,
|
||||
'message' => 'OK',
|
||||
),
|
||||
);
|
||||
},
|
||||
20,
|
||||
2
|
||||
);
|
||||
|
||||
$actual = $wp_site_health->get_test_page_cache();
|
||||
$this->assertArrayHasKey( 'description', $actual );
|
||||
$this->assertArrayHasKey( 'actions', $actual );
|
||||
if ( $is_unauthorized ) {
|
||||
$this->assertStringContainsString( 'Unauthorized', $actual['description'] );
|
||||
} else {
|
||||
$this->assertStringNotContainsString( 'Unauthorized', $actual['description'] );
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
$expected_props,
|
||||
wp_array_slice_assoc( $actual, array_keys( $expected_props ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group ms-excluded
|
||||
* @ticket 56040
|
||||
@@ -162,6 +255,158 @@ class Tests_Site_Health extends WP_UnitTestCase {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets response data for get_test_page_cache().
|
||||
* @ticket 56041
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function data_page_cache_test() {
|
||||
$recommended_label = 'Page cache is not detected but the server response time is OK';
|
||||
$good_label = 'Page cache is detected and the server response time is good';
|
||||
$critical_label = 'Page cache is not detected and the server response time is slow';
|
||||
$error_label = 'Unable to detect the presence of page cache';
|
||||
|
||||
return array(
|
||||
'basic-auth-fail' => array(
|
||||
'responses' => array(
|
||||
'unauthorized',
|
||||
),
|
||||
'expected_status' => 'recommended',
|
||||
'expected_label' => $error_label,
|
||||
'good_basic_auth' => false,
|
||||
),
|
||||
'no-cache-control' => array(
|
||||
'responses' => array_fill( 0, 3, array() ),
|
||||
'expected_status' => 'critical',
|
||||
'expected_label' => $critical_label,
|
||||
'good_basic_auth' => null,
|
||||
'delay_the_response' => true,
|
||||
),
|
||||
'no-cache' => array(
|
||||
'responses' => array_fill( 0, 3, array( 'cache-control' => 'no-cache' ) ),
|
||||
'expected_status' => 'recommended',
|
||||
'expected_label' => $recommended_label,
|
||||
),
|
||||
'no-cache-arrays' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array(
|
||||
'cache-control' => array(
|
||||
'no-cache',
|
||||
'no-store',
|
||||
),
|
||||
)
|
||||
),
|
||||
'expected_status' => 'recommended',
|
||||
'expected_label' => $recommended_label,
|
||||
),
|
||||
'no-cache-with-delayed-response' => array(
|
||||
'responses' => array_fill( 0, 3, array( 'cache-control' => 'no-cache' ) ),
|
||||
'expected_status' => 'critical',
|
||||
'expected_label' => $critical_label,
|
||||
'good_basic_auth' => null,
|
||||
'delay_the_response' => true,
|
||||
),
|
||||
'age' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'age' => '1345' )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
'cache-control-max-age' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'cache-control' => 'public; max-age=600' )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
'etag' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'etag' => '"1234567890"' )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
'cache-control-max-age-after-2-requests' => array(
|
||||
'responses' => array(
|
||||
array(),
|
||||
array(),
|
||||
array( 'cache-control' => 'public; max-age=600' ),
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
'cache-control-with-future-expires' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'expires' => gmdate( 'r', time() + MINUTE_IN_SECONDS * 10 ) )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
'cache-control-with-past-expires' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'expires' => gmdate( 'r', time() - MINUTE_IN_SECONDS * 10 ) )
|
||||
),
|
||||
'expected_status' => 'critical',
|
||||
'expected_label' => $critical_label,
|
||||
'good_basic_auth' => null,
|
||||
'delay_the_response' => true,
|
||||
),
|
||||
'cache-control-with-basic-auth' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'cache-control' => 'public; max-age=600' )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
'good_basic_auth' => true,
|
||||
),
|
||||
'x-cache-enabled' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'x-cache-enabled' => 'true' )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
'x-cache-enabled-with-delay' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'x-cache-enabled' => 'false' )
|
||||
),
|
||||
'expected_status' => 'critical',
|
||||
'expected_label' => $critical_label,
|
||||
'good_basic_auth' => null,
|
||||
'delay_the_response' => true,
|
||||
),
|
||||
'x-cache-disabled' => array(
|
||||
'responses' => array_fill(
|
||||
0,
|
||||
3,
|
||||
array( 'x-cache-disabled' => 'off' )
|
||||
),
|
||||
'expected_status' => 'good',
|
||||
'expected_label' => $good_label,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user