Commit 2a99015a authored by Will Banfield's avatar Will Banfield Committed by Jeremy Mikola

added many many more tests, added getIdFromStream

parent 9d1a9cba
......@@ -161,6 +161,16 @@ class Bucket
{
return $this->collectionsWrapper->getFilesCollection()->find($filter, $options);
}
public function getIdFromStream($stream)
{
$metadata = stream_get_meta_data($stream);
if(isset($metadata["wrapper_data"]->id)){
return $metadata["wrapper_data"]->id;
}
return null;
}
public function getCollectionsWrapper()
{
return $this->collectionsWrapper;
......
......@@ -26,15 +26,17 @@ class GridFsDownload
*
*
* @param GridFSCollectionsWrapper $collectionsWrapper File options
* @param \MongoDB\BSON\ObjectId $options File options
* @param array $options File options
* @throws FileNotFoundException
* @param \stdClass $file GridFS file to use
* @throws GridFSCorruptFileException
*/
public function __construct(
GridFSCollectionsWrapper $collectionsWrapper,
$file
)
{
if(!($file instanceof \stdClass)){
throw new \MongoDB\Exception\InvalidArgumentTypeException('"file"', $file, 'stdClass');
}
$this->collectionsWrapper = $collectionsWrapper;
$this->file = $file;
try{
......@@ -81,12 +83,11 @@ class GridFsDownload
$this->bufferEmpty=true;
$bytesLeft = $numToRead - strlen($output);
while(strlen($output) < $numToRead && $this->advanceChunks()) {
$bytesLeft = $numToRead - strlen($output);
$output .= substr($this->chunksIterator->current()->data->getData(), 0, $bytesLeft);
}
if ($this->file->length > 0 && $bytesLeft < strlen($this->chunksIterator->current()->data->getData())) {
if (!$this->iteratorEmpty && $this->file->length > 0 && $bytesLeft < strlen($this->chunksIterator->current()->data->getData())) {
fwrite($this->buffer, substr($this->chunksIterator->current()->data->getData(), $bytesLeft));
$this->bufferEmpty=false;
}
......
......@@ -73,14 +73,14 @@ class GridFsUpload
if (is_string($options['contentType'])) {
$fileOptions['contentType'] = $options['contentType'];
} else {
throw new InvalidArgumentTypeException('"contentType" option', $options['contentType'], 'string');
throw new \MongoDB\Exception\InvalidArgumentTypeException('"contentType" option', $options['contentType'], 'string');
}
}
if (isset($options['aliases'])) {
if (\MongoDB\is_string_array($options['aliases'])) {
$fileOptions['aliases'] = $options['aliases'];
} else {
throw new InvalidArgumentTypeException('"aliases" option', $options['aliases'], 'array of strings');
throw new \MongoDB\Exception\InvalidArgumentTypeException('"aliases" option', $options['aliases'], 'array of strings');
}
}
......@@ -88,7 +88,7 @@ class GridFsUpload
if (is_array($options['metadata']) || is_object($options['metadata'])) {
$fileOptions['metadata'] = $options['metadata'];
} else {
throw new InvalidArgumentTypeException('"metadata" option', $options['metadata'], 'object or array');
throw new \MongoDB\Exception\InvalidArgumentTypeException('"metadata" option', $options['metadata'], 'object or array');
}
}
$this->file = array_merge($main_file, $fileOptions);
......@@ -173,6 +173,10 @@ class GridFsUpload
{
return $this->file;
}
public function isEOF()
{
return false;
}
private function insertChunk($data)
{
$toUpload = ["files_id" => $this->file['_id'], "n" => $this->chunkOffset, "data" => new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_GENERIC)];
......
......@@ -22,6 +22,7 @@ class StreamWrapper
private $mode;
private $gridFsStream;
private $collectionsWrapper;
public $id;
/**
* Register the GridFS stream wrapper.
......@@ -54,7 +55,6 @@ class StreamWrapper
{
$stat = $this->getStatTemplate();
$stat[7] = $stat['size'] = $this->gridFsStream->getSize();
$stat[2] = $stat['mode'] = $this->mode;
return $stat;
}
public function stream_open($path, $mode, $options, &$openedPath)
......@@ -73,12 +73,14 @@ class StreamWrapper
$context = stream_context_get_options($this->context);
$options =$context['gridfs']['uploadOptions'];
$this->gridFsStream = new GridFsUpload($this->collectionsWrapper, $this->identifier, $options);
$this->id = $this->gridFsStream->getId();
return true;
}
public function openReadStream() {
$context = stream_context_get_options($this->context);
$this->gridFsStream = new GridFsDownload($this->collectionsWrapper, $context['gridfs']['file']);
$this->id = $this->gridFsStream->getId();
return true;
}
......
......@@ -114,20 +114,20 @@ class BucketFunctionalTest extends FunctionalTestCase
public function testGetLastVersion()
{
$idOne = $this->bucket->uploadFromStream("test",$this->generateStream("foo"));
//$streamTwo = $this->bucket->openUploadStream("test");
//fwrite($streamTwo, "bar");
$streamTwo = $this->bucket->openUploadStream("test");
fwrite($streamTwo, "bar");
//echo "Calling FSTAT\n";
//$stat = fstat($streamTwo);
//$idTwo = $stat['uid'];
$idTwo = $this->bucket->getIdFromStream($streamTwo);
//var_dump
//var_dump($idTwo);
//fclose($streamTwo);
fclose($streamTwo);
$idThree = $this->bucket->uploadFromStream("test",$this->generateStream("baz"));
$this->assertEquals("baz", stream_get_contents($this->bucket->openDownloadStreamByName("test")));
$this->bucket->delete($idThree);
//$this->assertEquals("bar", stream_get_contents($this->bucket->openDownloadStreamByName("test")));
//$this->bucket->delete($idTwo);
$this->assertEquals("bar", stream_get_contents($this->bucket->openDownloadStreamByName("test")));
$this->bucket->delete($idTwo);
$this->assertEquals("foo", stream_get_contents($this->bucket->openDownloadStreamByName("test")));
$this->bucket->delete($idOne);
$error = null;
......@@ -207,6 +207,42 @@ class BucketFunctionalTest extends FunctionalTestCase
$testStream = fopen($testPath, "r");
$id = $this->bucket->uploadFromStream("BigInsertTest", $testStream);
}
public function testGetIdFromStream()
{
$upload = $this->bucket->openUploadStream("test");
$id = $this->bucket->getIdFromStream($upload);
fclose($upload);
$this->assertTrue($id instanceof \MongoDB\BSON\ObjectId);
$download = $this->bucket->openDownloadStream($id);
$id=null;
$id = $this->bucket->getIdFromStream($download);
fclose($download);
$this->assertTrue($id instanceof \MongoDB\BSON\ObjectId);
}
/**
*@dataProvider provideInsertChunks
*/
public function testProvidedMultipleReads($data)
{
$upload = $this->bucket->openUploadStream("test", ["chunkSizeBytes"=>rand(1, 5)]);
fwrite($upload,$data);
$id = $this->bucket->getIdFromStream($upload);
fclose($upload);
$download = $this->bucket->openDownloadStream($id);
$readPos = 0;
while($readPos < strlen($data)){
$numToRead = rand(1, strlen($data) - $readPos);
$expected = substr($data, $readPos, $numToRead);
$actual = fread($download, $numToRead);
$this->assertEquals($expected,$actual);
$readPos+= $numToRead;
}
$actual = fread($download, 5);
$expected = "";
$this->assertEquals($expected,$actual);
fclose($download);
}
private function generateStream($input)
{
$stream = fopen('php://temp', 'w+');
......
......@@ -37,4 +37,26 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase
return;
}
}
public function provideInsertChunks()
{
$dataVals = [];
$testArgs[][] = "hello world";
$testArgs[][] = "1234567890";
$testArgs[][] = "~!@#$%^&*()_+";
for($j=0; $j<30; $j++){
$randomTest = "";
for($i=0; $i<100; $i++){
$randomTest .= chr(rand(0, 256));
}
$testArgs[][] = $randomTest;
}
$utf8="";
for($i=0; $i<256; $i++){
$utf8 .= chr($i);
}
$testArgs[][]=$utf8;
return $testArgs;
}
}
......@@ -10,35 +10,6 @@ use MongoDB\GridFS;
class GridFsStreamTest extends FunctionalTestCase
{
/* public function testConstructorOptionTypeChecks(array $options)
{
new \MongoDB\GridFS\Bucket($this->manager, $this->getDatabaseName(), $options);
}
public function provideInvalidConstructorOptions()
{
$options = [];
$invalidBucketNames = [123, 3.14, true, [], new \stdClass];
$invalidChunkSizes = ['foo', 3.14, true, [], new \stdClass];
foreach ($this->getInvalidReadPreferenceValues() as $value) {
$options[][] = ['readPreference' => $value];
}
foreach ($this->getInvalidWriteConcernValues() as $value) {
$options[][] = ['writeConcern' => $value];
}
foreach ($invalidBucketNames as $value) {
$options[][] = ['bucketName' => $value];
}
foreach ($invalidChunkSizes as $value) {
$options[][] = ['chunkSizeBytes' => $value];
}
return $options;
}
*/
public function testBasic()
{
$upload = new \MongoDB\GridFS\GridFsUpload($this->collectionsWrapper, "test");
......@@ -177,31 +148,122 @@ class GridFsStreamTest extends FunctionalTestCase
$this->assertEquals($data, stream_get_contents($stream));
}
public function provideInsertChunks()
public function testMultiChunkFile()
{
$toUpload="";
for($i=0; $i<255*1024+1000; $i++){
$toUpload .= "a";
}
$upload = new \MongoDB\GridFS\GridFsUpload($this->collectionsWrapper, "test");
$upload->insertChunks($toUpload);
$upload->close();
$this->assertEquals(1, $this->collectionsWrapper->getFilesCollection()->count());
$this->assertEquals(2, $this->collectionsWrapper->getChunksCollection()->count());
$download = $this->bucket->openDownloadStream($upload->getId());
$this->assertEquals($toUpload, stream_get_contents($download));
}
/**
*@dataProvider provideInsertChunks
*/
public function testSmallChunks($data)
{
$options = ["chunkSizeBytes"=>1];
$upload = new \MongoDB\GridFS\GridFsUpload($this->collectionsWrapper, "test", $options);
$upload->insertChunks($data);
$upload->close();
$this->assertEquals(strlen($data), $this->collectionsWrapper->getChunksCollection()->count());
$this->assertEquals(1, $this->collectionsWrapper->getFilesCollection()->count());
$stream = $this->bucket->openDownloadStream($upload->getId());
$this->assertEquals($data, stream_get_contents($stream));
}
public function testMultipleReads()
{
$upload = new \MongoDB\GridFS\GridFsUpload($this->collectionsWrapper, "test", ["chunkSizeBytes"=>3]);
$upload->insertChunks("hello world");
$upload->close();
$file = $this->collectionsWrapper->getFilesCollection()->findOne(["_id"=>$upload->getId()]);
$download = new \MongoDB\GridFS\GridFsDownload($this->collectionsWrapper, $file);
$this->assertEquals("he", $download->downloadNumBytes(2));
$this->assertEquals("ll", $download->downloadNumBytes(2));
$this->assertEquals("o ", $download->downloadNumBytes(2));
$this->assertEquals("wo", $download->downloadNumBytes(2));
$this->assertEquals("rl", $download->downloadNumBytes(2));
$this->assertEquals("d", $download->downloadNumBytes(2));
$this->assertEquals("", $download->downloadNumBytes(2));
$this->assertEquals("", $download->downloadNumBytes(2));
$download->close();
}
/**
*@dataProvider provideInsertChunks
*/
public function testProvidedMultipleReads($data)
{
$upload = new \MongoDB\GridFS\GridFsUpload($this->collectionsWrapper, "test", ["chunkSizeBytes"=>rand(1, 5)]);
$upload->insertChunks($data);
$upload->close();
$file = $this->collectionsWrapper->getFilesCollection()->findOne(["_id"=>$upload->getId()]);
$download = new \MongoDB\GridFS\GridFsDownload($this->collectionsWrapper, $file);
$readPos = 0;
while($readPos < strlen($data)){
$numToRead = rand(1, strlen($data) - $readPos);
$expected = substr($data, $readPos, $numToRead);
$actual = $download->downloadNumBytes($numToRead);
$this->assertEquals($expected,$actual);
$readPos+= $numToRead;
}
$actual = $download->downloadNumBytes(5);
$expected = "";
$this->assertEquals($expected,$actual);
$download->close();
}
/**
* @expectedException \MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidUploadConstructorOptions
*/
public function testUploadConstructorOptionTypeChecks(array $options)
{
$dataVals = [];
$testArgs[][] = "hello world";
$testArgs[][] = "1234567890";
$testArgs[][] = "~!@#$%^&*()_+";
for($j=0; $j<10; $j++){
$randomTest = "";
for($i=0; $i<100; $i++){
$randomTest .= chr(rand(0, 256));
new \MongoDB\GridFS\GridFsUpload($this->collectionsWrapper,"test", $options);
}
$testArgs[][] = $randomTest;
public function provideInvalidUploadConstructorOptions()
{
$options = [];
$invalidContentType = [123, 3.14, true, [], new \stdClass];
$invalidAliases = ['foo', 3.14, true, [12, 34], new \stdClass];
$invalidMetadata = ['foo', 3.14, true];
foreach ($invalidContentType as $value) {
$options[][] = ['contentType' => $value];
}
foreach ($invalidAliases as $value) {
$options[][] = ['aliases' => $value];
}
$utf8="";
for($i=0; $i<256; $i++){
$utf8 .= chr($i);
foreach ($invalidMetadata as $value) {
$options[][] = ['metadata' => $value];
}
$testArgs[][]=$utf8;
return $testArgs;
return $options;
}
private function generateStream($input)
/**
* @expectedException \MongoDB\Exception\InvalidArgumentTypeException
* @dataProvider provideInvalidDownloadConstructorFile
*/
public function testDownloadConstructorFileCheck($file)
{
$stream = fopen('php://temp', 'w+');
fwrite($stream, $input);
rewind($stream);
return $stream;
$download = new \MongoDB\GridFS\GridFsDownload($this->collectionsWrapper, $file);
}
public function provideInvalidDownloadConstructorFile()
{
$files = [];
$invalidFiles = [123, 3.14, true, []];
foreach ($invalidFiles as $value) {
$files[][] = $value;
}
return $files;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment