is_dir() randomly failing for vfsStreamDirectory
I have a test suite where I create a directory with vfsStream, which is meant to simulate a write-blocked directory for my SUT. In my code the logic checks both is_dir() and is_writable() for a directory to give granural errors to the user.
Now, in my test case I have to use __construct() as the directory is fetched in the test case via data providers, which are run before setUp. The constructor creates the directory as follows:
public function __construct(?string $name = null, array $data = [], $dataName = '')
{
parent::__construct($name, $data, $dataName);
vfsStream::setup();
$tmpdir_name = md5((string) time());
$tmpdir = new vfsStreamDirectory($tmpdir_name);
$tmpdir->chmod(0444);
vfsStreamWrapper::getRoot()->addChild($tmpdir);
assert(vfsStreamWrapper::getRoot()->hasChild($tmpdir_name));
$this->unwritable_tmp_directory = vfsStreamWrapper::getRoot()->getChild($tmpdir_name)->url();
}
Here is the test case code I'm running:
public function badTemporaryDirectories() : array
{
return [
['/missing/directory', '/missing/i'],
[$this->unwritable_tmp_directory, '/unwritable/i'],
];
}
/**
* @dataProvider badTemporaryDirectories
*/
public function test_it_requires_proper_tmpdir(string $directory, string $expected_message) : void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessageMatches($expected_message);
$_ = new Thingy($directory);
}
And the code inside Thingy which I am testing looks as follows:
public function __construct(?string $tmp_dir = null)
{
if ($tmp_dir === null) {
$tmp_dir = \sys_get_temp_dir();
}
/** @var string $tmp_dir */
if (\is_dir($tmp_dir) === false) { // <-- this here randomly fails for existing directory
throw new \InvalidArgumentException('Invalid tempdir: missing');
}
if (\is_writable($tmp_dir) === false) {
throw new \InvalidArgumentException('Invalid tempdir: unwritable');
}
$this->tmpdir = $tmp_dir;
}
Now, the is_dir() call is randomly failing, even with the assert() in my test case constructor passing all runs properly. It seems like I get 50% success rate, where I can either get no exception from the SUT constructor, or then I land into the "unwritable error branch" as mandated by a test case.
PHP version is 7.4. PHPUnit version is 9.3.8, and vfsStream is at 1.6.8.
This problem seemingly went away after a co-worker removed the data provider and split the target test method into two separate test methods. Will be monitoring whether this permanently fixes the issue or not.