Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongo-php-library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sinan
mongo-php-library
Commits
cd9394c2
Commit
cd9394c2
authored
Jun 20, 2016
by
Jeremy Mikola
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #192
parents
3dbbd798
a916f8f6
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1202 additions
and
1454 deletions
+1202
-1454
Bucket.php
src/GridFS/Bucket.php
+10
-0
CollectionWrapper.php
src/GridFS/CollectionWrapper.php
+19
-6
ReadableStream.php
src/GridFS/ReadableStream.php
+65
-16
WritableStream.php
src/GridFS/WritableStream.php
+27
-15
functions.php
src/functions.php
+2
-1
BucketFunctionalTest.php
tests/GridFS/BucketFunctionalTest.php
+395
-216
FunctionalTestCase.php
tests/GridFS/FunctionalTestCase.php
+33
-35
GridFSStreamTest.php
tests/GridFS/GridFSStreamTest.php
+0
-251
ReadableStreamFunctionalTest.php
tests/GridFS/ReadableStreamFunctionalTest.php
+180
-0
SpecFunctionalTest.php
tests/GridFS/SpecFunctionalTest.php
+362
-0
README.rst
tests/GridFS/Specification/tests/README.rst
+0
-83
delete.yml
tests/GridFS/Specification/tests/delete.yml
+0
-127
download.yml
tests/GridFS/Specification/tests/download.yml
+0
-173
download_by_name.yml
tests/GridFS/Specification/tests/download_by_name.yml
+0
-113
upload.yml
tests/GridFS/Specification/tests/upload.yml
+0
-158
SpecificationTests.php
tests/GridFS/SpecificationTests.php
+0
-247
WritableStreamFunctionalTest.php
tests/GridFS/WritableStreamFunctionalTest.php
+100
-0
delete.json
tests/GridFS/spec-tests/delete.json
+0
-0
download.json
tests/GridFS/spec-tests/download.json
+0
-0
download_by_name.json
tests/GridFS/spec-tests/download_by_name.json
+0
-0
upload.json
tests/GridFS/spec-tests/upload.json
+0
-0
CreateIndexesFunctionalTest.php
tests/Operation/CreateIndexesFunctionalTest.php
+2
-1
DropCollectionFunctionalTest.php
tests/Operation/DropCollectionFunctionalTest.php
+7
-12
No files found.
src/GridFS/Bucket.php
View file @
cd9394c2
...
@@ -265,9 +265,14 @@ class Bucket
...
@@ -265,9 +265,14 @@ class Bucket
*
*
* Supported options:
* Supported options:
*
*
* * _id (mixed): File document identifier. Defaults to a new ObjectId.
*
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* bucket's chunk size.
* bucket's chunk size.
*
*
* * metadata (document): User data for the "metadata" field of the files
* collection document.
*
* @param string $filename Filename
* @param string $filename Filename
* @param array $options Upload options
* @param array $options Upload options
* @return resource
* @return resource
...
@@ -322,9 +327,14 @@ class Bucket
...
@@ -322,9 +327,14 @@ class Bucket
*
*
* Supported options:
* Supported options:
*
*
* * _id (mixed): File document identifier. Defaults to a new ObjectId.
*
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
* bucket's chunk size.
* bucket's chunk size.
*
*
* * metadata (document): User data for the "metadata" field of the files
* collection document.
*
* @param string $filename Filename
* @param string $filename Filename
* @param resource $source Readable stream
* @param resource $source Readable stream
* @param array $options Stream options
* @param array $options Stream options
...
...
src/GridFS/CollectionWrapper.php
View file @
cd9394c2
...
@@ -17,7 +17,9 @@ use stdClass;
...
@@ -17,7 +17,9 @@ use stdClass;
*/
*/
class
CollectionWrapper
class
CollectionWrapper
{
{
private
$bucketName
;
private
$chunksCollection
;
private
$chunksCollection
;
private
$databaseName
;
private
$checkedIndexes
=
false
;
private
$checkedIndexes
=
false
;
private
$filesCollection
;
private
$filesCollection
;
...
@@ -33,6 +35,9 @@ class CollectionWrapper
...
@@ -33,6 +35,9 @@ class CollectionWrapper
*/
*/
public
function
__construct
(
Manager
$manager
,
$databaseName
,
$bucketName
,
array
$collectionOptions
=
[])
public
function
__construct
(
Manager
$manager
,
$databaseName
,
$bucketName
,
array
$collectionOptions
=
[])
{
{
$this
->
databaseName
=
(
string
)
$databaseName
;
$this
->
bucketName
=
(
string
)
$bucketName
;
$this
->
filesCollection
=
new
Collection
(
$manager
,
$databaseName
,
sprintf
(
'%s.files'
,
$bucketName
),
$collectionOptions
);
$this
->
filesCollection
=
new
Collection
(
$manager
,
$databaseName
,
sprintf
(
'%s.files'
,
$bucketName
),
$collectionOptions
);
$this
->
chunksCollection
=
new
Collection
(
$manager
,
$databaseName
,
sprintf
(
'%s.chunks'
,
$bucketName
),
$collectionOptions
);
$this
->
chunksCollection
=
new
Collection
(
$manager
,
$databaseName
,
sprintf
(
'%s.chunks'
,
$bucketName
),
$collectionOptions
);
}
}
...
@@ -135,10 +140,14 @@ class CollectionWrapper
...
@@ -135,10 +140,14 @@ class CollectionWrapper
return
$this
->
filesCollection
->
find
(
$filter
,
$options
);
return
$this
->
filesCollection
->
find
(
$filter
,
$options
);
}
}
// TODO: Remove this
/**
public
function
getChunksCollection
()
* Return the bucket name.
*
* @return string
*/
public
function
getBucketName
()
{
{
return
$this
->
chunksCollection
;
return
$this
->
bucketName
;
}
}
/**
/**
...
@@ -160,10 +169,14 @@ class CollectionWrapper
...
@@ -160,10 +169,14 @@ class CollectionWrapper
return
new
IteratorIterator
(
$cursor
);
return
new
IteratorIterator
(
$cursor
);
}
}
// TODO: Remove this
/**
public
function
getFilesCollection
()
* Return the database name.
*
* @return string
*/
public
function
getDatabaseName
()
{
{
return
$this
->
filesCollection
;
return
$this
->
databaseName
;
}
}
/**
/**
...
...
src/GridFS/ReadableStream.php
View file @
cd9394c2
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
namespace
MongoDB\GridFS
;
namespace
MongoDB\GridFS
;
use
MongoDB\
Driver\Exception\
Exception
;
use
MongoDB\
Exception\InvalidArgument
Exception
;
use
MongoDB\GridFS\Exception\CorruptFileException
;
use
MongoDB\GridFS\Exception\CorruptFileException
;
use
stdClass
;
use
stdClass
;
...
@@ -17,11 +17,14 @@ class ReadableStream
...
@@ -17,11 +17,14 @@ class ReadableStream
private
$bufferEmpty
;
private
$bufferEmpty
;
private
$bufferFresh
;
private
$bufferFresh
;
private
$bytesSeen
=
0
;
private
$bytesSeen
=
0
;
private
$chunkSize
;
private
$chunkOffset
=
0
;
private
$chunkOffset
=
0
;
private
$chunksIterator
;
private
$chunksIterator
;
private
$
file
;
private
$
collectionWrapper
;
private
$firstCheck
=
true
;
private
$firstCheck
=
true
;
private
$id
;
private
$iteratorEmpty
=
false
;
private
$iteratorEmpty
=
false
;
private
$length
;
private
$numChunks
;
private
$numChunks
;
/**
/**
...
@@ -33,13 +36,45 @@ class ReadableStream
...
@@ -33,13 +36,45 @@ class ReadableStream
*/
*/
public
function
__construct
(
CollectionWrapper
$collectionWrapper
,
stdClass
$file
)
public
function
__construct
(
CollectionWrapper
$collectionWrapper
,
stdClass
$file
)
{
{
$this
->
file
=
$file
;
if
(
!
isset
(
$file
->
chunkSize
)
||
!
is_integer
(
$file
->
chunkSize
)
||
$file
->
chunkSize
<
1
)
{
throw
new
CorruptFileException
(
'file.chunkSize is not an integer >= 1'
);
}
if
(
!
isset
(
$file
->
length
)
||
!
is_integer
(
$file
->
length
)
||
$file
->
length
<
0
)
{
throw
new
CorruptFileException
(
'file.length is not an integer > 0'
);
}
$this
->
chunksIterator
=
$collectionWrapper
->
getChunksIteratorByFilesId
(
$this
->
file
->
_id
);
if
(
!
isset
(
$file
->
_id
)
&&
!
array_key_exists
(
'_id'
,
(
array
)
$file
))
{
$this
->
numChunks
=
(
$file
->
length
>=
0
)
?
ceil
(
$file
->
length
/
$file
->
chunkSize
)
:
0
;
throw
new
CorruptFileException
(
'file._id does not exist'
);
}
$this
->
id
=
$file
->
_id
;
$this
->
chunkSize
=
$file
->
chunkSize
;
$this
->
length
=
$file
->
length
;
$this
->
chunksIterator
=
$collectionWrapper
->
getChunksIteratorByFilesId
(
$this
->
id
);
$this
->
collectionWrapper
=
$collectionWrapper
;
$this
->
numChunks
=
ceil
(
$this
->
length
/
$this
->
chunkSize
);
$this
->
initEmptyBuffer
();
$this
->
initEmptyBuffer
();
}
}
/**
* Return internal properties for debugging purposes.
*
* @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
* @return array
*/
public
function
__debugInfo
()
{
return
[
'bucketName'
=>
$this
->
collectionWrapper
->
getBucketName
(),
'databaseName'
=>
$this
->
collectionWrapper
->
getDatabaseName
(),
'id'
=>
$this
->
id
,
'chunkSize'
=>
$this
->
chunkSize
,
'length'
=>
$this
->
length
,
];
}
public
function
close
()
public
function
close
()
{
{
fclose
(
$this
->
buffer
);
fclose
(
$this
->
buffer
);
...
@@ -52,10 +87,19 @@ class ReadableStream
...
@@ -52,10 +87,19 @@ class ReadableStream
* if data is not available to be read.
* if data is not available to be read.
*
*
* @param integer $numBytes Number of bytes to read
* @param integer $numBytes Number of bytes to read
* @return string
* @return string
* @throws InvalidArgumentException if $numBytes is negative
*/
*/
public
function
downloadNumBytes
(
$numBytes
)
public
function
downloadNumBytes
(
$numBytes
)
{
{
if
(
$numBytes
<
0
)
{
throw
new
InvalidArgumentException
(
sprintf
(
'$numBytes must be >= zero; given: %d'
,
$numBytes
));
}
if
(
$numBytes
==
0
)
{
return
''
;
}
if
(
$this
->
bufferFresh
)
{
if
(
$this
->
bufferFresh
)
{
rewind
(
$this
->
buffer
);
rewind
(
$this
->
buffer
);
$this
->
bufferFresh
=
false
;
$this
->
bufferFresh
=
false
;
...
@@ -77,7 +121,7 @@ class ReadableStream
...
@@ -77,7 +121,7 @@ class ReadableStream
$output
.=
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
0
,
$bytesLeft
);
$output
.=
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
0
,
$bytesLeft
);
}
}
if
(
!
$this
->
iteratorEmpty
&&
$this
->
file
->
length
>
0
&&
$bytesLeft
<
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
()))
{
if
(
!
$this
->
iteratorEmpty
&&
$this
->
length
>
0
&&
$bytesLeft
<
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
()))
{
fwrite
(
$this
->
buffer
,
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
$bytesLeft
));
fwrite
(
$this
->
buffer
,
substr
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
(),
$bytesLeft
));
$this
->
bufferEmpty
=
false
;
$this
->
bufferEmpty
=
false
;
}
}
...
@@ -103,19 +147,24 @@ class ReadableStream
...
@@ -103,19 +147,24 @@ class ReadableStream
}
}
}
}
public
function
getFile
()
/**
{
* Return the stream's ID (i.e. file document identifier).
return
$this
->
file
;
*
}
* @return integer
*/
public
function
getId
()
public
function
getId
()
{
{
return
$this
->
file
->
_
id
;
return
$this
->
id
;
}
}
/**
* Return the stream's size in bytes.
*
* @return integer
*/
public
function
getSize
()
public
function
getSize
()
{
{
return
$this
->
file
->
length
;
return
$this
->
length
;
}
}
public
function
isEOF
()
public
function
isEOF
()
...
@@ -149,8 +198,8 @@ class ReadableStream
...
@@ -149,8 +198,8 @@ class ReadableStream
$actualChunkSize
=
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
());
$actualChunkSize
=
strlen
(
$this
->
chunksIterator
->
current
()
->
data
->
getData
());
$expectedChunkSize
=
(
$this
->
chunkOffset
==
$this
->
numChunks
-
1
)
$expectedChunkSize
=
(
$this
->
chunkOffset
==
$this
->
numChunks
-
1
)
?
(
$this
->
file
->
length
-
$this
->
bytesSeen
)
?
(
$this
->
length
-
$this
->
bytesSeen
)
:
$this
->
file
->
chunkSize
;
:
$this
->
chunkSize
;
if
(
$actualChunkSize
!=
$expectedChunkSize
)
{
if
(
$actualChunkSize
!=
$expectedChunkSize
)
{
throw
CorruptFileException
::
unexpectedSize
(
$actualChunkSize
,
$expectedChunkSize
);
throw
CorruptFileException
::
unexpectedSize
(
$actualChunkSize
,
$expectedChunkSize
);
...
...
src/GridFS/WritableStream.php
View file @
cd9394c2
...
@@ -89,6 +89,21 @@ class WritableStream
...
@@ -89,6 +89,21 @@ class WritableStream
]
+
array_intersect_key
(
$options
,
[
'aliases'
=>
1
,
'contentType'
=>
1
,
'metadata'
=>
1
]);
]
+
array_intersect_key
(
$options
,
[
'aliases'
=>
1
,
'contentType'
=>
1
,
'metadata'
=>
1
]);
}
}
/**
* Return internal properties for debugging purposes.
*
* @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
* @return array
*/
public
function
__debugInfo
()
{
return
[
'bucketName'
=>
$this
->
collectionWrapper
->
getBucketName
(),
'databaseName'
=>
$this
->
collectionWrapper
->
getDatabaseName
(),
'file'
=>
$this
->
file
,
];
}
/**
/**
* Closes an active stream and flushes all buffered data to GridFS.
* Closes an active stream and flushes all buffered data to GridFS.
*/
*/
...
@@ -111,26 +126,23 @@ class WritableStream
...
@@ -111,26 +126,23 @@ class WritableStream
$this
->
isClosed
=
true
;
$this
->
isClosed
=
true
;
}
}
public
function
getChunkSize
()
/**
{
* Return the stream's ID (i.e. file document identifier).
return
$this
->
chunkSize
;
*
}
* @return integer
*/
public
function
getFile
()
{
return
$this
->
file
;
}
public
function
getId
()
public
function
getId
()
{
{
return
$this
->
file
[
'_id'
];
return
$this
->
file
[
'_id'
];
}
}
public
function
getLength
()
/**
{
* Return the stream's size in bytes.
return
$this
->
length
;
*
}
* Note: this value will increase as more data is written to the stream.
*
* @return integer
*/
public
function
getSize
()
public
function
getSize
()
{
{
return
$this
->
length
;
return
$this
->
length
;
...
...
src/functions.php
View file @
cd9394c2
...
@@ -77,9 +77,10 @@ function is_first_key_operator($document)
...
@@ -77,9 +77,10 @@ function is_first_key_operator($document)
throw
InvalidArgumentException
::
invalidType
(
'$document'
,
$document
,
'array or object'
);
throw
InvalidArgumentException
::
invalidType
(
'$document'
,
$document
,
'array or object'
);
}
}
reset
(
$document
);
$firstKey
=
(
string
)
key
(
$document
);
$firstKey
=
(
string
)
key
(
$document
);
return
(
isset
(
$firstKey
[
0
])
&&
$firstKey
[
0
]
==
'$'
);
return
(
isset
(
$firstKey
[
0
])
&&
$firstKey
[
0
]
==
=
'$'
);
}
}
/**
/**
...
...
tests/GridFS/BucketFunctionalTest.php
View file @
cd9394c2
...
@@ -2,9 +2,14 @@
...
@@ -2,9 +2,14 @@
namespace
MongoDB\Tests\GridFS
;
namespace
MongoDB\Tests\GridFS
;
use
MongoDB\BSON\Binary
;
use
MongoDB\Driver\ReadPreference
;
use
MongoDB\Driver\ReadPreference
;
use
MongoDB\Driver\WriteConcern
;
use
MongoDB\Driver\WriteConcern
;
use
MongoDB\GridFS\Bucket
;
use
MongoDB\GridFS\Bucket
;
use
MongoDB\GridFS\Exception\FileNotFoundException
;
use
MongoDB\Model\IndexInfo
;
use
MongoDB\Operation\ListCollections
;
use
MongoDB\Operation\ListIndexes
;
/**
/**
* Functional tests for the Bucket class.
* Functional tests for the Bucket class.
...
@@ -53,271 +58,445 @@ class BucketFunctionalTest extends FunctionalTestCase
...
@@ -53,271 +58,445 @@ class BucketFunctionalTest extends FunctionalTestCase
return
$options
;
return
$options
;
}
}
/**
* @dataProvider provideInputDataAndExpectedChunks
*/
public
function
testDelete
(
$input
,
$expectedChunks
)
{
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
$input
));
$this
->
assertCollectionCount
(
$this
->
filesCollection
,
1
);
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
$expectedChunks
);
$this
->
bucket
->
delete
(
$id
);
$this
->
assertCollectionCount
(
$this
->
filesCollection
,
0
);
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
0
);
}
public
function
provideInputDataAndExpectedChunks
()
{
return
[
[
''
,
0
],
[
'foobar'
,
1
],
[
str_repeat
(
'a'
,
261120
),
1
],
[
str_repeat
(
'a'
,
261121
),
2
],
[
str_repeat
(
'a'
,
522240
),
2
],
[
str_repeat
(
'a'
,
522241
),
3
],
[
str_repeat
(
'foobar'
,
43520
),
1
],
[
str_repeat
(
'foobar'
,
43521
),
2
],
[
str_repeat
(
'foobar'
,
87040
),
2
],
[
str_repeat
(
'foobar'
,
87041
),
3
],
];
}
/**
* @expectedException MongoDB\GridFS\Exception\FileNotFoundException
*/
public
function
testDeleteShouldRequireFileToExist
()
{
$this
->
bucket
->
delete
(
'nonexistent-id'
);
}
/**
* @dataProvider provideInputDataAndExpectedChunks
*/
public
function
testDeleteStillRemovesChunksIfFileDoesNotExist
(
$input
,
$expectedChunks
)
{
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
$input
));
$this
->
assertCollectionCount
(
$this
->
filesCollection
,
1
);
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
$expectedChunks
);
$this
->
filesCollection
->
deleteOne
([
'_id'
=>
$id
]);
try
{
$this
->
bucket
->
delete
(
$id
);
$this
->
fail
(
'FileNotFoundException was not thrown'
);
}
catch
(
FileNotFoundException
$e
)
{}
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
0
);
}
/**
* @expectedException MongoDB\GridFS\Exception\CorruptFileException
*/
public
function
testDownloadingFileWithMissingChunk
()
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"filename"
,
$this
->
createStream
(
"foobar"
));
$this
->
chunksCollection
->
deleteOne
([
'files_id'
=>
$id
,
'n'
=>
0
]);
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
));
}
/**
* @expectedException MongoDB\GridFS\Exception\CorruptFileException
*/
public
function
testDownloadingFileWithUnexpectedChunkIndex
()
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"filename"
,
$this
->
createStream
(
"foobar"
));
$this
->
chunksCollection
->
updateOne
(
[
'files_id'
=>
$id
,
'n'
=>
0
],
[
'$set'
=>
[
'n'
=>
1
]]
);
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
));
}
/**
* @expectedException MongoDB\GridFS\Exception\CorruptFileException
*/
public
function
testDownloadingFileWithUnexpectedChunkSize
()
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"filename"
,
$this
->
createStream
(
"foobar"
));
$this
->
chunksCollection
->
updateOne
(
[
'files_id'
=>
$id
,
'n'
=>
0
],
[
'$set'
=>
[
'data'
=>
new
Binary
(
'fooba'
,
Binary
::
TYPE_GENERIC
)]]
);
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
));
}
/**
* @dataProvider provideInputDataAndExpectedChunks
*/
public
function
testDownloadToStream
(
$input
)
{
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
$input
));
$destination
=
$this
->
createStream
();
$this
->
bucket
->
downloadToStream
(
$id
,
$destination
);
$this
->
assertStreamContents
(
$input
,
$destination
);
}
/**
* @expectedException MongoDB\GridFS\Exception\FileNotFoundException
*/
public
function
testDownloadToStreamShouldRequireFileToExist
()
{
$this
->
bucket
->
downloadToStream
(
'nonexistent-id'
,
$this
->
createStream
());
}
public
function
testDrop
()
{
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'foobar'
));
$this
->
assertCollectionCount
(
$this
->
filesCollection
,
1
);
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
1
);
$this
->
bucket
->
drop
();
$this
->
assertCollectionDoesNotExist
(
$this
->
filesCollection
->
getCollectionName
());
$this
->
assertCollectionDoesNotExist
(
$this
->
chunksCollection
->
getCollectionName
());
}
public
function
testFind
()
{
$this
->
bucket
->
uploadFromStream
(
'a'
,
$this
->
createStream
(
'foo'
));
$this
->
bucket
->
uploadFromStream
(
'b'
,
$this
->
createStream
(
'foobar'
));
$this
->
bucket
->
uploadFromStream
(
'c'
,
$this
->
createStream
(
'foobarbaz'
));
$cursor
=
$this
->
bucket
->
find
(
[
'length'
=>
[
'$lte'
=>
6
]],
[
'projection'
=>
[
'filename'
=>
1
,
'length'
=>
1
,
'_id'
=>
0
,
],
'sort'
=>
[
'length'
=>
-
1
],
]
);
$expected
=
[
[
'filename'
=>
'b'
,
'length'
=>
6
],
[
'filename'
=>
'a'
,
'length'
=>
3
],
];
$this
->
assertSameDocuments
(
$expected
,
$cursor
);
}
public
function
testGetDatabaseName
()
public
function
testGetDatabaseName
()
{
{
$this
->
assertEquals
(
$this
->
getDatabaseName
(),
$this
->
bucket
->
getDatabaseName
());
$this
->
assertEquals
(
$this
->
getDatabaseName
(),
$this
->
bucket
->
getDatabaseName
());
}
}
public
function
test
BasicOperations
()
public
function
test
GetIdFromStream
()
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
"hello world"
));
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'foobar'
));
$contents
=
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
));
$stream
=
$this
->
bucket
->
openDownloadStream
(
$id
);
$this
->
assertEquals
(
"hello world"
,
$contents
);
$this
->
assertEquals
(
1
,
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
1
,
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
()
->
count
());
$this
->
bucket
->
delete
(
$id
);
$this
->
assertEquals
(
$id
,
$this
->
bucket
->
getIdFromStream
(
$stream
));
$error
=
null
;
try
{
$this
->
bucket
->
openDownloadStream
(
$id
);
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$error
=
$e
;
}
$fileNotFound
=
'\MongoDB\GridFS\Exception\FileNotFoundException'
;
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
$this
->
assertEquals
(
0
,
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
0
,
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
()
->
count
());
}
}
public
function
testMultiChunkDelete
()
/**
* @dataProvider provideInputDataAndExpectedChunks
*/
public
function
testOpenDownloadStream
(
$input
)
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
"hello"
),
[
'chunkSizeBytes'
=>
1
]);
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
$input
));
$this
->
assertEquals
(
1
,
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
5
,
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
()
->
count
());
$this
->
assertStreamContents
(
$input
,
$this
->
bucket
->
openDownloadStream
(
$id
));
$this
->
bucket
->
delete
(
$id
);
$this
->
assertEquals
(
0
,
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
0
,
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
()
->
count
());
}
}
public
function
testEmptyFile
()
/**
* @dataProvider provideInputDataAndExpectedChunks
*/
public
function
testOpenDownloadStreamAndMultipleReadOperations
(
$input
)
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
""
));
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
$input
));
$contents
=
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
));
$stream
=
$this
->
bucket
->
openDownloadStream
(
$id
);
$this
->
assertEquals
(
""
,
$contents
);
$buffer
=
''
;
$this
->
assertEquals
(
1
,
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
0
,
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
()
->
count
());
$raw
=
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
findOne
();
while
(
strlen
(
$buffer
)
<
strlen
(
$input
))
{
$this
->
assertEquals
(
0
,
$raw
->
length
);
$expectedReadLength
=
min
(
4096
,
strlen
(
$input
)
-
strlen
(
$buffer
));
$this
->
assertEquals
(
$id
,
$raw
->
_id
);
$buffer
.=
$read
=
fread
(
$stream
,
4096
);
$this
->
assertTrue
(
$raw
->
uploadDate
instanceof
\MongoDB\BSON\UTCDateTime
);
$this
->
assertEquals
(
255
*
1024
,
$raw
->
chunkSize
);
$this
->
assertInternalType
(
'string'
,
$read
);
$this
->
assertTrue
(
is_string
(
$raw
->
md5
));
$this
->
assertEquals
(
$expectedReadLength
,
strlen
(
$read
));
}
$this
->
assertTrue
(
fclose
(
$stream
));
$this
->
assertEquals
(
$input
,
$buffer
);
}
}
public
function
testCorruptChunk
()
/**
* @expectedException MongoDB\GridFS\Exception\FileNotFoundException
*/
public
function
testOpenDownloadStreamShouldRequireFileToExist
()
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
"foobar"
));
$this
->
bucket
->
openDownloadStream
(
'nonexistent-id'
);
}
$this
->
collectionWrapper
->
getChunksCollection
()
->
updateOne
([
'files_id'
=>
$id
],
/**
[
'$set'
=>
[
'data'
=>
new
\MongoDB\BSON\Binary
(
'foo'
,
\MongoDB\BSON\Binary
::
TYPE_GENERIC
)]]);
* @expectedException MongoDB\GridFS\Exception\FileNotFoundException
$error
=
null
;
*/
try
{
public
function
testOpenDownloadStreamByNameShouldRequireFilenameToExist
()
$download
=
$this
->
bucket
->
openDownloadStream
(
$id
);
{
stream_get_contents
(
$download
);
$this
->
bucket
->
openDownloadStream
(
'nonexistent-filename'
);
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$error
=
$e
;
}
$corruptFileError
=
'\MongoDB\GridFS\Exception\CorruptFileException'
;
$this
->
assertTrue
(
$error
instanceof
$corruptFileError
);
}
}
public
function
testErrorsOnMissingChunk
()
public
function
testOpenDownloadStreamByName
()
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
"hello world,abcdefghijklmnopqrstuv123456789"
),
[
"chunkSizeBytes"
=>
1
]);
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'foo'
));
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'bar'
));
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'baz'
));
$this
->
collectionWrapper
->
getChunksCollection
()
->
deleteOne
([
'files_id'
=>
$id
,
'n'
=>
7
]);
$this
->
assertStreamContents
(
'baz'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
));
$error
=
null
;
$this
->
assertStreamContents
(
'foo'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
,
[
'revision'
=>
-
3
]));
try
{
$this
->
assertStreamContents
(
'bar'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
,
[
'revision'
=>
-
2
]));
$download
=
$this
->
bucket
->
openDownloadStream
(
$id
);
$this
->
assertStreamContents
(
'baz'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
,
[
'revision'
=>
-
1
]));
stream_get_contents
(
$download
);
$this
->
assertStreamContents
(
'foo'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
,
[
'revision'
=>
0
]));
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$this
->
assertStreamContents
(
'bar'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
,
[
'revision'
=>
1
]));
$error
=
$e
;
$this
->
assertStreamContents
(
'baz'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
,
[
'revision'
=>
2
]));
}
$corruptFileError
=
'\MongoDB\GridFS\Exception\CorruptFileException'
;
$this
->
assertTrue
(
$error
instanceof
$corruptFileError
);
}
}
public
function
testUploadEnsureIndexes
()
/**
* @expectedException MongoDB\GridFS\Exception\FileNotFoundException
* @dataProvider provideNonexistentFilenameAndRevision
*/
public
function
testOpenDownloadStreamByNameShouldRequireFilenameAndRevisionToExist
(
$filename
,
$revision
)
{
{
$chunks
=
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
();
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'foo'
));
$files
=
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
();
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'bar'
));
$this
->
bucket
->
uploadFromStream
(
"filename"
,
$this
->
generateStream
(
"junk"
));
$chunksIndexed
=
false
;
$this
->
bucket
->
openDownloadStream
(
$filename
,
[
'revision'
=>
$revision
]);
foreach
(
$chunks
->
listIndexes
()
as
$index
)
{
}
$chunksIndexed
=
$chunksIndexed
||
(
$index
->
isUnique
()
&&
$index
->
getKey
()
===
[
'files_id'
=>
1
,
'n'
=>
1
]);
}
$this
->
assertTrue
(
$chunksIndexed
);
$filesIndexed
=
false
;
public
function
provideNonexistentFilenameAndRevision
()
foreach
(
$files
->
listIndexes
()
as
$index
)
{
{
$filesIndexed
=
$filesIndexed
||
(
$index
->
getKey
()
===
[
'filename'
=>
1
,
'uploadDate'
=>
1
]);
return
[
}
[
'filename'
,
2
],
$this
->
assertTrue
(
$filesIndexed
);
[
'filename'
,
-
3
],
}
[
'nonexistent-filename'
,
0
],
public
function
testGetLastVersion
()
[
'nonexistent-filename'
,
-
1
],
{
];
$idOne
=
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"foo"
));
$streamTwo
=
$this
->
bucket
->
openUploadStream
(
"test"
);
fwrite
(
$streamTwo
,
"bar"
);
//echo "Calling FSTAT\n";
//$stat = fstat($streamTwo);
$idTwo
=
$this
->
bucket
->
getIdFromStream
(
$streamTwo
);
//var_dump
//var_dump($idTwo);
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
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
)));
$this
->
bucket
->
delete
(
$idOne
);
$error
=
null
;
try
{
$this
->
bucket
->
openDownloadStreamByName
(
"test"
);
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$error
=
$e
;
}
$fileNotFound
=
'\MongoDB\GridFS\Exception\FileNotFoundException'
;
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
}
}
public
function
testGetVersion
()
public
function
testOpenUploadStream
()
{
{
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"foo"
));
$stream
=
$this
->
bucket
->
openUploadStream
(
'filename'
);
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"bar"
));
$this
->
bucket
->
uploadFromStream
(
"test"
,
$this
->
generateStream
(
"baz"
));
$this
->
assertEquals
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
0
])));
fwrite
(
$stream
,
'foobar'
);
$this
->
assertEquals
(
"bar"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
1
])));
fclose
(
$stream
);
$this
->
assertEquals
(
"baz"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
2
])));
$this
->
assertEquals
(
"baz"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
1
])));
$this
->
assertStreamContents
(
'foobar'
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
));
$this
->
assertEquals
(
"bar"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
2
])));
}
$this
->
assertEquals
(
"foo"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
3
])));
$fileNotFound
=
'\MongoDB\GridFS\Exception\FileNotFoundException'
;
/**
$error
=
null
;
* @dataProvider provideInputDataAndExpectedChunks
try
{
*/
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
3
]);
public
function
testOpenUploadStreamAndMultipleWriteOperations
(
$input
)
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
{
$error
=
$e
;
$stream
=
$this
->
bucket
->
openUploadStream
(
'filename'
);
}
$offset
=
0
;
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
$error
=
null
;
while
(
$offset
<
strlen
(
$input
))
{
try
{
$expectedWriteLength
=
min
(
4096
,
strlen
(
$input
)
-
$offset
);
$this
->
bucket
->
openDownloadStreamByName
(
"test"
,
[
'revision'
=>
-
4
]);
$writeLength
=
fwrite
(
$stream
,
substr
(
$input
,
$offset
,
4096
));
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$offset
+=
$writeLength
;
$error
=
$e
;
}
$this
->
assertEquals
(
$expectedWriteLength
,
$writeLength
);
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
}
public
function
testGridfsFind
()
{
$this
->
bucket
->
uploadFromStream
(
"two"
,
$this
->
generateStream
(
"test2"
));
usleep
(
5000
);
$this
->
bucket
->
uploadFromStream
(
"two"
,
$this
->
generateStream
(
"test2+"
));
usleep
(
5000
);
$this
->
bucket
->
uploadFromStream
(
"one"
,
$this
->
generateStream
(
"test1"
));
usleep
(
5000
);
$this
->
bucket
->
uploadFromStream
(
"two"
,
$this
->
generateStream
(
"test2++"
));
$cursor
=
$this
->
bucket
->
find
([
"filename"
=>
"two"
]);
$count
=
count
(
$cursor
->
toArray
());
$this
->
assertEquals
(
3
,
$count
);
$cursor
=
$this
->
bucket
->
find
([]);
$count
=
count
(
$cursor
->
toArray
());
$this
->
assertEquals
(
4
,
$count
);
$cursor
=
$this
->
bucket
->
find
([],
[
"noCursorTimeout"
=>
false
,
"sort"
=>
[
"uploadDate"
=>
-
1
],
"skip"
=>
1
,
"limit"
=>
2
]);
$outputs
=
[
"test1"
,
"test2+"
];
$i
=
0
;
foreach
(
$cursor
as
$file
){
$contents
=
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$file
->
_id
));
$this
->
assertEquals
(
$outputs
[
$i
],
$contents
);
$i
++
;
}
}
$this
->
assertTrue
(
fclose
(
$stream
));
$this
->
assertStreamContents
(
$input
,
$this
->
bucket
->
openDownloadStreamByName
(
'filename'
));
}
}
public
function
testGridInNonIntChunksize
()
public
function
testRename
()
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"f"
,
$this
->
generateStream
(
"data"
));
$id
=
$this
->
bucket
->
uploadFromStream
(
'a'
,
$this
->
createStream
(
'foo'
));
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
()
->
updateOne
([
"filename"
=>
"f"
],
$this
->
bucket
->
rename
(
$id
,
'b'
);
[
'$set'
=>
[
'chunkSize'
=>
100.00
]]);
$this
->
assertEquals
(
"data"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
)));
$fileDocument
=
$this
->
filesCollection
->
findOne
(
[
'_id'
=>
$id
],
[
'projection'
=>
[
'filename'
=>
1
,
'_id'
=>
0
]]
);
$this
->
assertSameDocument
([
'filename'
=>
'b'
],
$fileDocument
);
$this
->
assertStreamContents
(
'foo'
,
$this
->
bucket
->
openDownloadStreamByName
(
'b'
));
}
}
public
function
testBigInsert
()
public
function
testRenameShouldNotRequireFileToBeModified
()
{
{
for
(
$tmpStream
=
tmpfile
(),
$i
=
0
;
$i
<
20
;
$i
++
)
{
$id
=
$this
->
bucket
->
uploadFromStream
(
'a'
,
$this
->
createStream
(
'foo'
));
fwrite
(
$tmpStream
,
str_repeat
(
'a'
,
1048576
));
$this
->
bucket
->
rename
(
$id
,
'a'
);
}
fseek
(
$tmpStream
,
0
);
$fileDocument
=
$this
->
filesCollection
->
findOne
(
$this
->
bucket
->
uploadFromStream
(
"BigInsertTest"
,
$tmpStream
);
[
'_id'
=>
$id
],
fclose
(
$tmpStream
);
[
'projection'
=>
[
'filename'
=>
1
,
'_id'
=>
0
]]
);
$this
->
assertSameDocument
([
'filename'
=>
'a'
],
$fileDocument
);
$this
->
assertStreamContents
(
'foo'
,
$this
->
bucket
->
openDownloadStreamByName
(
'a'
));
}
}
public
function
testGetIdFromStream
()
/**
* @expectedException MongoDB\GridFS\Exception\FileNotFoundException
*/
public
function
testRenameShouldRequireFileToExist
()
{
{
$upload
=
$this
->
bucket
->
openUploadStream
(
"test"
);
$this
->
bucket
->
rename
(
'nonexistent-id'
,
'b'
);
$id
=
$this
->
bucket
->
getIdFromStream
(
$upload
);
}
fclose
(
$upload
);
$this
->
assertTrue
(
$id
instanceof
\MongoDB\BSON\ObjectId
);
$download
=
$this
->
bucket
->
openDownloadStream
(
$id
);
public
function
testUploadFromStream
()
$id
=
null
;
{
$id
=
$this
->
bucket
->
getIdFromStream
(
$download
);
$options
=
[
fclose
(
$download
);
'_id'
=>
'custom-id'
,
$this
->
assertTrue
(
$id
instanceof
\MongoDB\BSON\ObjectId
);
'chunkSizeBytes'
=>
2
,
'metadata'
=>
[
'foo'
=>
'bar'
],
];
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'foobar'
),
$options
);
$this
->
assertCollectionCount
(
$this
->
filesCollection
,
1
);
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
3
);
$this
->
assertSame
(
'custom-id'
,
$id
);
$fileDocument
=
$this
->
filesCollection
->
findOne
([
'_id'
=>
$id
]);
$this
->
assertSameDocument
([
'foo'
=>
'bar'
],
$fileDocument
[
'metadata'
]);
}
}
public
function
testRename
()
public
function
testUploadingAnEmptyFile
()
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"first_name"
,
$this
->
generateStream
(
"testing"
));
$id
=
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
''
));
$this
->
assertEquals
(
"testing"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$id
)));
$destination
=
$this
->
createStream
();
$this
->
bucket
->
downloadToStream
(
$id
,
$destination
);
$this
->
bucket
->
rename
(
$id
,
"second_name"
);
$this
->
assertStreamContents
(
''
,
$destination
);
$this
->
assertCollectionCount
(
$this
->
filesCollection
,
1
);
$this
->
assertCollectionCount
(
$this
->
chunksCollection
,
0
);
$error
=
null
;
$fileDocument
=
$this
->
filesCollection
->
findOne
(
try
{
[
'_id'
=>
$id
],
$this
->
bucket
->
openDownloadStreamByName
(
"first_name"
);
[
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
'projection'
=>
[
$error
=
$e
;
'length'
=>
1
,
}
'md5'
=>
1
,
$fileNotFound
=
'\MongoDB\GridFS\Exception\FileNotFoundException'
;
'_id'
=>
0
,
$this
->
assertTrue
(
$error
instanceof
$fileNotFound
);
],
]
);
$this
->
assertEquals
(
"testing"
,
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
"second_name"
)));
$expected
=
[
'length'
=>
0
,
'md5'
=>
'd41d8cd98f00b204e9800998ecf8427e'
,
];
$this
->
assertSameDocument
(
$expected
,
$fileDocument
);
}
}
public
function
testDrop
()
public
function
testUploadingFirstFileCreatesIndexes
()
{
{
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
"hello world"
));
$this
->
bucket
->
uploadFromStream
(
'filename'
,
$this
->
createStream
(
'foo'
));
$this
->
bucket
->
drop
();
$id
=
$this
->
bucket
->
uploadFromStream
(
"test_filename"
,
$this
->
generateStream
(
"hello world"
));
$this
->
assertIndexExists
(
$this
->
filesCollection
->
getCollectionName
(),
'filename_1_uploadDate_1'
);
$this
->
assertEquals
(
1
,
$this
->
collectionWrapper
->
getFilesCollection
()
->
count
());
$this
->
assertIndexExists
(
$this
->
chunksCollection
->
getCollectionName
(),
'files_id_1_n_1'
,
function
(
IndexInfo
$info
)
{
$this
->
assertTrue
(
$info
->
isUnique
());
});
}
}
/**
/**
*@dataProvider provideInsertChunks
* Asserts that a collection with the given name does not exist on the
* server.
*
* @param string $collectionName
*/
*/
public
function
testProvidedMultipleReads
(
$data
)
private
function
assertCollectionDoesNotExist
(
$collectionName
)
{
{
$upload
=
$this
->
bucket
->
openUploadStream
(
"test"
,
[
"chunkSizeBytes"
=>
rand
(
1
,
5
)]);
$operation
=
new
ListCollections
(
$this
->
getDatabaseName
());
fwrite
(
$upload
,
$data
);
$collections
=
$operation
->
execute
(
$this
->
getPrimaryServer
());
$id
=
$this
->
bucket
->
getIdFromStream
(
$upload
);
fclose
(
$upload
);
$foundCollection
=
null
;
$download
=
$this
->
bucket
->
openDownloadStream
(
$id
);
$readPos
=
0
;
foreach
(
$collections
as
$collection
)
{
while
(
$readPos
<
strlen
(
$data
)){
if
(
$collection
->
getName
()
===
$collectionName
)
{
$numToRead
=
rand
(
1
,
strlen
(
$data
)
-
$readPos
);
$foundCollection
=
$collection
;
$expected
=
substr
(
$data
,
$readPos
,
$numToRead
);
break
;
$actual
=
fread
(
$download
,
$numToRead
);
}
$this
->
assertEquals
(
$expected
,
$actual
);
$readPos
+=
$numToRead
;
}
}
$actual
=
fread
(
$download
,
5
);
$expected
=
""
;
$this
->
assertNull
(
$foundCollection
,
sprintf
(
'Collection %s exists'
,
$collectionName
));
$this
->
assertEquals
(
$expected
,
$actual
);
fclose
(
$download
);
}
}
private
function
generateStream
(
$input
)
/**
* Asserts that an index with the given name exists for the collection.
*
* An optional $callback may be provided, which should take an IndexInfo
* argument as its first and only parameter. If an IndexInfo matching the
* given name is found, it will be passed to the callback, which may perform
* additional assertions.
*
* @param string $collectionName
* @param string $indexName
* @param callable $callback
*/
private
function
assertIndexExists
(
$collectionName
,
$indexName
,
$callback
=
null
)
{
{
$stream
=
fopen
(
'php://temp'
,
'w+'
);
if
(
$callback
!==
null
&&
!
is_callable
(
$callback
))
{
fwrite
(
$stream
,
$input
);
throw
new
InvalidArgumentException
(
'$callback is not a callable'
);
rewind
(
$stream
);
}
return
$stream
;
$operation
=
new
ListIndexes
(
$this
->
getDatabaseName
(),
$collectionName
);
$indexes
=
$operation
->
execute
(
$this
->
getPrimaryServer
());
$foundIndex
=
null
;
foreach
(
$indexes
as
$index
)
{
if
(
$index
->
getName
()
===
$indexName
)
{
$foundIndex
=
$index
;
break
;
}
}
$this
->
assertNotNull
(
$foundIndex
,
sprintf
(
'Index %s does not exist'
,
$indexName
));
if
(
$callback
!==
null
)
{
call_user_func
(
$callback
,
$foundIndex
);
}
}
}
}
}
tests/GridFS/FunctionalTestCase.php
View file @
cd9394c2
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
namespace
MongoDB\Tests\GridFS
;
namespace
MongoDB\Tests\GridFS
;
use
MongoDB\GridFS
;
use
MongoDB\Collection
;
use
MongoDB\Collection
;
use
MongoDB\GridFS\Bucket
;
use
MongoDB\Tests\FunctionalTestCase
as
BaseFunctionalTestCase
;
use
MongoDB\Tests\FunctionalTestCase
as
BaseFunctionalTestCase
;
/**
/**
...
@@ -12,49 +12,47 @@ use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
...
@@ -12,49 +12,47 @@ use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
abstract
class
FunctionalTestCase
extends
BaseFunctionalTestCase
abstract
class
FunctionalTestCase
extends
BaseFunctionalTestCase
{
{
protected
$bucket
;
protected
$bucket
;
protected
$collectionWrapper
;
protected
$chunksCollection
;
protected
$filesCollection
;
public
function
setUp
()
public
function
setUp
()
{
{
parent
::
setUp
();
parent
::
setUp
();
foreach
([
'fs.files'
,
'fs.chunks'
]
as
$collection
){
$col
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
$collection
);
$this
->
bucket
=
new
Bucket
(
$this
->
manager
,
$this
->
getDatabaseName
()
);
$col
->
drop
();
$this
->
bucket
->
drop
();
}
$this
->
bucket
=
new
\MongoDB\GridFS\Bucket
(
$this
->
manager
,
$this
->
getDatabaseName
()
);
$this
->
chunksCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
'fs.chunks'
);
$this
->
collectionWrapper
=
$this
->
bucket
->
getCollectionWrapper
(
);
$this
->
filesCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
'fs.files'
);
}
}
public
function
tearDown
()
/**
* Asserts that a variable is a stream containing the expected data.
*
* Note: this will seek to the beginning of the stream before reading.
*
* @param string $expectedContents
* @param resource $stream
*/
protected
function
assertStreamContents
(
$expectedContents
,
$stream
)
{
{
foreach
([
'fs.files'
,
'fs.chunks'
]
as
$collection
){
$this
->
assertInternalType
(
'resource'
,
$stream
);
$col
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
$collection
);
$this
->
assertSame
(
'stream'
,
get_resource_type
(
$stream
));
$col
->
drop
();
$this
->
assertEquals
(
$expectedContents
,
stream_get_contents
(
$stream
,
-
1
,
.
0
));
}
if
(
$this
->
hasFailed
())
{
return
;
}
}
}
public
function
provideInsertChunks
()
/**
* Creates an in-memory stream with the given data.
*
* @param string $data
* @return resource
*/
protected
function
createStream
(
$data
=
''
)
{
{
$dataVals
=
[];
$stream
=
fopen
(
'php://temp'
,
'w+b'
);
$testArgs
[][]
=
"hello world"
;
fwrite
(
$stream
,
$data
);
$testArgs
[][]
=
"1234567890"
;
rewind
(
$stream
);
$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
;
}
return
$stream
;
}
}
}
tests/GridFS/GridFSStreamTest.php
deleted
100644 → 0
View file @
3dbbd798
<?php
namespace
MongoDB\Tests\GridFS
;
use
MongoDB\GridFS
;
/**
* Functional tests for the Bucket class.
*/
class
GridFSStreamTest
extends
FunctionalTestCase
{
public
function
testBasic
()
{
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$upload
->
insertChunks
(
"hello world"
);
$id
=
$upload
->
getId
();
$upload
->
close
();
$this
->
assertEquals
(
1
,
$this
->
collectionWrapper
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
1
,
$this
->
collectionWrapper
->
getChunksCollection
()
->
count
());
$file
=
$this
->
collectionWrapper
->
findFileById
(
$id
);
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$file
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$download
->
downloadToStream
(
$stream
);
rewind
(
$stream
);
$contents
=
stream_get_contents
(
$stream
);
$this
->
assertEquals
(
"hello world"
,
$contents
);
fclose
(
$stream
);
#make sure it's still there!
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$file
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$download
->
downloadToStream
(
$stream
);
rewind
(
$stream
);
$contents
=
stream_get_contents
(
$stream
);
$this
->
assertEquals
(
"hello world"
,
$contents
);
fclose
(
$stream
);
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$id
=
$upload
->
getId
();
$upload
->
close
();
$this
->
assertEquals
(
2
,
$this
->
collectionWrapper
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
1
,
$this
->
collectionWrapper
->
getChunksCollection
()
->
count
());
$file
=
$this
->
collectionWrapper
->
findFileById
(
$id
);
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$file
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$download
->
downloadToStream
(
$stream
);
rewind
(
$stream
);
$contents
=
stream_get_contents
(
$stream
);
$this
->
assertEquals
(
""
,
$contents
);
}
public
function
testMd5
()
{
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$upload
->
insertChunks
(
"hello world
\n
"
);
$id
=
$upload
->
getId
();
$upload
->
close
();
$file
=
$this
->
collectionWrapper
->
findFileById
(
$id
);
$this
->
assertEquals
(
"6f5902ac237024bdd0c176cb93063dc4"
,
$file
->
md5
);
}
public
function
testUploadDefaultOpts
()
{
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$this
->
assertTrue
(
$upload
->
getId
()
instanceof
\MongoDB\BSON\ObjectId
);
$this
->
assertTrue
(
$upload
->
getFile
()[
"uploadDate"
]
instanceof
\MongoDB\BSON\UTCDateTime
);
$this
->
assertEquals
(
$upload
->
getFile
()[
"filename"
],
"test"
);
$this
->
assertEquals
(
$upload
->
getLength
(),
0
);
$this
->
assertTrue
(
!
isset
(
$upload
->
getFile
()[
"contentType"
]));
$this
->
assertTrue
(
!
isset
(
$upload
->
getFile
()[
"aliases"
]));
$this
->
assertTrue
(
!
isset
(
$upload
->
getFile
()[
"metadata"
]));
$this
->
assertEquals
(
255
*
1024
,
$upload
->
getChunkSize
());
}
public
function
testUploadCustomOpts
()
{
$options
=
[
"chunkSizeBytes"
=>
1
,
"contentType"
=>
"text/html"
,
"aliases"
=>
[
"foo"
,
"bar"
],
"metadata"
=>
[
"foo"
=>
1
,
"bar"
=>
2
]
];
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
,
$options
);
$this
->
assertEquals
(
$upload
->
getChunkSize
(),
1
);
$this
->
assertEquals
(
$upload
->
getFile
()[
"contentType"
],
"text/html"
);
$this
->
assertEquals
(
$upload
->
getFile
()[
"aliases"
],
[
"foo"
,
"bar"
]);
$this
->
assertEquals
(
$upload
->
getFile
()[
"metadata"
],
[
"foo"
=>
1
,
"bar"
=>
2
]);
}
public
function
testDownloadDefaultOpts
()
{
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$upload
->
close
();
$file
=
$this
->
collectionWrapper
->
findFileById
(
$upload
->
getId
());
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$file
);
$download
->
close
();
$this
->
assertEquals
(
$upload
->
getId
(),
$download
->
getId
());
$this
->
assertEquals
(
0
,
$download
->
getFile
()
->
length
);
$this
->
assertTrue
(
!
isset
(
$download
->
getFile
()
->
contentType
));
$this
->
assertTrue
(
!
isset
(
$download
->
getFile
()
->
aliases
));
$this
->
assertTrue
(
!
isset
(
$download
->
getFile
()
->
metadata
));
$this
->
assertTrue
(
$download
->
getFile
()
->
uploadDate
instanceof
\MongoDB\BSON\UTCDateTime
);
$this
->
assertEquals
(
255
*
1024
,
$download
->
getFile
()
->
chunkSize
);
$this
->
assertEquals
(
"d41d8cd98f00b204e9800998ecf8427e"
,
$download
->
getFile
()
->
md5
);
}
public
function
testDownloadCustomOpts
()
{
$options
=
[
"chunkSizeBytes"
=>
1000
,
"contentType"
=>
"text/html"
,
"aliases"
=>
[
"foo"
,
"bar"
],
"metadata"
=>
[
"foo"
=>
1
,
"bar"
=>
2
]
];
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
,
$options
);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
close
();
$file
=
$this
->
collectionWrapper
->
findFileById
(
$upload
->
getId
());
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$file
);
$this
->
assertEquals
(
"test"
,
$download
->
getFile
()
->
filename
);
$this
->
assertEquals
(
$upload
->
getId
(),
$download
->
getId
());
$this
->
assertEquals
(
11
,
$download
->
getFile
()
->
length
);
$this
->
assertEquals
(
"text/html"
,
$download
->
getFile
()
->
contentType
);
$this
->
assertEquals
(
1000
,
$download
->
getFile
()
->
chunkSize
);
$this
->
assertEquals
([
"foo"
,
"bar"
],
$download
->
getFile
()
->
aliases
);
$this
->
assertEquals
([
"foo"
=>
1
,
"bar"
=>
2
],
(
array
)
$download
->
getFile
()
->
metadata
);
$this
->
assertEquals
(
"5eb63bbbe01eeed093cb22bb8f5acdc3"
,
$download
->
getFile
()
->
md5
);
}
/**
*@dataProvider provideInsertChunks
*/
public
function
testInsertChunks
(
$data
)
{
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$upload
->
insertChunks
(
$data
);
$upload
->
close
();
$stream
=
$this
->
bucket
->
openDownloadStream
(
$upload
->
getId
());
$this
->
assertEquals
(
$data
,
stream_get_contents
(
$stream
));
}
public
function
testMultiChunkFile
()
{
$toUpload
=
""
;
for
(
$i
=
0
;
$i
<
255
*
1024
+
1000
;
$i
++
){
$toUpload
.=
"a"
;
}
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
);
$upload
->
insertChunks
(
$toUpload
);
$upload
->
close
();
$this
->
assertEquals
(
1
,
$this
->
collectionWrapper
->
getFilesCollection
()
->
count
());
$this
->
assertEquals
(
2
,
$this
->
collectionWrapper
->
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\WritableStream
(
$this
->
collectionWrapper
,
"test"
,
$options
);
$upload
->
insertChunks
(
$data
);
$upload
->
close
();
$this
->
assertEquals
(
strlen
(
$data
),
$this
->
collectionWrapper
->
getChunksCollection
()
->
count
());
$this
->
assertEquals
(
1
,
$this
->
collectionWrapper
->
getFilesCollection
()
->
count
());
$stream
=
$this
->
bucket
->
openDownloadStream
(
$upload
->
getId
());
$this
->
assertEquals
(
$data
,
stream_get_contents
(
$stream
));
}
public
function
testMultipleReads
()
{
$upload
=
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
,
[
"chunkSizeBytes"
=>
3
]);
$upload
->
insertChunks
(
"hello world"
);
$upload
->
close
();
$file
=
$this
->
collectionWrapper
->
findFileById
(
$upload
->
getId
());
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$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\WritableStream
(
$this
->
collectionWrapper
,
"test"
,
[
"chunkSizeBytes"
=>
rand
(
1
,
5
)]);
$upload
->
insertChunks
(
$data
);
$upload
->
close
();
$file
=
$this
->
collectionWrapper
->
findFileById
(
$upload
->
getId
());
$download
=
new
\MongoDB\GridFS\ReadableStream
(
$this
->
collectionWrapper
,
$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\InvalidArgumentException
* @dataProvider provideInvalidUploadConstructorOptions
*/
public
function
testUploadConstructorOptionTypeChecks
(
array
$options
)
{
new
\MongoDB\GridFS\WritableStream
(
$this
->
collectionWrapper
,
"test"
,
$options
);
}
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
];
}
foreach
(
$invalidMetadata
as
$value
)
{
$options
[][]
=
[
'metadata'
=>
$value
];
}
return
$options
;
}
}
tests/GridFS/ReadableStreamFunctionalTest.php
0 → 100644
View file @
cd9394c2
<?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
*/
public
function
testDownloadNumBytes
(
$fileId
,
$numBytes
,
$expectedBytes
)
{
$fileDocument
=
$this
->
collectionWrapper
->
findFileById
(
$fileId
);
$stream
=
new
ReadableStream
(
$this
->
collectionWrapper
,
$fileDocument
);
$this
->
assertSame
(
$expectedBytes
,
$stream
->
downloadNumBytes
(
$numBytes
));
}
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
*/
public
function
testDownloadNumBytesCalledMultipleTimes
(
$fileId
,
$numBytes
,
$expectedBytes
)
{
$fileDocument
=
$this
->
collectionWrapper
->
findFileById
(
$fileId
);
$stream
=
new
ReadableStream
(
$this
->
collectionWrapper
,
$fileDocument
);
for
(
$i
=
0
;
$i
<
$numBytes
;
$i
++
)
{
$expectedByte
=
isset
(
$expectedBytes
[
$i
])
?
$expectedBytes
[
$i
]
:
''
;
$this
->
assertSame
(
$expectedByte
,
$stream
->
downloadNumBytes
(
1
));
}
}
/**
* @expectedException MongoDB\GridFS\Exception\CorruptFileException
* @expectedExceptionMessage Chunk not found for index "2"
*/
public
function
testDownloadNumBytesWithMissingChunk
()
{
$this
->
chunksCollection
->
deleteOne
([
'files_id'
=>
'length-10'
,
'n'
=>
2
]);
$fileDocument
=
$this
->
collectionWrapper
->
findFileById
(
'length-10'
);
$stream
=
new
ReadableStream
(
$this
->
collectionWrapper
,
$fileDocument
);
$stream
->
downloadNumBytes
(
10
);
}
/**
* @expectedException MongoDB\GridFS\Exception\CorruptFileException
* @expectedExceptionMessage Expected chunk to have index "1" but found "2"
*/
public
function
testDownloadNumBytesWithUnexpectedChunkIndex
()
{
$this
->
chunksCollection
->
deleteOne
([
'files_id'
=>
'length-10'
,
'n'
=>
1
]);
$fileDocument
=
$this
->
collectionWrapper
->
findFileById
(
'length-10'
);
$stream
=
new
ReadableStream
(
$this
->
collectionWrapper
,
$fileDocument
);
$stream
->
downloadNumBytes
(
10
);
}
/**
* @expectedException MongoDB\GridFS\Exception\CorruptFileException
* @expectedExceptionMessage Expected chunk to have size "2" but found "1"
*/
public
function
testDownloadNumBytesWithUnexpectedChunkSize
()
{
$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
);
$stream
->
downloadNumBytes
(
10
);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
*/
public
function
testDownloadNumBytesWithNegativeReadSize
()
{
$fileDocument
=
$this
->
collectionWrapper
->
findFileById
(
'length-0'
);
$stream
=
new
ReadableStream
(
$this
->
collectionWrapper
,
$fileDocument
);
$stream
->
downloadNumBytes
(
-
1
);
}
}
tests/GridFS/SpecFunctionalTest.php
0 → 100644
View file @
cd9394c2
<?php
namespace
MongoDB\Tests\GridFS
;
use
MongoDB\Collection
;
use
MongoDB\BSON\Binary
;
use
MongoDB\BSON\ObjectId
;
use
MongoDB\BSON\UTCDateTime
;
use
MongoDB\Exception\RuntimeException
;
use
MongoDB\Operation\BulkWrite
;
use
DateTime
;
use
IteratorIterator
;
use
LogicException
;
use
MultipleIterator
;
/**
* GridFS spec functional tests.
*
* @see https://github.com/mongodb/specifications/tree/master/source/gridfs/tests
*/
class
SpecFunctionalTest
extends
FunctionalTestCase
{
private
$expectedChunksCollection
;
private
$expectedFilesCollection
;
public
function
setUp
()
{
parent
::
setUp
();
$this
->
expectedFilesCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
'expected.files'
);
$this
->
expectedFilesCollection
->
drop
();
$this
->
expectedChunksCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
'expected.chunks'
);
$this
->
expectedChunksCollection
->
drop
();
}
/**
* @dataProvider provideSpecificationTests
*/
public
function
testSpecification
(
array
$initialData
,
array
$test
)
{
$this
->
setName
(
str_replace
(
' '
,
'_'
,
$test
[
'description'
]));
$this
->
initializeData
(
$initialData
);
if
(
isset
(
$test
[
'arrange'
]))
{
foreach
(
$test
[
'arrange'
][
'data'
]
as
$dataModification
)
{
$this
->
executeDataModification
(
$dataModification
);
}
}
try
{
$result
=
$this
->
executeAct
(
$test
[
'act'
]);
}
catch
(
RuntimeException
$e
)
{
$result
=
$e
;
}
if
(
isset
(
$test
[
'assert'
]))
{
$this
->
executeAssert
(
$test
[
'assert'
],
$result
);
}
}
public
function
provideSpecificationTests
()
{
$testArgs
=
[];
foreach
(
glob
(
__DIR__
.
'/spec-tests/*.json'
)
as
$filename
)
{
$json
=
json_decode
(
file_get_contents
(
$filename
),
true
);
foreach
(
$json
[
'tests'
]
as
$test
)
{
$testArgs
[]
=
[
$json
[
'data'
],
$test
];
}
}
return
$testArgs
;
}
/**
* Assert that the collections contain equivalent documents.
*
* This method will resolve references within the expected collection's
* documents before comparing documents. Occurrences of "*result" in the
* expected collection's documents will be replaced with the actual result.
* Occurrences of "*actual" in the expected collection's documents will be
* replaced with the corresponding value in the actual collection's document
* being compared.
*
* @param Collection $expectedCollection
* @param Collection $actualCollection
* @param mixed $actualResult
*/
private
function
assertEquivalentCollections
(
$expectedCollection
,
$actualCollection
,
$actualResult
)
{
$mi
=
new
MultipleIterator
;
$mi
->
attachIterator
(
new
IteratorIterator
(
$expectedCollection
->
find
()));
$mi
->
attachIterator
(
new
IteratorIterator
(
$actualCollection
->
find
()));
foreach
(
$mi
as
$documents
)
{
list
(
$expectedDocument
,
$actualDocument
)
=
$documents
;
array_walk
(
$expectedDocument
,
function
(
&
$value
)
use
(
$actualResult
)
{
if
(
$value
===
'*result'
)
{
$value
=
$actualResult
;
}
});
array_walk
(
$expectedDocument
,
function
(
&
$value
,
$key
)
use
(
$actualDocument
)
{
if
(
!
is_string
(
$value
))
{
return
;
}
if
(
!
strncmp
(
$value
,
'*actual_'
,
8
))
{
$value
=
$actualDocument
[
$key
];
}
});
$this
->
assertSameDocument
(
$expectedDocument
,
$actualDocument
);
}
}
/**
* Convert encoded types in the array and return the modified array.
*
* Nested arrays with "$oid" and "$date" keys will be converted to ObjectID
* and UTCDateTime instances, respectively. Nested arrays with "$hex" keys
* will be converted to a string or Binary object.
*
* @param param $data
* @param boolean $createBinary If true, convert "$hex" values to a Binary
* @return array
*/
private
function
convertTypes
(
array
$data
,
$createBinary
=
true
)
{
/* array_walk_recursive() only visits leaf nodes within the array, so we
* need to manually recurse.
*/
array_walk
(
$data
,
function
(
&
$value
)
use
(
$createBinary
)
{
if
(
!
is_array
(
$value
))
{
return
;
}
if
(
isset
(
$value
[
'$oid'
]))
{
$value
=
new
ObjectId
(
$value
[
'$oid'
]);
return
;
}
if
(
isset
(
$value
[
'$hex'
]))
{
$value
=
$createBinary
?
new
Binary
(
hex2bin
(
$value
[
'$hex'
]),
Binary
::
TYPE_GENERIC
)
:
hex2bin
(
$value
[
'$hex'
]);
return
;
}
if
(
isset
(
$value
[
'$date'
]))
{
// TODO: This is necessary until PHPC-536 is implemented
$milliseconds
=
floor
((
new
DateTime
(
$value
[
'$date'
]))
->
format
(
'U.u'
)
*
1000
);
$value
=
new
UTCDateTime
(
$milliseconds
);
return
;
}
$value
=
$this
->
convertTypes
(
$value
,
$createBinary
);
});
return
$data
;
}
/**
* Executes an "act" block.
*
* @param array $act
* @return mixed
* @throws LogicException if the operation is unsupported
*/
private
function
executeAct
(
array
$act
)
{
$act
=
$this
->
convertTypes
(
$act
,
false
);
switch
(
$act
[
'operation'
])
{
case
'delete'
:
return
$this
->
bucket
->
delete
(
$act
[
'arguments'
][
'id'
]);
case
'download'
:
return
stream_get_contents
(
$this
->
bucket
->
openDownloadStream
(
$act
[
'arguments'
][
'id'
]));
case
'download_by_name'
:
return
stream_get_contents
(
$this
->
bucket
->
openDownloadStreamByName
(
$act
[
'arguments'
][
'filename'
],
isset
(
$act
[
'arguments'
][
'options'
])
?
$act
[
'arguments'
][
'options'
]
:
[]
));
case
'upload'
:
return
$this
->
bucket
->
uploadFromStream
(
$act
[
'arguments'
][
'filename'
],
$this
->
createStream
(
$act
[
'arguments'
][
'source'
]),
isset
(
$act
[
'arguments'
][
'options'
])
?
$act
[
'arguments'
][
'options'
]
:
[]
);
default
:
throw
new
LogicException
(
'Unsupported act: '
.
$act
[
'operation'
]);
}
}
/**
* Executes an "assert" block.
*
* @param array $assert
* @param mixed $actualResult
* @return mixed
* @throws FileNotFoundException
* @throws LogicException if the operation is unsupported
*/
private
function
executeAssert
(
array
$assert
,
$actualResult
)
{
if
(
isset
(
$assert
[
'error'
]))
{
$this
->
assertInstanceOf
(
$this
->
getExceptionClassForError
(
$assert
[
'error'
]),
$actualResult
);
}
if
(
isset
(
$assert
[
'result'
]))
{
$this
->
executeAssertResult
(
$assert
[
'result'
],
$actualResult
);
}
if
(
!
isset
(
$assert
[
'data'
]))
{
return
;
}
/* Since "*actual" may be used for an expected document's "_id", append
* a unique value to avoid duplicate key exceptions.
*/
array_walk_recursive
(
$assert
[
'data'
],
function
(
&
$value
)
{
if
(
$value
===
'*actual'
)
{
$value
.=
'_'
.
new
ObjectId
;
}
});
foreach
(
$assert
[
'data'
]
as
$dataModification
)
{
$this
->
executeDataModification
(
$dataModification
);
}
$this
->
assertEquivalentCollections
(
$this
->
expectedFilesCollection
,
$this
->
filesCollection
,
$actualResult
);
$this
->
assertEquivalentCollections
(
$this
->
expectedChunksCollection
,
$this
->
chunksCollection
,
$actualResult
);
}
/**
* Executes the "result" section of an "assert" block.
*
* @param mixed $expectedResult
* @param mixed $actualResult
* @param array $data
* @throws LogicException if the result assertion is unsupported
*/
private
function
executeAssertResult
(
$expectedResult
,
$actualResult
)
{
if
(
$expectedResult
===
'void'
)
{
return
$this
->
assertNull
(
$actualResult
);
}
if
(
$expectedResult
===
'&result'
)
{
// Do nothing; assertEquivalentCollections() will handle this
return
;
}
if
(
isset
(
$expectedResult
[
'$hex'
]))
{
return
$this
->
assertSame
(
hex2bin
(
$expectedResult
[
'$hex'
]),
$actualResult
);
}
throw
new
LogicException
(
'Unsupported result assertion: '
.
var_export
(
$expectedResult
,
true
));
}
/**
* Executes a data modification from an "arrange" or "assert" block.
*
* @param array $dataModification
* @return mixed
* @throws LogicException if the operation or collection is unsupported
*/
private
function
executeDataModification
(
array
$dataModification
)
{
foreach
(
$dataModification
as
$type
=>
$collectionName
)
{
break
;
}
if
(
!
in_array
(
$collectionName
,
[
'fs.files'
,
'fs.chunks'
,
'expected.files'
,
'expected.chunks'
]))
{
throw
new
LogicException
(
'Unsupported collection: '
.
$collectionName
);
}
$dataModification
=
$this
->
convertTypes
(
$dataModification
);
$operations
=
[];
switch
(
$type
)
{
case
'delete'
:
foreach
(
$dataModification
[
'deletes'
]
as
$delete
)
{
$operations
[]
=
[
(
$delete
[
'limit'
]
===
1
?
'deleteOne'
:
'deleteMany'
)
=>
[
$delete
[
'q'
]
]
];
}
break
;
case
'insert'
:
foreach
(
$dataModification
[
'documents'
]
as
$document
)
{
$operations
[]
=
[
'insertOne'
=>
[
$document
]
];
}
break
;
case
'update'
:
foreach
(
$dataModification
[
'updates'
]
as
$update
)
{
$operations
[]
=
[
'updateOne'
=>
[
$update
[
'q'
],
$update
[
'u'
]
]
];
}
break
;
default
:
throw
new
LogicException
(
'Unsupported arrangement: '
.
$type
);
}
$bulk
=
new
BulkWrite
(
$this
->
getDatabaseName
(),
$collectionName
,
$operations
);
return
$bulk
->
execute
(
$this
->
getPrimaryServer
());
}
/**
* Returns the exception class for the "error" section of an "assert" block.
*
* @param string $error
* @return string
* @throws LogicException if the error is unsupported
*/
private
function
getExceptionClassForError
(
$error
)
{
switch
(
$error
)
{
case
'FileNotFound'
:
case
'RevisionNotFound'
:
return
'MongoDB\GridFS\Exception\FileNotFoundException'
;
case
'ChunkIsMissing'
:
case
'ChunkIsWrongSize'
:
return
'MongoDB\GridFS\Exception\CorruptFileException'
;
default
:
throw
new
LogicException
(
'Unsupported error: '
.
$error
);
}
}
/**
* Initializes data in the files and chunks collections.
*
* @param array $data
*/
private
function
initializeData
(
array
$data
)
{
$data
=
$this
->
convertTypes
(
$data
);
if
(
!
empty
(
$data
[
'files'
]))
{
$this
->
filesCollection
->
insertMany
(
$data
[
'files'
]);
$this
->
expectedFilesCollection
->
insertMany
(
$data
[
'files'
]);
}
if
(
!
empty
(
$data
[
'chunks'
]))
{
$this
->
chunksCollection
->
insertMany
(
$data
[
'chunks'
]);
$this
->
expectedChunksCollection
->
insertMany
(
$data
[
'chunks'
]);
}
}
}
tests/GridFS/Specification/tests/README.rst
deleted
100644 → 0
View file @
3dbbd798
GridFS Tests
============
The YAML and JSON files in this directory are platform-independent tests
meant to exercise a driver's implementation of GridFS.
Converting to JSON
==================
The tests are written in YAML because it is easier for humans to write
and read, and because YAML supports a standard comment format. Each test
is also provided in JSON format because in some languages it is easier
to parse JSON than YAML.
If you modify any test, you should modify the YAML file and then
regenerate the JSON file from it.
One way to convert the files is using an online web page. I used:
http://www.json2yaml.com/
It's advertised as a JSON to YAML converter but it can be used in either direction.
Note: the yaml2json utility from npm is not capable of converting these YAML tests
because it doesn't implement the full YAML spec.
Format
======
Each test file has two top level sections:
1. data
2. tests
The data section defines the initial contents of the files and chunks
collections for all tests in that file.
The tests section defines the tests to be run. The format of the tests
section will vary slightly depending on what tests are being defined.
In general, they will have the following sections:
1. description
2. arrange
3. act
4. assert
The arrange section, if present, defines changes to be made to the
initial contents of the files and chunks collections (as defined by
the data section) before this particular test is run. These changes
are described in the form of write commands that can be sent directly
to MongoDB.
The act section defines what operation (with which arguments) should
be performed.
The assert section defines what should be true at the end of the test.
This includes checking the return value of the operation, as well as
checking the expected contents of the files and chunks collections. The
expected contents of the files and chunks collections are described
in the form of write commands that modify collections named
expected.files and expected.chunks. Before running these commands,
load the initial files and chunks documents into the expected.files
and expected.chunks collections and then run the commands. At that point
you can assert that fs.files and expected.files are the same, and that
expected.chunks and fs.chunks are the same.
For operations that are expected to succeed the assert section contains
a "result" element describing the expected result. For operations
that are expected to fail the assert section contains an "error"
element describing the expected failure.
The "result" element is either the expected result when it is possible to
know the result in advance, or it is the special value "&result"
which means that we expect a result (not a failure) but the actual
value of the result could be anything. The notation "&result" is
modeled after YAML syntax for defining an anchor, and the
result value may be referenced later in the assert section as
"*result".
Another special notation in the assert section is "*actual", which
is used when the value of a field cannot be known in advance of the
test, so the assert logic should accept whatever the actual value
ended up being.
tests/GridFS/Specification/tests/delete.yml
deleted
100644 → 0
View file @
3dbbd798
data
:
files
:
-
_id
:
{
"
$oid"
:
"
000000000000000000000001"
}
length
:
0
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
d41d8cd98f00b204e9800998ecf8427e"
filename
:
"
length-0"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000002"
}
length
:
0
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
d41d8cd98f00b204e9800998ecf8427e"
filename
:
"
length-0-with-empty-chunk"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000003"
}
length
:
2
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
c700ed4fdb1d27055aa3faa2c2432283"
filename
:
"
length-2"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
length
:
8
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
dd254cdc958e53abaa67da9f797125f5"
filename
:
"
length-8"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
chunks
:
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000001"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000002"
},
n
:
0
,
data
:
{
$hex
:
"
"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000002"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000003"
},
n
:
0
,
data
:
{
$hex
:
"
1122"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000003"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
n
:
0
,
data
:
{
$hex
:
"
11223344"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
n
:
1
,
data
:
{
$hex
:
"
55667788"
}
}
tests
:
-
description
:
"
Delete
when
length
is
0"
act
:
operation
:
delete
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000001"
}
assert
:
result
:
void
data
:
-
{
delete
:
"
expected.files"
,
deletes
:
[
{
q
:
{
_id
:
{
"
$oid"
:
"
000000000000000000000001"
}
},
limit
:
1
}
]
}
-
description
:
"
Delete
when
length
is
0
and
there
is
one
extra
empty
chunk"
act
:
operation
:
delete
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000002"
}
assert
:
result
:
void
data
:
-
{
delete
:
"
expected.files"
,
deletes
:
[
{
q
:
{
_id
:
{
"
$oid"
:
"
000000000000000000000002"
}
},
limit
:
1
}
]
}
-
{
delete
:
"
expected.chunks"
,
deletes
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000002"
}
},
limit
:
0
}
]
}
-
description
:
"
Delete
when
length
is
8"
act
:
operation
:
delete
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000004"
}
assert
:
result
:
void
data
:
-
{
delete
:
"
expected.files"
,
deletes
:
[
{
q
:
{
_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
},
limit
:
1
}
]
}
-
{
delete
:
"
expected.chunks"
,
deletes
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
},
limit
:
0
}
]
}
-
description
:
"
Delete
when
files
entry
does
not
exist"
act
:
operation
:
delete
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000000"
}
assert
:
error
:
"
FileNotFound"
-
description
:
"
Delete
when
files
entry
does
not
exist
and
there
are
orphaned
chunks"
arrange
:
data
:
-
{
delete
:
"
fs.files"
,
deletes
:
[
{
q
:
{
_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
},
limit
:
1
}
]
}
act
:
operation
:
delete
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000004"
}
assert
:
error
:
"
FileNotFound"
data
:
-
{
delete
:
"
expected.files"
,
deletes
:
[
{
q
:
{
_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
},
limit
:
1
}
]
}
-
{
delete
:
"
expected.chunks"
,
deletes
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
},
limit
:
0
}
]
}
tests/GridFS/Specification/tests/download.yml
deleted
100644 → 0
View file @
3dbbd798
data
:
files
:
-
_id
:
{
"
$oid"
:
"
000000000000000000000001"
}
length
:
0
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
d41d8cd98f00b204e9800998ecf8427e"
filename
:
"
length-0"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000002"
}
length
:
0
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
d41d8cd98f00b204e9800998ecf8427e"
filename
:
"
length-0-with-empty-chunk"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000003"
}
length
:
2
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
c700ed4fdb1d27055aa3faa2c2432283"
filename
:
"
length-2"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
length
:
8
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
dd254cdc958e53abaa67da9f797125f5"
filename
:
"
length-8"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000005"
}
length
:
10
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
57d83cd477bfb1ccd975ab33d827a92b"
filename
:
"
length-10"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
chunks
:
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000001"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000002"
},
n
:
0
,
data
:
{
$hex
:
"
"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000002"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000003"
},
n
:
0
,
data
:
{
$hex
:
"
1122"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000003"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
n
:
0
,
data
:
{
$hex
:
"
11223344"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
n
:
1
,
data
:
{
$hex
:
"
55667788"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
0
,
data
:
{
$hex
:
"
11223344"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000006"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
1
,
data
:
{
$hex
:
"
55667788"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000007"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
2
,
data
:
{
$hex
:
"
99aa"
}
}
tests
:
-
description
:
"
Download
when
length
is
zero"
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000001"
}
options
:
{
}
assert
:
result
:
{
$hex
:
"
"
}
-
description
:
"
Download
when
length
is
zero
and
there
is
one
empty
chunk"
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000002"
}
options
:
{
}
assert
:
result
:
{
$hex
:
"
"
}
-
description
:
"
Download
when
there
is
one
chunk"
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000003"
}
options
:
{
}
assert
:
result
:
{
$hex
:
"
1122"
}
-
description
:
"
Download
when
there
are
two
chunks"
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000004"
}
options
:
{
}
assert
:
result
:
{
$hex
:
"
1122334455667788"
}
-
description
:
"
Download
when
there
are
three
chunks"
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000005"
}
options
:
{
}
assert
:
result
:
{
$hex
:
"
112233445566778899aa"
}
-
description
:
"
Download
when
files
entry
does
not
exist"
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000000"
}
options
:
{
}
assert
:
error
:
"
FileNotFound"
-
description
:
"
Download
when
an
intermediate
chunk
is
missing"
arrange
:
data
:
-
{
delete
:
"
fs.chunks"
,
deletes
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
1
},
limit
:
1
}
]
}
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000005"
}
assert
:
error
:
"
ChunkIsMissing"
-
description
:
"
Download
when
final
chunk
is
missing"
arrange
:
data
:
-
{
delete
:
"
fs.chunks"
,
deletes
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
1
},
limit
:
1
}
]
}
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000005"
}
assert
:
error
:
"
ChunkIsMissing"
-
description
:
"
Download
when
an
intermediate
chunk
is
the
wrong
size"
arrange
:
data
:
-
{
update
:
"
fs.chunks"
,
updates
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
1
},
u
:
{
$set
:
{
data
:
{
$hex
:
"
556677"
}
}
}
},
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
2
},
u
:
{
$set
:
{
data
:
{
$hex
:
"
8899aa"
}
}
}
}
]
}
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000005"
}
assert
:
error
:
"
ChunkIsWrongSize"
-
description
:
"
Download
when
final
chunk
is
the
wrong
size"
arrange
:
data
:
-
{
update
:
"
fs.chunks"
,
updates
:
[
{
q
:
{
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
2
},
u
:
{
$set
:
{
data
:
{
$hex
:
"
99"
}
}
}
}
]
}
act
:
operation
:
download
arguments
:
id
:
{
"
$oid"
:
"
000000000000000000000005"
}
assert
:
error
:
"
ChunkIsWrongSize"
tests/GridFS/Specification/tests/download_by_name.yml
deleted
100644 → 0
View file @
3dbbd798
data
:
files
:
-
_id
:
{
"
$oid"
:
"
000000000000000000000001"
}
length
:
1
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-01T00:00:00.000Z"
}
md5
:
"
47ed733b8d10be225eceba344d533586"
filename
:
"
abc"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000002"
}
length
:
1
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-02T00:00:00.000Z"
}
md5
:
"
b15835f133ff2e27c7cb28117bfae8f4"
filename
:
"
abc"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000003"
}
length
:
1
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-03T00:00:00.000Z"
}
md5
:
"
eccbc87e4b5ce2fe28308fd9f2a7baf3"
filename
:
"
abc"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000004"
}
length
:
1
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-04T00:00:00.000Z"
}
md5
:
"
f623e75af30e62bbd73d6df5b50bb7b5"
filename
:
"
abc"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
-
_id
:
{
"
$oid"
:
"
000000000000000000000005"
}
length
:
1
chunkSize
:
4
uploadDate
:
{
"
$date"
:
"
1970-01-05T00:00:00.000Z"
}
md5
:
"
4c614360da93c0a041b22e537de151eb"
filename
:
"
abc"
contentType
:
"
application/octet-stream"
aliases
:
[]
metadata
:
{}
chunks
:
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000001"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000001"
},
n
:
0
,
data
:
{
$hex
:
"
11"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000002"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000002"
},
n
:
0
,
data
:
{
$hex
:
"
22"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000003"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000003"
},
n
:
0
,
data
:
{
$hex
:
"
33"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000004"
},
n
:
0
,
data
:
{
$hex
:
"
44"
}
}
-
{
_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
files_id
:
{
"
$oid"
:
"
000000000000000000000005"
},
n
:
0
,
data
:
{
$hex
:
"
55"
}
}
tests
:
-
description
:
"
Download_by_name
when
revision
is
0"
act
:
operation
:
download_by_name
arguments
:
filename
:
"
abc"
options
:
{
revision
:
0
}
assert
:
result
:
{
$hex
:
"
11"
}
-
description
:
"
Download_by_name
when
revision
is
1"
act
:
operation
:
download_by_name
arguments
:
filename
:
"
abc"
options
:
{
revision
:
1
}
assert
:
result
:
{
$hex
:
"
22"
}
-
description
:
"
Download_by_name
when
revision
is
-2"
act
:
operation
:
download_by_name
arguments
:
filename
:
"
abc"
options
:
{
revision
:
-2
}
assert
:
result
:
{
$hex
:
"
44"
}
-
description
:
"
Download_by_name
when
revision
is
-1"
act
:
operation
:
download_by_name
arguments
:
filename
:
"
abc"
options
:
{
revision
:
-1
}
assert
:
result
:
{
$hex
:
"
55"
}
-
description
:
"
Download_by_name
when
files
entry
does
not
exist"
act
:
operation
:
download_by_name
arguments
:
filename
:
"
xyz"
assert
:
error
:
"
FileNotFound"
-
description
:
"
Download_by_name
when
revision
does
not
exist"
act
:
operation
:
download_by_name
arguments
:
filename
:
"
abc"
options
:
{
revision
:
999
}
assert
:
error
:
"
RevisionNotFound"
tests/GridFS/Specification/tests/upload.yml
deleted
100644 → 0
View file @
3dbbd798
data
:
files
:
[]
chunks
:
[]
tests
:
-
description
:
"
Upload
when
length
is
0"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
"
}
options
:
{
chunkSizeBytes
:
4
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
0
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
d41d8cd98f00b204e9800998ecf8427e"
,
filename
:
"
filename"
}
]
}
-
description
:
"
Upload
when
length
is
1"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
11"
}
options
:
{
chunkSizeBytes
:
4
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
1
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
47ed733b8d10be225eceba344d533586"
,
filename
:
"
filename"
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
11"
}
}
]
}
-
description
:
"
Upload
when
length
is
3"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
112233"
}
options
:
{
chunkSizeBytes
:
4
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
3
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
bafae3a174ab91fc70db7a6aa50f4f52"
,
filename
:
"
filename"
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
112233"
}
}
]
}
-
description
:
"
Upload
when
length
is
4"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
11223344"
}
options
:
{
chunkSizeBytes
:
4
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
4
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
7e7c77cff5705d1f7574a25ef6662117"
,
filename
:
"
filename"
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
11223344"
}
}
]
}
-
description
:
"
Upload
when
length
is
5"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
1122334455"
}
options
:
{
chunkSizeBytes
:
4
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
5
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
283d4fea5dded59cf837d3047328f5af"
,
filename
:
"
filename"
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
11223344"
}
},
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
1
,
data
:
{
$hex
:
"
55"
}
}
]
}
-
description
:
"
Upload
when
length
is
8"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
1122334455667788"
}
options
:
{
chunkSizeBytes
:
4
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
8
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
dd254cdc958e53abaa67da9f797125f5"
,
filename
:
"
filename"
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
11223344"
}
},
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
1
,
data
:
{
$hex
:
"
55667788"
}
}
]
}
-
description
:
"
Upload
when
contentType
is
provided"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
11"
}
options
:
{
chunkSizeBytes
:
4
,
contentType
:
"
image/jpeg"
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
1
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
47ed733b8d10be225eceba344d533586"
,
filename
:
"
filename"
,
contentType
:
"
image/jpeg"
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
11"
}
}
]
}
-
description
:
"
Upload
when
metadata
is
provided"
act
:
operation
:
upload
arguments
:
filename
:
"
filename"
source
:
{
$hex
:
"
11"
}
options
:
chunkSizeBytes
:
4
metadata
:
{
x
:
1
}
assert
:
result
:
"
&result"
data
:
-
{
insert
:
"
expected.files"
,
documents
:
[
{
_id
:
"
*result"
,
length
:
1
,
chunkSize
:
4
,
uploadDate
:
"
*actual"
,
md5
:
"
47ed733b8d10be225eceba344d533586"
,
filename
:
"
filename"
,
metadata
:
{
x
:
1
}
}
]
}
-
{
insert
:
"
expected.chunks"
,
documents
:
[
{
_id
:
"
*actual"
,
files_id
:
"
*result"
,
n
:
0
,
data
:
{
$hex
:
"
11"
}
}
]
}
tests/GridFS/SpecificationTests.php
deleted
100644 → 0
View file @
3dbbd798
<?php
namespace
MongoDB\Tests\GridFS
;
use
\MongoDB\GridFS
;
use
\MongoDB\Collection
;
use
\MongoDB\BSON\ObjectId
;
use
\MongoDB\BSON\Binary
;
use
\MongoDB\Exception
;
class
SpecificationTests
extends
FunctionalTestCase
{
private
$commands
;
private
$collections
;
public
function
setUp
()
{
parent
::
setUp
();
$this
->
commands
=
array
(
'insert'
=>
function
(
$col
,
$docs
)
{
$col
->
insertMany
(
$docs
[
'documents'
]);},
'update'
=>
function
(
$col
,
$docs
)
{
foreach
(
$docs
[
'updates'
]
as
$update
)
{
$col
->
updateMany
(
$update
[
'q'
],
$update
[
'u'
]);
}
},
'delete'
=>
function
(
$col
,
$docs
){
foreach
(
$docs
[
'deletes'
]
as
$delete
){
$col
->
deleteMany
(
$delete
[
'q'
]);
}
}
);
}
/**
*@dataProvider provideSpecificationTests
*/
public
function
testSpecificationTests
(
$testJson
)
{
foreach
(
$testJson
[
'tests'
]
as
$test
)
{
$this
->
initializeDatabases
(
$testJson
[
'data'
],
$test
);
if
(
isset
(
$test
[
'act'
][
'arguments'
][
'options'
])){
$options
=
$test
[
'act'
][
'arguments'
][
'options'
];
}
else
{
$options
=
[];
}
$this
->
bucket
=
new
\MongoDB\GridFS\Bucket
(
$this
->
manager
,
$this
->
getDatabaseName
(),
$this
->
fixTypes
(
$options
,
false
));
$func
=
$test
[
'act'
][
'operation'
]
.
"Command"
;
$error
=
null
;
try
{
$result
=
$this
->
$func
(
$test
[
'act'
][
'arguments'
]);
}
catch
(
\MongoDB\Exception\Exception
$e
)
{
$error
=
$e
;
}
$errors
=
[
'FileNotFound'
=>
'\MongoDB\GridFS\Exception\FileNotFoundException'
,
'ChunkIsMissing'
=>
'\MongoDB\GridFS\Exception\CorruptFileException'
,
'ExtraChunk'
=>
'\MongoDB\GridFS\Exception\CorruptFileException'
,
'ChunkIsWrongSize'
=>
'\MongoDB\GridFS\Exception\CorruptFileException'
,
'RevisionNotFound'
=>
'\MongoDB\GridFS\Exception\FileNotFoundException'
];
if
(
!
isset
(
$test
[
'assert'
][
'error'
]))
{
$this
->
assertNull
(
$error
);
}
else
{
$shouldError
=
$test
[
'assert'
][
'error'
];
$this
->
assertTrue
(
$error
instanceof
$errors
[
$shouldError
]);
}
if
(
isset
(
$test
[
'assert'
][
'result'
]))
{
$testResult
=
$test
[
'assert'
][
'result'
];
if
(
$testResult
==
'&result'
)
{
$test
[
'assert'
][
'result'
]
=
$result
;
}
if
(
$testResult
==
"void"
)
{
$test
[
'assert'
][
'result'
]
=
null
;
}
$fixedAssertFalse
=
$this
->
fixTypes
(
$test
[
'assert'
],
false
);
$this
->
assertEquals
(
$result
,
$fixedAssertFalse
[
'result'
]);
}
$fixedAssertTrue
=
$this
->
fixTypes
(
$test
[
'assert'
],
true
);
if
(
isset
(
$test
[
'assert'
][
'data'
]))
{
$this
->
runCommands
(
$fixedAssertTrue
[
'data'
],
$result
);
$this
->
collectionsEqual
(
$this
->
collections
[
'expected.files'
],
$this
->
bucket
->
getCollectionWrapper
()
->
getFilesCollection
());
if
(
isset
(
$this
->
collections
[
'expected.chunks'
]))
{
$this
->
collectionsEqual
(
$this
->
collections
[
'expected.chunks'
],
$this
->
bucket
->
getCollectionWrapper
()
->
getChunksCollection
());
}
}
}
}
public
function
provideSpecificationTests
()
{
$testPath
=
__DIR__
.
'/Specification/tests/*.json'
;
$testArgs
=
[];
foreach
(
glob
(
$testPath
)
as
$filename
)
{
$fileContents
=
file_get_contents
(
$filename
);
$testJson
=
json_decode
(
$fileContents
,
true
);
$testArgs
[][]
=
$testJson
;
}
return
$testArgs
;
}
public
function
fixTypes
(
$testJson
,
$makeBinary
)
{
$result
=
$testJson
;
foreach
(
$result
as
$key
=>
$value
)
{
if
(
is_array
(
$value
)
&&
isset
(
$value
[
'$hex'
]))
{
$result
[
$key
]
=
hex2bin
(
$value
[
'$hex'
]);
if
(
$makeBinary
)
{
$result
[
$key
]
=
new
\MongoDB\BSON\Binary
(
$result
[
$key
],
\MongoDB\BSON\Binary
::
TYPE_GENERIC
);
}
}
else
if
(
is_array
(
$value
)
&&
isset
(
$value
[
'$oid'
]))
{
$result
[
$key
]
=
new
\MongoDB\BSON\ObjectId
(
""
.
$value
[
'$oid'
]);
}
else
if
(
is_array
(
$value
))
{
$result
[
$key
]
=
$this
->
fixTypes
(
$result
[
$key
],
$makeBinary
);
}
else
if
(
is_string
(
$value
)
&&
$value
==
'*actual'
)
{
unset
(
$result
[
$key
]);
}
}
return
$result
;
}
public
function
collectionsEqual
(
$col1
,
$col2
)
{
$docs1
=
$this
->
filterDoc
(
$col1
,
true
);
$docs2
=
$this
->
filterDoc
(
$col2
,
true
);
$this
->
assertSameDocuments
(
$docs1
,
$docs2
);
}
public
function
filterDoc
(
$collection
,
$ignoreId
)
{
$output
=
[];
$documents
=
$collection
->
find
();
foreach
(
$documents
as
$doc
){
if
(
$ignoreId
)
{
unset
(
$doc
->
_id
);
}
if
(
isset
(
$doc
->
uploadDate
))
{
// $this->assertTrue($doc->uploadDate instanceof DateTime);
unset
(
$doc
->
uploadDate
);
}
$output
[]
=
$doc
;
}
return
$output
;
}
public
function
runCommands
(
$cmds
,
$result
)
{
foreach
(
$cmds
as
$cmd
){
foreach
(
$cmd
as
$key
=>
$value
)
{
if
(
isset
(
$this
->
commands
[
$key
]))
{
$cmdName
=
$key
;
$collectionName
=
$value
;
if
(
isset
(
$cmd
[
'documents'
])){
foreach
(
$cmd
[
'documents'
]
as
$docIndex
=>
$doc
)
{
foreach
(
$doc
as
$docKey
=>
$docVal
){
if
(
is_string
(
$docVal
))
{
if
(
$docVal
==
'*result'
)
{
$doc
[
$docKey
]
=
$result
;
}
}
}
$cmd
[
'documents'
][
$docIndex
]
=
$doc
;
}
}
$collection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
$collectionName
);
$this
->
commands
[
$key
](
$collection
,
$this
->
fixTypes
(
$cmd
,
true
));
$this
->
collections
[
$collectionName
]
=
$collection
;
}
}
}
}
public
function
initializeDatabases
(
$data
,
$test
)
{
$collectionsToDrop
=
[
'fs.files'
,
'fs.chunks'
,
'expected.files'
,
'expected.chunks'
];
$data
=
$this
->
fixTypes
(
$data
,
true
);
foreach
(
$collectionsToDrop
as
$collectionName
)
{
$collection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
$collectionName
);
$collection
->
drop
();
}
if
(
isset
(
$data
[
'files'
])
&&
count
(
$data
[
'files'
])
>
0
)
{
$filesCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
"fs.files"
);
$filesCollection
->
insertMany
(
$data
[
'files'
]);
$expectedFilesCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
"expected.files"
);
$expectedFilesCollection
->
insertMany
(
$data
[
'files'
]);
$this
->
collections
[
'expected.files'
]
=
$expectedFilesCollection
;
}
if
(
isset
(
$data
[
'chunks'
])
&&
count
(
$data
[
'chunks'
])
>
0
)
{
$chunksCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
"fs.chunks"
);
$chunksCollection
->
insertMany
(
$data
[
'chunks'
]);
$expectedChunksCollection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
"expected.chunks"
);
$expectedChunksCollection
->
insertMany
(
$data
[
'chunks'
]);
$this
->
collections
[
'expected.chunks'
]
=
$expectedChunksCollection
;
}
if
(
isset
(
$test
[
'arrange'
]))
{
foreach
(
$test
[
'arrange'
][
'data'
]
as
$cmd
)
{
foreach
(
$cmd
as
$key
=>
$value
)
{
if
(
isset
(
$this
->
commands
[
$key
]))
{
$collection
=
new
Collection
(
$this
->
manager
,
$this
->
getDatabaseName
(),
$cmd
[
$key
]);
$this
->
commands
[
$key
](
$collection
,
$this
->
fixTypes
(
$cmd
,
true
));
}
}
}
}
}
public
function
uploadCommand
(
$args
)
{
$args
=
$this
->
fixTypes
(
$args
,
false
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
fwrite
(
$stream
,
$args
[
'source'
]);
rewind
(
$stream
);
$result
=
$this
->
bucket
->
uploadFromStream
(
$args
[
'filename'
],
$stream
,
$args
[
'options'
]);
fclose
(
$stream
);
return
$result
;
}
function
downloadCommand
(
$args
)
{
$args
=
$this
->
fixTypes
(
$args
,
false
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
$this
->
bucket
->
downloadToStream
(
$args
[
'id'
],
$stream
);
rewind
(
$stream
);
$result
=
stream_get_contents
(
$stream
);
fclose
(
$stream
);
return
$result
;
}
function
deleteCommand
(
$args
)
{
$args
=
$this
->
fixTypes
(
$args
,
false
);
$this
->
bucket
->
delete
(
$args
[
'id'
]);
}
function
download_by_nameCommand
(
$args
)
{
$args
=
$this
->
fixTypes
(
$args
,
false
);
$stream
=
fopen
(
'php://temp'
,
'w+'
);
if
(
isset
(
$args
[
'options'
]))
{
$this
->
bucket
->
downloadToStreamByName
(
$args
[
'filename'
],
$stream
,
$args
[
'options'
]);
}
else
{
$this
->
bucket
->
downloadToStreamByName
(
$args
[
'filename'
],
$stream
);
}
rewind
(
$stream
);
$result
=
stream_get_contents
(
$stream
);
fclose
(
$stream
);
return
$result
;
}
}
tests/GridFS/WritableStreamFunctionalTest.php
0 → 100644
View file @
cd9394c2
<?php
namespace
MongoDB\Tests\GridFS
;
use
MongoDB\GridFS\CollectionWrapper
;
use
MongoDB\GridFS\WritableStream
;
/**
* Functional tests for the internal WritableStream class.
*/
class
WritableStreamFunctionalTest
extends
FunctionalTestCase
{
private
$collectionWrapper
;
public
function
setUp
()
{
parent
::
setUp
();
$this
->
collectionWrapper
=
new
CollectionWrapper
(
$this
->
manager
,
$this
->
getDatabaseName
(),
'fs'
);
}
public
function
testValidConstructorOptions
()
{
new
WritableStream
(
$this
->
collectionWrapper
,
'filename'
,
[
'_id'
=>
'custom-id'
,
'chunkSizeBytes'
=>
2
,
'metadata'
=>
[
'foo'
=>
'bar'
],
]);
}
/**
* @expectedException MongoDB\Exception\InvalidArgumentException
* @dataProvider provideInvalidConstructorOptions
*/
public
function
testConstructorOptionTypeChecks
(
array
$options
)
{
new
WritableStream
(
$this
->
collectionWrapper
,
'filename'
,
$options
);
}
public
function
provideInvalidConstructorOptions
()
{
$options
=
[];
foreach
(
$this
->
getInvalidIntegerValues
()
as
$value
)
{
$options
[][]
=
[
'chunkSizeBytes'
=>
$value
];
}
foreach
(
$this
->
getInvalidDocumentValues
()
as
$value
)
{
$options
[][]
=
[
'metadata'
=>
$value
];
}
return
$options
;
}
/**
* @dataProvider provideInputDataAndExpectedMD5
*/
public
function
testInsertChunksCalculatesMD5
(
$input
,
$expectedMD5
)
{
$stream
=
new
WritableStream
(
$this
->
collectionWrapper
,
'filename'
);
$stream
->
insertChunks
(
$input
);
$stream
->
close
();
$fileDocument
=
$this
->
filesCollection
->
findOne
(
[
'_id'
=>
$stream
->
getId
()],
[
'projection'
=>
[
'md5'
=>
1
,
'_id'
=>
0
]]
);
$this
->
assertSameDocument
([
'md5'
=>
$expectedMD5
],
$fileDocument
);
}
public
function
provideInputDataAndExpectedMD5
()
{
return
[
[
''
,
'd41d8cd98f00b204e9800998ecf8427e'
],
[
'foobar'
,
'3858f62230ac3c915f300c664312c63f'
],
[
str_repeat
(
'foobar'
,
43520
),
'88ff0e5fcb0acb27947d736b5d69cb73'
],
[
str_repeat
(
'foobar'
,
43521
),
'8ff86511c95a06a611842ceb555d8454'
],
[
str_repeat
(
'foobar'
,
87040
),
'45bfa1a9ec36728ee7338d15c5a30c13'
],
[
str_repeat
(
'foobar'
,
87041
),
'95e78f624f8e745bcfd2d11691fa601e'
],
];
}
/**
* @dataProvider provideInputDataAndExpectedMD5
*/
public
function
testUploadFromStreamCalculatesMD5
(
$input
,
$expectedMD5
)
{
$stream
=
new
WritableStream
(
$this
->
collectionWrapper
,
'filename'
);
$stream
->
uploadFromStream
(
$this
->
createStream
(
$input
));
//$stream->close();
$fileDocument
=
$this
->
filesCollection
->
findOne
(
[
'_id'
=>
$stream
->
getId
()],
[
'projection'
=>
[
'md5'
=>
1
,
'_id'
=>
0
]]
);
$this
->
assertSameDocument
([
'md5'
=>
$expectedMD5
],
$fileDocument
);
}
}
tests/GridFS/
Specification/
tests/delete.json
→
tests/GridFS/
spec-
tests/delete.json
View file @
cd9394c2
File moved
tests/GridFS/
Specification/
tests/download.json
→
tests/GridFS/
spec-
tests/download.json
View file @
cd9394c2
File moved
tests/GridFS/
Specification/
tests/download_by_name.json
→
tests/GridFS/
spec-
tests/download_by_name.json
View file @
cd9394c2
File moved
tests/GridFS/
Specification/
tests/upload.json
→
tests/GridFS/
spec-
tests/upload.json
View file @
cd9394c2
File moved
tests/Operation/CreateIndexesFunctionalTest.php
View file @
cd9394c2
...
@@ -165,6 +165,7 @@ class CreateIndexesFunctionalTest extends FunctionalTestCase
...
@@ -165,6 +165,7 @@ class CreateIndexesFunctionalTest extends FunctionalTestCase
* given name is found, it will be passed to the callback, which may perform
* given name is found, it will be passed to the callback, which may perform
* additional assertions.
* additional assertions.
*
*
* @param string $indexName
* @param callable $callback
* @param callable $callback
*/
*/
private
function
assertIndexExists
(
$indexName
,
$callback
=
null
)
private
function
assertIndexExists
(
$indexName
,
$callback
=
null
)
...
@@ -185,7 +186,7 @@ class CreateIndexesFunctionalTest extends FunctionalTestCase
...
@@ -185,7 +186,7 @@ class CreateIndexesFunctionalTest extends FunctionalTestCase
}
}
}
}
$this
->
assertNotNull
(
$foundIndex
,
sprintf
(
'
Found %s index for the collection
'
,
$indexName
));
$this
->
assertNotNull
(
$foundIndex
,
sprintf
(
'
Index %s does not exist
'
,
$indexName
));
if
(
$callback
!==
null
)
{
if
(
$callback
!==
null
)
{
call_user_func
(
$callback
,
$foundIndex
);
call_user_func
(
$callback
,
$foundIndex
);
...
...
tests/Operation/DropCollectionFunctionalTest.php
View file @
cd9394c2
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
namespace
MongoDB\Tests\Operation
;
namespace
MongoDB\Tests\Operation
;
use
MongoDB\Driver\Server
;
use
MongoDB\Operation\DropCollection
;
use
MongoDB\Operation\DropCollection
;
use
MongoDB\Operation\InsertOne
;
use
MongoDB\Operation\InsertOne
;
use
MongoDB\Operation\ListCollections
;
use
MongoDB\Operation\ListCollections
;
...
@@ -20,7 +19,7 @@ class DropCollectionFunctionalTest extends FunctionalTestCase
...
@@ -20,7 +19,7 @@ class DropCollectionFunctionalTest extends FunctionalTestCase
$operation
=
new
DropCollection
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
());
$operation
=
new
DropCollection
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
());
$operation
->
execute
(
$server
);
$operation
->
execute
(
$server
);
$this
->
assertCollectionDoesNotExist
(
$
server
,
$this
->
getDatabaseName
(),
$
this
->
getCollectionName
());
$this
->
assertCollectionDoesNotExist
(
$this
->
getCollectionName
());
}
}
/**
/**
...
@@ -28,26 +27,22 @@ class DropCollectionFunctionalTest extends FunctionalTestCase
...
@@ -28,26 +27,22 @@ class DropCollectionFunctionalTest extends FunctionalTestCase
*/
*/
public
function
testDropNonexistentCollection
()
public
function
testDropNonexistentCollection
()
{
{
$server
=
$this
->
getPrimaryServer
();
$this
->
assertCollectionDoesNotExist
(
$this
->
getCollectionName
());
$this
->
assertCollectionDoesNotExist
(
$server
,
$this
->
getDatabaseName
(),
$this
->
getCollectionName
());
$operation
=
new
DropCollection
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
());
$operation
=
new
DropCollection
(
$this
->
getDatabaseName
(),
$this
->
getCollectionName
());
$operation
->
execute
(
$
server
);
$operation
->
execute
(
$
this
->
getPrimaryServer
()
);
}
}
/**
/**
* Asserts that a collection with the given name does not exist on the
* Asserts that a collection with the given name does not exist on the
* server.
* server.
*
*
* @param Server $server
* @param string $databaseName
* @param string $collectionName
* @param string $collectionName
*/
*/
private
function
assertCollectionDoesNotExist
(
Server
$server
,
$databaseName
,
$collectionName
)
private
function
assertCollectionDoesNotExist
(
$collectionName
)
{
{
$operation
=
new
ListCollections
(
$
databaseName
);
$operation
=
new
ListCollections
(
$
this
->
getDatabaseName
()
);
$collections
=
$operation
->
execute
(
$
server
);
$collections
=
$operation
->
execute
(
$
this
->
getPrimaryServer
()
);
$foundCollection
=
null
;
$foundCollection
=
null
;
...
@@ -58,6 +53,6 @@ class DropCollectionFunctionalTest extends FunctionalTestCase
...
@@ -58,6 +53,6 @@ class DropCollectionFunctionalTest extends FunctionalTestCase
}
}
}
}
$this
->
assertNull
(
$foundCollection
,
sprintf
(
'Collection %s exists
on the server
'
,
$collectionName
));
$this
->
assertNull
(
$foundCollection
,
sprintf
(
'Collection %s exists'
,
$collectionName
));
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment