PHP - PHPUnit - тестирование возможности защиты файловой блокировки - PullRequest
3 голосов
/ 04 февраля 2012

Я работаю над обновлением модульных тестов для своей базовой библиотеки и натолкнулся на сценарий, касающийся блокировок файлов (flock), и хотел посмотреть, как другие реализуют эти типы модульных тестов.Класс файла, который будет записывать содержимое в файл:

class CoreLib_Api_File_Package
{
    public static function write(array $options)
    {
        ...

        if (!$file->flock(LOCK_EX)) {
            throw new CoreLib_Api_Exception('Unable to obtain lock on file');
        }

        ...
    }
}

И мой модульный тест выглядит следующим образом:

public function testWriteException_UnableToSecureLock()
{
    $this->touchFile($this->destFileUri);

    $file = new SplFileObject($this->destFileUri, CoreLib_Api_File::MODE_WRITE);

    $file->flock(LOCK_EX);

    CoreLib_Api_File_Package::write(array('fileUri' => $this->destFileUri, 'content' => $this->testContent, 'mode' => CoreLib_Api_File::MODE_WRITE));
}

Как видно из кода теста, я устанавливаю явную блокировку$this->destFileUri до того, как я вызову API для метода write().Я ожидаю, что будет выдано исключение throw new CoreLib_Api_Exception('Unable to obtain lock on file');.Вместо этого мой модульный тест просто зависает на неопределенное время.

Как правильно проверить, не заблокирован ли файл?

Заранее спасибо.

1 Ответ

3 голосов
/ 04 февраля 2012

Вы должны проверить этот комментарий на странице flock документов .

По существу, flock приостановит выполнение, пока не сможет получить блокировку. Возьмите следующий код, который похож на вашу ситуацию выше:

$file = 'file.txt';

$first = fopen($file, "w");
flock($first, LOCK_EX);

$second = fopen($file, "w");

# Your script will pause on the next line until timeout
# due to the inability to obtain a lock.
flock($second, LOCK_EX);

Однако вы можете получить неблокирующие блокировки, например:

flock($file, LOCK_EX | LOCK_NB);

Я не уверен, есть ли негативные последствия для блокировки файлов таким способом. Кроме того, , в то время как документы говорят, что LOCK_NB не работает в Windows, я просто протестировал его, и он работал на моей машине . Итак, вы можете сделать что-то подобное в вашем CoreLib_Api_File_Package::write методе:

class CoreLib_Api_File_Package
{
    public static function write(array $options)
    {
        if ( ! $file->flock(LOCK_EX | LOCK_NB))
        {
            throw new CoreLib_Api_Exception('Unable to obtain lock on file');
        }
    }
}

Ваш текущий тест должен пройти как написано. Кроме этого, я не могу думать ни о чем.

Редактировать: Они должны пройти, пока вы говорите PHPUnit, что следует ожидать исключения CoreLib_Api_Exception (просто указывает на него, потому что в вашем примере его не было).

...