Skip to content
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

is_dir() randomly failing for vfsStreamDirectory #242

Open
rask opened this issue Sep 2, 2020 · 1 comment
Open

is_dir() randomly failing for vfsStreamDirectory #242

rask opened this issue Sep 2, 2020 · 1 comment

Comments

@rask
Copy link

rask commented Sep 2, 2020

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.

@rask
Copy link
Author

rask commented Jun 7, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants