Skip to content

Commit

Permalink
Merge pull request #212 from bizurkur/add-erroneous-file
Browse files Browse the repository at this point in the history
Add an erroneous file for triggering failure cases
  • Loading branch information
bizurkur committed Feb 18, 2020
2 parents 5ec5bdb + e008035 commit 9901c04
Show file tree
Hide file tree
Showing 5 changed files with 935 additions and 10 deletions.
26 changes: 26 additions & 0 deletions src/vfsStream.php
Expand Up @@ -374,6 +374,32 @@ public static function newFile(string $name, ?int $permissions = null): vfsStrea
return new vfsStreamFile($name, $permissions);
}

/**
* Returns a new erroneous file with given name.
*
* Allows for throwing an error during fopen, fwrite, etc.
*
* For example:
*
* $file = vfsStream::newErroneousFile('foo.txt', ['open' => 'error message']);
*
* Will generate a file that always fails on open and displays "error message".
*
* You can set errors for: open, read, write, truncate, tell, seek, stat,
* eof, and lock.
*
* @param string $name name of file to create
* @param string[] $errorMessages Formatted as [action => message], e.g. ['open' => 'error message']
* @param int|null $permissions permissions of file to create
*/
public static function newErroneousFile(
string $name,
array $errorMessages,
?int $permissions = null
): vfsStreamErroneousFile {
return new vfsStreamErroneousFile($name, $errorMessages, $permissions);
}

/**
* returns a new directory with given name
*
Expand Down
251 changes: 251 additions & 0 deletions src/vfsStreamErroneousFile.php
@@ -0,0 +1,251 @@
<?php

declare(strict_types=1);

/**
* This file is part of vfsStream.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace bovigo\vfs;

use const E_USER_WARNING;
use function trigger_error;

/**
* File to trigger errors on specific actions.
*
* Allows for throwing an error during fopen, fwrite, etc.
*
* @api
*/
class vfsStreamErroneousFile extends vfsStreamFile
{
/** @var string[] */
private $errorMessages;

/**
* @param string[] $errorMessages Formatted as [action => message], e.g. ['open' => 'error message']
* @param int|null $permissions optional
*/
public function __construct(string $name, array $errorMessages, ?int $permissions = null)
{
parent::__construct($name, $permissions);

$this->errorMessages = $errorMessages;
}

/**
* {@inheritDoc}
*/
public function open(): void
{
if (isset($this->errorMessages['open'])) {
trigger_error($this->errorMessages['open'], E_USER_WARNING);

return;
}

parent::open();
}

/**
* {@inheritDoc}
*/
public function openForAppend(): void
{
if (isset($this->errorMessages['open'])) {
trigger_error($this->errorMessages['open'], E_USER_WARNING);

return;
}

parent::openForAppend();
}

/**
* {@inheritDoc}
*/
public function openWithTruncate(): void
{
if (isset($this->errorMessages['open'])) {
trigger_error($this->errorMessages['open'], E_USER_WARNING);

return;
}

parent::openWithTruncate();
}

/**
* {@inheritDoc}
*/
public function read(int $count): string
{
if (isset($this->errorMessages['read'])) {
trigger_error($this->errorMessages['read'], E_USER_WARNING);

return '';
}

return parent::read($count);
}

/**
* {@inheritDoc}
*/
public function readUntilEnd(): string
{
if (isset($this->errorMessages['read'])) {
trigger_error($this->errorMessages['read'], E_USER_WARNING);

return '';
}

return parent::readUntilEnd();
}

/**
* {@inheritDoc}
*/
public function write(string $data): int
{
if (isset($this->errorMessages['write'])) {
trigger_error($this->errorMessages['write'], E_USER_WARNING);

return 0;
}

return parent::write($data);
}

/**
* {@inheritDoc}
*/
public function truncate(int $size): bool
{
if (isset($this->errorMessages['truncate'])) {
trigger_error($this->errorMessages['truncate'], E_USER_WARNING);

return false;
}

return parent::truncate($size);
}

/**
* {@inheritDoc}
*/
public function eof(): bool
{
if (isset($this->errorMessages['eof'])) {
trigger_error($this->errorMessages['eof'], E_USER_WARNING);

// True on error.
// See: https://www.php.net/manual/en/function.feof.php#refsect1-function.feof-returnvalues
return true;
}

return parent::eof();
}

/**
* {@inheritDoc}
*/
public function getBytesRead(): int
{
if (isset($this->errorMessages['tell'])) {
trigger_error($this->errorMessages['tell'], E_USER_WARNING);

return 0;
}

return parent::getBytesRead();
}

/**
* {@inheritDoc}
*/
public function seek(int $offset, int $whence): bool
{
if (isset($this->errorMessages['seek'])) {
trigger_error($this->errorMessages['seek'], E_USER_WARNING);

return false;
}

return parent::seek($offset, $whence);
}

/**
* {@inheritDoc}
*/
public function size(): int
{
if (isset($this->errorMessages['stat'])) {
trigger_error($this->errorMessages['stat'], E_USER_WARNING);

return -1;
}

return parent::size();
}

/**
* {@inheritDoc}
*/
public function lock($resource, int $operation): bool
{
if (isset($this->errorMessages['lock'])) {
trigger_error($this->errorMessages['lock'], E_USER_WARNING);

return false;
}

return parent::lock($resource, $operation);
}

/**
* {@inheritDoc}
*/
public function filemtime(): int
{
if (isset($this->errorMessages['stat'])) {
trigger_error($this->errorMessages['stat'], E_USER_WARNING);

return -1;
}

return parent::filemtime();
}

/**
* {@inheritDoc}
*/
public function fileatime(): int
{
if (isset($this->errorMessages['stat'])) {
trigger_error($this->errorMessages['stat'], E_USER_WARNING);

return -1;
}

return parent::fileatime();
}

/**
* {@inheritDoc}
*/
public function filectime(): int
{
if (isset($this->errorMessages['stat'])) {
trigger_error($this->errorMessages['stat'], E_USER_WARNING);

return -1;
}

return parent::filectime();
}
}
36 changes: 26 additions & 10 deletions src/vfsStreamWrapper.php
Expand Up @@ -679,10 +679,18 @@ public function stream_flush(): bool
/**
* returns status of stream
*
* @return mixed[]
* @return int[]|false
*/
public function stream_stat(): array
public function stream_stat()
{
$atime = $this->content->fileatime();
$ctime = $this->content->filectime();
$mtime = $this->content->filemtime();
$size = $this->content->size();
if ($atime === -1 || $ctime === -1 || $mtime === -1 || $size === -1) {
return false;
}

$fileStat = [
'dev' => 0,
'ino' => spl_object_id($this->content),
Expand All @@ -691,10 +699,10 @@ public function stream_stat(): array
'uid' => $this->content->getUser(),
'gid' => $this->content->getGroup(),
'rdev' => 0,
'size' => $this->content->size(),
'atime' => $this->content->fileatime(),
'mtime' => $this->content->filemtime(),
'ctime' => $this->content->filectime(),
'size' => $size,
'atime' => $atime,
'mtime' => $mtime,
'ctime' => $ctime,
'blksize' => -1,
'blocks' => -1,
];
Expand Down Expand Up @@ -1035,6 +1043,14 @@ public function url_stat(string $path, int $flags)
return false;
}

$atime = $content->fileatime();
$ctime = $content->filectime();
$mtime = $content->filemtime();
$size = $content->size();
if ($atime === -1 || $ctime === -1 || $mtime === -1 || $size === -1) {
return false;
}

$fileStat = [
'dev' => 0,
'ino' => spl_object_id($content),
Expand All @@ -1043,10 +1059,10 @@ public function url_stat(string $path, int $flags)
'uid' => $content->getUser(),
'gid' => $content->getGroup(),
'rdev' => 0,
'size' => $content->size(),
'atime' => $content->fileatime(),
'mtime' => $content->filemtime(),
'ctime' => $content->filectime(),
'size' => $size,
'atime' => $atime,
'mtime' => $mtime,
'ctime' => $ctime,
'blksize' => -1,
'blocks' => -1,
];
Expand Down

0 comments on commit 9901c04

Please sign in to comment.