Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Improved FileResource and DirectoryResource #17598

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

Closed
wants to merge 5 commits into from
Closed
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
8 changes: 7 additions & 1 deletion src/Symfony/Component/Config/Resource/DirectoryResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,17 @@ class DirectoryResource implements SelfCheckingResourceInterface, \Serializable
*
* @param string $resource The file path to the resource
* @param string|null $pattern A pattern to restrict monitored files
*
* @throws \InvalidArgumentException
*/
public function __construct($resource, $pattern = null)
{
$this->resource = $resource;
$this->resource = realpath($resource);
$this->pattern = $pattern;

if (false === $this->resource || !is_dir($this->resource)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $resource));
}
}

/**
Expand Down
16 changes: 9 additions & 7 deletions src/Symfony/Component/Config/Resource/FileResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,28 @@ class FileResource implements SelfCheckingResourceInterface, \Serializable
* Constructor.
*
* @param string $resource The file path to the resource
*
* @throws \InvalidArgumentException
*/
public function __construct($resource)
{
$this->resource = realpath($resource);

if (false === $this->resource) {
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource));
Copy link
Member

Choose a reason for hiding this comment

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

This change breaks our test suite. For example, the ObjectRouteLoader registers FileResource instances based on the filename returned by the ReflectionClass: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Routing/Loader/ObjectRouteLoader.php#L90 However, this fails when the object is a PHPUnit mock object, see https://travis-ci.org/symfony/symfony/jobs/106738857#L3760 (I am also not sure how this is working with classes stored in phar archives).

Copy link
Member

Choose a reason for hiding this comment

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

The question is how we fix this. I tend to fix the creation of FileResource instances to only build these objects when we handle "real" files. However, if we experience these issues in our test suite, isn't this something that will likely appear to other users too and (unexpectedly) break their applications?

Copy link
Member

Choose a reason for hiding this comment

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

Well, for eval'd classes, the code was already weird before as it was creating a FileResource for something which is not a file. so I would consider it a bug in the ObjectRouteLoader

Copy link
Member

Choose a reason for hiding this comment

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

see #17672 and #17673

}
}

/**
* {@inheritdoc}
*/
public function __toString()
{
return (string) $this->resource;
return $this->resource;
}

/**
* @return string|false The canonicalized, absolute path to the resource or false if the resource does not exist.
* @return string The canonicalized, absolute path to the resource.
*/
public function getResource()
{
Expand All @@ -56,11 +62,7 @@ public function getResource()
*/
public function isFresh($timestamp)
{
if (false === $this->resource || !file_exists($this->resource)) {
return false;
}

return filemtime($this->resource) <= $timestamp;
return file_exists($this->resource) && @filemtime($this->resource) <= $timestamp;
Copy link
Contributor

Choose a reason for hiding this comment

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

filemtime returns false on error which means isFresh evaluetes to true in this case (false < timestamp) which is wrong.

}

public function serialize()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase

protected function setUp()
{
$this->directory = sys_get_temp_dir().'/symfonyDirectoryIterator';
$this->directory = realpath(sys_get_temp_dir()).'/symfonyDirectoryIterator';
if (!file_exists($this->directory)) {
mkdir($this->directory);
}
Expand Down Expand Up @@ -58,17 +58,31 @@ public function testGetResource()

public function testGetPattern()
{
$resource = new DirectoryResource('foo', 'bar');
$resource = new DirectoryResource($this->directory, 'bar');
$this->assertEquals('bar', $resource->getPattern());
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessageRegExp /The directory ".*" does not exist./
*/
public function testResourceDoesNotExist()
{
$resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999));
}

public function testIsFresh()
{
$resource = new DirectoryResource($this->directory);
$this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
$this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
}

public function testIsFreshForDeletedResources()
{
$resource = new DirectoryResource($this->directory);
$this->removeDirectory($this->directory);

$resource = new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999));
$this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
}

Expand Down
21 changes: 19 additions & 2 deletions src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ protected function setUp()

protected function tearDown()
{
if (!file_exists($this->file)) {
return;
}

unlink($this->file);
}

Expand All @@ -42,14 +46,27 @@ public function testToString()
$this->assertSame(realpath($this->file), (string) $this->resource);
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessageRegExp /The file ".*" does not exist./
*/
public function testResourceDoesNotExist()
{
$resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999));
}

public function testIsFresh()
{
$this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second');
$this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed');
$this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated');
}

$resource = new FileResource('/____foo/foobar'.mt_rand(1, 999999));
$this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
public function testIsFreshForDeletedResources()
{
unlink($this->file);

$this->assertFalse($this->resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist');
}

public function testSerializeUnserialize()
Expand Down