ReadableStreamFunctionalTest.php 6.85 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
<?php

namespace MongoDB\Tests\GridFS;

use MongoDB\BSON\Binary;
use MongoDB\GridFS\CollectionWrapper;
use MongoDB\GridFS\ReadableStream;

/**
 * Functional tests for the internal ReadableStream class.
 */
class ReadableStreamFunctionalTest extends FunctionalTestCase
{
    private $collectionWrapper;

    public function setUp()
    {
        parent::setUp();

        $this->collectionWrapper = new CollectionWrapper($this->manager, $this->getDatabaseName(), 'fs');

        $this->filesCollection->insertMany([
            ['_id' => 'length-0', 'length' => 0, 'chunkSize' => 4],
            ['_id' => 'length-0-with-empty-chunk', 'length' => 0, 'chunkSize' => 4],
            ['_id' => 'length-2', 'length' => 2, 'chunkSize' => 4],
            ['_id' => 'length-8', 'length' => 8, 'chunkSize' => 4],
            ['_id' => 'length-10', 'length' => 10, 'chunkSize' => 4],
        ]);

        $this->chunksCollection->insertMany([
            ['_id' => 1, 'files_id' => 'length-0-with-empty-chunk', 'n' => 0, 'data' => new Binary('', Binary::TYPE_GENERIC)],
            ['_id' => 2, 'files_id' => 'length-2', 'n' => 0, 'data' => new Binary('ab', Binary::TYPE_GENERIC)],
            ['_id' => 3, 'files_id' => 'length-8', 'n' => 0, 'data' => new Binary('abcd', Binary::TYPE_GENERIC)],
            ['_id' => 4, 'files_id' => 'length-8', 'n' => 1, 'data' => new Binary('efgh', Binary::TYPE_GENERIC)],
            ['_id' => 5, 'files_id' => 'length-10', 'n' => 0, 'data' => new Binary('abcd', Binary::TYPE_GENERIC)],
            ['_id' => 6, 'files_id' => 'length-10', 'n' => 1, 'data' => new Binary('efgh', Binary::TYPE_GENERIC)],
            ['_id' => 7, 'files_id' => 'length-10', 'n' => 2, 'data' => new Binary('ij', Binary::TYPE_GENERIC)],
        ]);
    }

    public function testValidConstructorFileDocument()
    {
        new ReadableStream($this->collectionWrapper, (object) ['_id' => null, 'chunkSize' => 1, 'length' => 0]);
    }

    /**
     * @expectedException MongoDB\GridFS\Exception\CorruptFileException
     * @dataProvider provideInvalidConstructorFileDocuments
     */
    public function testConstructorFileDocumentChecks($file)
    {
        new ReadableStream($this->collectionWrapper, $file);
    }

    public function provideInvalidConstructorFileDocuments()
    {
        $options = [];

        foreach ($this->getInvalidIntegerValues() as $value) {
            $options[][] = (object) ['_id' => 1, 'chunkSize' => $value, 'length' => 0];
        }

        foreach ($this->getInvalidIntegerValues() as $value) {
            $options[][] = (object) ['_id' => 1, 'chunkSize' => 1, 'length' => $value];
        }

        $options[][] = (object) ['_id' => 1, 'chunkSize' => 0, 'length' => 0];
        $options[][] = (object) ['_id' => 1, 'chunkSize' => 1, 'length' => -1];
        $options[][] = (object) ['chunkSize' => 1, 'length' => 0];

        return $options;
    }

    /**
     * @dataProvider provideFileIdAndExpectedBytes
     */
77
    public function testReadBytes($fileId, $length, $expectedBytes)
78 79 80 81
    {
        $fileDocument = $this->collectionWrapper->findFileById($fileId);
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

82
        $this->assertSame($expectedBytes, $stream->readBytes($length));
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    }

    public function provideFileIdAndExpectedBytes()
    {
        return [
            ['length-0', 0, ''],
            ['length-0', 2, ''],
            ['length-0-with-empty-chunk', 0, ''],
            ['length-0-with-empty-chunk', 2, ''],
            ['length-2', 0, ''],
            ['length-2', 2, 'ab'],
            ['length-2', 4, 'ab'],
            ['length-8', 0, ''],
            ['length-8', 2, 'ab'],
            ['length-8', 4, 'abcd'],
            ['length-8', 6, 'abcdef'],
            ['length-8', 8, 'abcdefgh'],
            ['length-8', 10, 'abcdefgh'],
            ['length-10', 0, ''],
            ['length-10', 2, 'ab'],
            ['length-10', 4, 'abcd'],
            ['length-10', 6, 'abcdef'],
            ['length-10', 8, 'abcdefgh'],
            ['length-10', 10, 'abcdefghij'],
            ['length-10', 12, 'abcdefghij'],
        ];
    }

    /**
     * @dataProvider provideFileIdAndExpectedBytes
     */
114
    public function testReadBytesCalledMultipleTimes($fileId, $length, $expectedBytes)
115 116 117 118
    {
        $fileDocument = $this->collectionWrapper->findFileById($fileId);
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

119
        for ($i = 0; $i < $length; $i++) {
120
            $expectedByte = isset($expectedBytes[$i]) ? $expectedBytes[$i] : '';
121
            $this->assertSame($expectedByte, $stream->readBytes(1));
122 123 124 125 126 127 128
        }
    }

    /**
     * @expectedException MongoDB\GridFS\Exception\CorruptFileException
     * @expectedExceptionMessage Chunk not found for index "2"
     */
129
    public function testReadBytesWithMissingChunk()
130 131 132 133 134 135
    {
        $this->chunksCollection->deleteOne(['files_id' => 'length-10', 'n' => 2]);

        $fileDocument = $this->collectionWrapper->findFileById('length-10');
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

136
        $stream->readBytes(10);
137 138 139 140 141 142
    }

    /**
     * @expectedException MongoDB\GridFS\Exception\CorruptFileException
     * @expectedExceptionMessage Expected chunk to have index "1" but found "2"
     */
143
    public function testReadBytesWithUnexpectedChunkIndex()
144 145 146 147 148 149
    {
        $this->chunksCollection->deleteOne(['files_id' => 'length-10', 'n' => 1]);

        $fileDocument = $this->collectionWrapper->findFileById('length-10');
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

150
        $stream->readBytes(10);
151 152 153 154 155 156
    }

    /**
     * @expectedException MongoDB\GridFS\Exception\CorruptFileException
     * @expectedExceptionMessage Expected chunk to have size "2" but found "1"
     */
157
    public function testReadBytesWithUnexpectedChunkSize()
158 159 160 161 162 163 164 165 166
    {
        $this->chunksCollection->updateOne(
            ['files_id' => 'length-10', 'n' => 2],
            ['$set' => ['data' => new Binary('i', Binary::TYPE_GENERIC)]]
        );

        $fileDocument = $this->collectionWrapper->findFileById('length-10');
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

167
        $stream->readBytes(10);
168 169 170 171 172
    }

    /**
     * @expectedException MongoDB\Exception\InvalidArgumentException
     */
173
    public function testReadBytesWithNegativeLength()
174 175 176 177
    {
        $fileDocument = $this->collectionWrapper->findFileById('length-0');
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

178
        $stream->readBytes(-1);
179
    }
180 181 182 183 184 185 186 187 188 189 190 191

    /**
     * @expectedException MongoDB\Exception\InvalidArgumentException
     * @expectedExceptionMessage $offset must be >= 0 and <= 10; given: 11
     */
    public function testSeekOutOfRange()
    {
        $fileDocument = $this->collectionWrapper->findFileById('length-10');
        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);

        $stream->seek(11);
    }
192
}