From a683959717ae414e8adf9ba0a5d7dbd6fd5d9a48 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 29 Jan 2016 10:11:55 +0100 Subject: [PATCH 1/5] Improved FileResource and DirectoryResource --- .../Config/Resource/DirectoryResource.php | 8 ++++++- .../Config/Resource/FileResource.php | 6 ++++++ .../Tests/Resource/DirectoryResourceTest.php | 20 +++++++++++++++--- .../Tests/Resource/FileResourceTest.php | 21 +++++++++++++++++-- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 38413934f35d3..c8aaed1863608 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -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 (!is_dir($this->resource)) { + throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $resource)); + } } /** diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 54a974caef3d0..82ee97f3dfd7c 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -29,10 +29,16 @@ 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 (!file_exists($this->resource)) { + throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $resource)); + } } /** diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 2bbaadc3a721e..7d8621edc8bda 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -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); } @@ -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'); } diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index db85cf7bd0eee..41845c4fa9040 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -29,6 +29,10 @@ protected function setUp() protected function tearDown() { + if (!file_exists($this->file)) { + return; + } + unlink($this->file); } @@ -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() From 294522dbb19bb62cae452b68d69783d89b9353f7 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 29 Jan 2016 14:59:19 +0100 Subject: [PATCH 2/5] Fixed the errors pointed by reviewers --- .../Component/Config/Resource/DirectoryResource.php | 2 +- src/Symfony/Component/Config/Resource/FileResource.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index c8aaed1863608..440fe6fe1d96c 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -34,7 +34,7 @@ public function __construct($resource, $pattern = null) $this->resource = realpath($resource); $this->pattern = $pattern; - if (!is_dir($this->resource)) { + if (false === $this->resource || !is_dir($this->resource)) { throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $resource)); } } diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 82ee97f3dfd7c..e8a8459d4ad83 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -36,7 +36,7 @@ public function __construct($resource) { $this->resource = realpath($resource); - if (!file_exists($this->resource)) { + if (false === $this->resource) { throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $resource)); } } @@ -46,11 +46,11 @@ public function __construct($resource) */ 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() { @@ -62,7 +62,7 @@ public function getResource() */ public function isFresh($timestamp) { - if (false === $this->resource || !file_exists($this->resource)) { + if (!file_exists($this->resource)) { return false; } From 648c2e45c9f6938630a9460c333900601e3748ad Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 29 Jan 2016 15:45:15 +0100 Subject: [PATCH 3/5] Tweaked the error messages --- src/Symfony/Component/Config/Resource/DirectoryResource.php | 2 +- src/Symfony/Component/Config/Resource/FileResource.php | 2 +- .../Component/Config/Tests/Resource/DirectoryResourceTest.php | 2 +- .../Component/Config/Tests/Resource/FileResourceTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 440fe6fe1d96c..eaef8d5b1e9b9 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -35,7 +35,7 @@ public function __construct($resource, $pattern = null) $this->pattern = $pattern; if (false === $this->resource || !is_dir($this->resource)) { - throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $resource)); + throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $resource)); } } diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index e8a8459d4ad83..3321f55f483d8 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -37,7 +37,7 @@ public function __construct($resource) $this->resource = realpath($resource); if (false === $this->resource) { - throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $resource)); + throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource)); } } diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 7d8621edc8bda..507224f7c4da4 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -64,7 +64,7 @@ public function testGetPattern() /** * @expectedException \InvalidArgumentException - * @expectedExceptionMessageRegExp /The ".*" directory does not exist./ + * @expectedExceptionMessageRegExp /The directory ".*" does not exist./ */ public function testResourceDoesNotExist() { diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index 41845c4fa9040..4151f66bc5cac 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -48,7 +48,7 @@ public function testToString() /** * @expectedException \InvalidArgumentException - * @expectedExceptionMessageRegExp /The ".*" file does not exist./ + * @expectedExceptionMessageRegExp /The file ".*" does not exist./ */ public function testResourceDoesNotExist() { From 5097d1452ad6d4533cf75227c1e314d72f4df4a1 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 3 Feb 2016 11:03:47 +0100 Subject: [PATCH 4/5] Refactor to try avoid "race conditions" --- src/Symfony/Component/Config/Resource/FileResource.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 3321f55f483d8..d232f56dce49b 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -62,11 +62,7 @@ public function getResource() */ public function isFresh($timestamp) { - if (!file_exists($this->resource)) { - return false; - } - - return filemtime($this->resource) <= $timestamp; + return file_exists($this->resource) && filemtime($this->resource) <= $timestamp; } public function serialize() From f6b92e4197e5ece859514973995dca97c7ac4222 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 3 Feb 2016 13:13:09 +0100 Subject: [PATCH 5/5] Supress errors in filemtime() --- src/Symfony/Component/Config/Resource/FileResource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index d232f56dce49b..f94640fffc34c 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -62,7 +62,7 @@ public function getResource() */ public function isFresh($timestamp) { - return file_exists($this->resource) && filemtime($this->resource) <= $timestamp; + return file_exists($this->resource) && @filemtime($this->resource) <= $timestamp; } public function serialize()