Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Use current time() instead of Request Time for the expiration TTL #85

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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 src/AbstractContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ public function getIterator()
public function setExpirationSeconds($ttl, $vars = null)
{
$storage = $this->getStorage();
$ts = $_SERVER['REQUEST_TIME'] + $ttl;
$ts = time() + $ttl;
if (is_scalar($vars) && null !== $vars) {
$vars = (array) $vars;
}
Expand Down
23 changes: 17 additions & 6 deletions test/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,22 +193,24 @@ public function testContainerWritesToStorage()

public function testSettingExpirationSecondsUpdatesStorageMetadataForFullContainer()
{
$currentTimestamp = time();
$this->container->setExpirationSeconds(3600);
$storage = $this->manager->getStorage();
$metadata = $storage->getMetadata($this->container->getName());
$this->assertArrayHasKey('EXPIRE', $metadata);
$this->assertEquals($_SERVER['REQUEST_TIME'] + 3600, $metadata['EXPIRE']);
$this->assertEquals($currentTimestamp + 3600, $metadata['EXPIRE']);
}

public function testSettingExpirationSecondsForIndividualKeyUpdatesStorageMetadataForThatKey()
{
$this->container->foo = 'bar';
$currentTimestamp = time();
$this->container->setExpirationSeconds(3600, 'foo');
$storage = $this->manager->getStorage();
$metadata = $storage->getMetadata($this->container->getName());
$this->assertArrayHasKey('EXPIRE_KEYS', $metadata);
$this->assertArrayHasKey('foo', $metadata['EXPIRE_KEYS']);
$this->assertEquals($_SERVER['REQUEST_TIME'] + 3600, $metadata['EXPIRE_KEYS']['foo']);
$this->assertEquals($currentTimestamp + 3600, $metadata['EXPIRE_KEYS']['foo']);
}

public function testMultipleCallsToExpirationSecondsAggregates()
Expand All @@ -217,15 +219,24 @@ public function testMultipleCallsToExpirationSecondsAggregates()
$this->container->bar = 'baz';
$this->container->baz = 'bat';
$this->container->bat = 'bas';
$currentTimestamp = time();
$this->container->setExpirationSeconds(3600);
$this->container->setExpirationSeconds(1800, 'foo');
$this->container->setExpirationSeconds(900, ['baz', 'bat']);
$storage = $this->manager->getStorage();
$metadata = $storage->getMetadata($this->container->getName());
$this->assertEquals($_SERVER['REQUEST_TIME'] + 1800, $metadata['EXPIRE_KEYS']['foo']);
$this->assertEquals($_SERVER['REQUEST_TIME'] + 900, $metadata['EXPIRE_KEYS']['baz']);
$this->assertEquals($_SERVER['REQUEST_TIME'] + 900, $metadata['EXPIRE_KEYS']['bat']);
$this->assertEquals($_SERVER['REQUEST_TIME'] + 3600, $metadata['EXPIRE']);
$this->assertEquals($currentTimestamp + 1800, $metadata['EXPIRE_KEYS']['foo']);
$this->assertEquals($currentTimestamp + 900, $metadata['EXPIRE_KEYS']['baz']);
$this->assertEquals($currentTimestamp + 900, $metadata['EXPIRE_KEYS']['bat']);
$this->assertEquals($currentTimestamp + 3600, $metadata['EXPIRE']);
}

public function testSettingExpirationSecondsUsesCurrentTime()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this test doesn't prove the fix.

To test, I reverted the change you provided (s/time()/$_SERVER['REQUEST_TIME']/), and ran just this test; it passed. I tried resetting the sleep and expiration seconds values as well, but they always passed. I also tried putting the assignment prior to the setExpirationSeconds() method, and that did not work, either.

While I do not doubt that the fix is correct, we need an accurate way to test it that emulates what happens in a normal server-side web request so that we can ensure the fix is correct and will not break with future updates.

{
sleep(3);
$this->container->setExpirationSeconds(2);
$this->container->foo = 'bar';
$this->assertEquals('bar', $this->container->foo);
}

public function testPassingUnsetKeyToSetExpirationSecondsDoesNothing()
Expand Down