1 bootstrap.test | BootstrapPageCacheTestCase::testPageCache() |
Test cache headers.
File
- core/
modules/ simpletest/ tests/ bootstrap.test, line 195
Class
Code
function testPageCache() {
config_set('system.core', 'cache', 1);
config_set('system.core', 'page_cache_background_fetch', 0);
config_set('system.core', 'page_cache_maximum_age', 300);
// Emulate a browser's support for keep-alive so that we can check
// Connection: "close" headers.
$headers = array('Connection: "keep-alive"');
// Fill the cache.
$this->backdropGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')), $headers);
$this->assertEqual($this->backdropGetHeader('X-Backdrop-Cache'), 'MISS', 'Page was not cached.');
$this->assertEqual($this->backdropGetHeader('Vary'), 'Cookie,Accept-Encoding', 'Vary header was sent.');
$this->assertEqual($this->backdropGetHeader('Cache-Control'), 'public, max-age=300', 'Cache-Control header was sent.');
$this->assertEqual($this->backdropGetHeader('Expires'), 'Fri, 16 Jan 2015 07:50:00 GMT', 'Expires header was sent.');
$this->assertEqual($this->backdropGetHeader('Foo'), 'bar', 'Custom header was sent.');
$this->assertEqual($this->backdropGetHeader('Connection'), 'close', 'Connection header set to closed when hitting an uncached page.');
// Check cache.
sleep(5); // Delay to ensure caches are set.
$this->backdropGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')), $headers);
$this->assertEqual($this->backdropGetHeader('X-Backdrop-Cache'), 'HIT', 'Page was cached.');
$this->assertEqual($this->backdropGetHeader('Vary'), 'Cookie,Accept-Encoding', 'Vary: Cookie header was sent.');
$this->assertEqual($this->backdropGetHeader('Cache-Control'), 'public, max-age=300', 'Cache-Control header was sent.');
$this->assertEqual($this->backdropGetHeader('Expires'), 'Fri, 16 Jan 2015 07:50:00 GMT', 'Expires header was sent.');
$this->assertEqual($this->backdropGetHeader('Foo'), 'bar', 'Custom header was sent.');
$this->assertEqual($this->backdropGetHeader('Connection'), 'Keep-Alive', 'Connection header set to keep alive when getting a cached page.');
// Check replacing default headers.
$this->backdropGet('system-test/set-header', array('query' => array('name' => 'Expires', 'value' => 'Fri, 19 Nov 2008 05:00:00 GMT')), $headers);
$this->assertEqual($this->backdropGetHeader('Expires'), 'Fri, 19 Nov 2008 05:00:00 GMT', 'Default header was replaced.');
$this->backdropGet('system-test/set-header', array('query' => array('name' => 'Vary', 'value' => 'User-Agent')), $headers);
$this->assertEqual($this->backdropGetHeader('Vary'), 'User-Agent,Accept-Encoding', 'Default header was replaced.');
// Check setting the cache via an HTTP HEAD request.
$this->backdropHead('system-test/hello-world', array('query' => array('cache' => 'test')));
$this->assertEqual($this->backdropGetHeader('X-Backdrop-Cache'), 'MISS', 'Cache miss on first request via HTTP HEAD request.');
sleep(5); // Delay to ensure caches are set.
$this->backdropGet('system-test/hello-world', array('query' => array('cache' => 'test')));
$this->assertEqual($this->backdropGetHeader('X-Backdrop-Cache'), 'HIT', 'Cache hit on second request via HTTP GET request.');
$this->assertText('Hello world!', 'Page contents shown from cached page that was set via an HTTP HEAD request.');
// Test that the initial load does not wait for shutdown functions.
// This request will wait 10 seconds, but it should return faster than this
// because Backdrop does not wait for shutdown functions after the page
// has been delivered.
$start = microtime(TRUE);
$this->backdropGet('system-test/sleep/shutdown/5', array(), $headers);
$total = microtime(TRUE) - $start;
$this->assertEqual($this->backdropGetHeader('X-Backdrop-Cache'), 'MISS', 'Initial page request was miss.');
$this->assertTrue($total < 5, 'Initial page requests returned before shutdown functions are executed.');
sleep(5); // Delay to ensure caches are set.
$start = microtime(TRUE);
$this->backdropGet('system-test/sleep/shutdown/5', array(), $headers);
$total = microtime(TRUE) - $start;
$this->assertEqual($this->backdropGetHeader('X-Backdrop-Cache'), 'HIT', 'Cached page request.');
$this->assertTrue($total < 5, 'Cached page requests returned without executing shutdown functions.');
// Check when background fetch is disabled that a delay takes place when
// generating a new cache entry.
config_set('system.core', 'page_cache_maximum_age', 5);
config_set('system.core', 'page_cache_background_fetch', 0);
// Create a new cache entry.
$this->backdropGet('system-test/sleep/0', array(), $headers);
$this->assertIdentical($this->backdropGetHeader('Cache-Control'), 'public, max-age=5');
$start_element = $this->xpath('//div[@id="start"]');
$start_time1 = (string) $start_element[0];
// Wait 5 seconds to wait past the maximum age (6). Fresh copy expected.
sleep(5);
$this->backdropGet('system-test/sleep/6', array('query' => array('cache' => $this->randomName())));
$this->backdropGet('system-test/sleep/0', array(), $headers);
$start_element = $this->xpath('//div[@id="start"]');
$start_time2 = (string) $start_element[0];
$this->assertNotIdentical($start_time1, $start_time2, 'Fresh page generated after waiting cache lifetime.');
$this->assertIdentical($this->backdropGetHeader('X-Backdrop-Cache'), 'MISS');
// Clear the current cache to try with background fetch enabled.
cache('page')->flush();
config_set('system.core', 'page_cache_background_fetch', 1);
// Do the double-hit again with a delay in between.
$this->backdropGet('system-test/sleep/0', array(), $headers);
$start_element = $this->xpath('//div[@id="start"]');
$start_time1 = (string) $start_element[0];
// Wait 6 seconds to wait past the maximum age (5). Stale copy expected.
sleep(6);
$this->backdropGet('system-test/sleep/0', array(), $headers);
$start_element = $this->xpath('//div[@id="start"]');
$start_time2 = (string) $start_element[0];
$this->assertIdentical($start_time1, $start_time2, 'Stale page served after waiting cache lifetime.');
$this->assertIdentical($this->backdropGetHeader('X-Backdrop-Cache'), 'HIT');
// When a stale page is served, the connection is closed to prevent the PHP
// process from holding up other assets (JS/CSS/images) from waiting to use
// that same connection.
$this->assertIdentical($this->backdropGetHeader('Connection'), 'close', 'Connection closed after serving stale page to allow background processes to run.');
// Wait 1 more second, after which the new cache entry should be saved.
sleep(1);
$this->backdropGet('system-test/sleep/0', array(), $headers);
$start_element = $this->xpath('//div[@id="start"]');
$start_time3 = (string) $start_element[0];
$this->assertNotIdentical($start_time2, $start_time3, 'A fresh page is shown on the next page load (generated by the previous request).');
$this->assertIdentical($this->backdropGetHeader('X-Backdrop-Cache'), 'HIT');
$this->assertIdentical($this->backdropGetHeader('Connection'), 'Keep-Alive', 'Connection header not set keep-alive when serving cached page.');
// Check that authenticated users bypass the cache.
$user = $this->backdropCreateUser();
$this->backdropLogin($user);
$this->backdropGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar')), $headers);
$this->assertFalse($this->backdropGetHeader('X-Backdrop-Cache'), 'Caching was bypassed.');
$this->assertTrue(strpos($this->backdropGetHeader('Vary'), 'Cookie') === FALSE, 'Vary: Cookie header was not sent.');
$this->assertEqual($this->backdropGetHeader('Cache-Control'), 'no-cache, must-revalidate', 'Cache-Control header was sent.');
$this->assertEqual($this->backdropGetHeader('Expires'), 'Fri, 16 Jan 2015 07:50:00 GMT', 'Expires header was sent.');
$this->assertEqual($this->backdropGetHeader('Foo'), 'bar', 'Custom header was sent.');
$this->backdropLogout();
// Check that 403 pages are refreshed properly after caches expire.
$this->backdropGet('system-test/access');
$this->assertResponse(200, 'Access granted by default on first page load.');
// Disable access.
state_set('system_test_access', FALSE);
// Wait 6 seconds to wait past the maximum age (5). Stale copy expected.
sleep(6);
$this->backdropGet('system-test/access');
$this->assertResponse(200, 'Background fetch copy served after blocking access.');
$this->assertText(t('Access granted'), 'Access granted page title shown.');
// Fresh copy should now be a 403.
sleep(2);
$this->backdropGet('system-test/access');
$this->assertResponse(403, 'Access denied on basic callback on fresh copy.');
$this->assertText(t('Access denied'), 'Access denied page title shown.');
// Enable access.
state_set('system_test_access', TRUE);
// Wait 6 seconds to wait past the maximum age (5). Stale copy expected.
sleep(6);
$this->backdropGet('system-test/access');
$this->assertResponse(403, 'Background fetch copy served after granting access.');
$this->assertText(t('Access denied'), 'Access denied page title shown.');
// Fresh copy should now be a 200.
sleep(2);
$this->backdropGet('system-test/access');
$this->assertResponse(200, 'Access granted on basic callback on fresh copy.');
$this->assertText(t('Access granted'), 'Access granted page title shown.');
}