3

私はコア ライブラリの単体テストの更新に取り組んでおり、ファイルロック (群れ) に関するシナリオに出くわし、他の人がこれらの種類の単体テストをどのように実装したかを知りたいと思いました。

基本的に、コンテンツをファイルに書き込むユーティリティ File クラスがあります。

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');がスローされることです。代わりに、単体テストが無期限にハングします。

ファイルがロックされているかどうかをテストする適切な方法は何ですか?

前もって感謝します。

4

1 に答える 1

3

ドキュメント ページのこのコメントを確認してください。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(例にそれがなかったため、それを指摘するだけです)。

于 2012-02-03T23:02:03.917 に答える