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
fd53a1a2
Commit
fd53a1a2
authored
Jun 13, 2019
by
Jeremy Mikola
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #615
parents
a4067ff4
1e5a99bf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2305 additions
and
88 deletions
+2305
-88
CommandExpectations.php
tests/SpecTests/CommandExpectations.php
+64
-23
CommandMonitoringSpecTest.php
tests/SpecTests/CommandMonitoringSpecTest.php
+220
-0
Context.php
tests/SpecTests/Context.php
+9
-0
DocumentsMatchConstraint.php
tests/SpecTests/DocumentsMatchConstraint.php
+179
-0
DocumentsMatchConstraintTest.php
tests/SpecTests/DocumentsMatchConstraintTest.php
+53
-0
FunctionalTestCase.php
tests/SpecTests/FunctionalTestCase.php
+28
-1
Operation.php
tests/SpecTests/Operation.php
+29
-4
RetryableWritesSpecTest.php
tests/SpecTests/RetryableWritesSpecTest.php
+6
-1
TransactionsSpecTest.php
tests/SpecTests/TransactionsSpecTest.php
+64
-59
bulkWrite.json
tests/SpecTests/command-monitoring/bulkWrite.json
+110
-0
command.json
tests/SpecTests/command-monitoring/command.json
+113
-0
deleteMany.json
tests/SpecTests/command-monitoring/deleteMany.json
+115
-0
deleteOne.json
tests/SpecTests/command-monitoring/deleteOne.json
+115
-0
find.json
tests/SpecTests/command-monitoring/find.json
+560
-0
insertMany.json
tests/SpecTests/command-monitoring/insertMany.json
+145
-0
insertOne.json
tests/SpecTests/command-monitoring/insertOne.json
+97
-0
unacknowledgedBulkWrite.json
...SpecTests/command-monitoring/unacknowledgedBulkWrite.json
+69
-0
updateMany.json
tests/SpecTests/command-monitoring/updateMany.json
+135
-0
updateOne.json
tests/SpecTests/command-monitoring/updateOne.json
+190
-0
bootstrap.php
tests/bootstrap.php
+4
-0
No files found.
tests/SpecTests/CommandExpectations.php
View file @
fd53a1a2
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
namespace
MongoDB\Tests\SpecTests
;
namespace
MongoDB\Tests\SpecTests
;
use
MongoDB\BSON\Timestamp
;
use
MongoDB\Driver\Monitoring\CommandFailedEvent
;
use
MongoDB\Driver\Monitoring\CommandFailedEvent
;
use
MongoDB\Driver\Monitoring\CommandStartedEvent
;
use
MongoDB\Driver\Monitoring\CommandStartedEvent
;
use
MongoDB\Driver\Monitoring\CommandSucceededEvent
;
use
MongoDB\Driver\Monitoring\CommandSucceededEvent
;
...
@@ -17,20 +16,45 @@ use stdClass;
...
@@ -17,20 +16,45 @@ use stdClass;
*/
*/
class
CommandExpectations
implements
CommandSubscriber
class
CommandExpectations
implements
CommandSubscriber
{
{
private
$commandStartedEvents
=
[];
private
$actualEvents
=
[];
private
$expectedCommandStartedEvents
=
[];
private
$expectedEvents
=
[];
private
$ignoreCommandFailed
=
false
;
private
$ignoreCommandStarted
=
false
;
private
$ignoreCommandSucceeded
=
false
;
p
ublic
static
function
fromTransactions
(
array
$expectedE
vents
)
p
rivate
function
__construct
(
array
$e
vents
)
{
{
$o
=
new
self
;
foreach
(
$events
as
$event
)
{
switch
(
key
(
$event
))
{
foreach
(
$expectedEvents
as
$expectedEvent
)
{
case
'command_failed_event'
:
if
(
!
isset
(
$expectedEvent
->
command_started_event
))
{
$this
->
expectedEvents
[]
=
[
$event
->
command_failed_event
,
CommandFailedEvent
::
class
];
throw
new
LogicException
(
'$expectedEvent->command_started_event field is not set'
);
break
;
case
'command_started_event'
:
$this
->
expectedEvents
[]
=
[
$event
->
command_started_event
,
CommandStartedEvent
::
class
];
break
;
case
'command_succeeded_event'
:
$this
->
expectedEvents
[]
=
[
$event
->
command_succeeded_event
,
CommandSucceededEvent
::
class
];
break
;
default
:
throw
new
LogicException
(
'Unsupported event type: '
.
key
(
$event
));
}
}
$o
->
expectedCommandStartedEvents
[]
=
$expectedEvent
->
command_started_event
;
}
}
}
public
static
function
fromCommandMonitoring
(
array
$expectedEvents
)
{
return
new
self
(
$expectedEvents
);
}
public
static
function
fromTransactions
(
array
$expectedEvents
)
{
$o
=
new
self
(
$expectedEvents
);
$o
->
ignoreCommandFailed
=
true
;
$o
->
ignoreCommandSucceeded
=
true
;
return
$o
;
return
$o
;
}
}
...
@@ -42,6 +66,11 @@ class CommandExpectations implements CommandSubscriber
...
@@ -42,6 +66,11 @@ class CommandExpectations implements CommandSubscriber
*/
*/
public
function
commandFailed
(
CommandFailedEvent
$event
)
public
function
commandFailed
(
CommandFailedEvent
$event
)
{
{
if
(
$this
->
ignoreCommandFailed
)
{
return
;
}
$this
->
actualEvents
[]
=
$event
;
}
}
/**
/**
...
@@ -51,7 +80,11 @@ class CommandExpectations implements CommandSubscriber
...
@@ -51,7 +80,11 @@ class CommandExpectations implements CommandSubscriber
*/
*/
public
function
commandStarted
(
CommandStartedEvent
$event
)
public
function
commandStarted
(
CommandStartedEvent
$event
)
{
{
$this
->
commandStartedEvents
[]
=
$event
;
if
(
$this
->
ignoreCommandStarted
)
{
return
;
}
$this
->
actualEvents
[]
=
$event
;
}
}
/**
/**
...
@@ -61,6 +94,11 @@ class CommandExpectations implements CommandSubscriber
...
@@ -61,6 +94,11 @@ class CommandExpectations implements CommandSubscriber
*/
*/
public
function
commandSucceeded
(
CommandSucceededEvent
$event
)
public
function
commandSucceeded
(
CommandSucceededEvent
$event
)
{
{
if
(
$this
->
ignoreCommandSucceeded
)
{
return
;
}
$this
->
actualEvents
[]
=
$event
;
}
}
/**
/**
...
@@ -87,16 +125,17 @@ class CommandExpectations implements CommandSubscriber
...
@@ -87,16 +125,17 @@ class CommandExpectations implements CommandSubscriber
*/
*/
public
function
assert
(
FunctionalTestCase
$test
,
Context
$context
)
public
function
assert
(
FunctionalTestCase
$test
,
Context
$context
)
{
{
$test
->
assertCount
(
count
(
$this
->
expected
CommandStartedEvents
),
$this
->
commandStarted
Events
);
$test
->
assertCount
(
count
(
$this
->
expected
Events
),
$this
->
actual
Events
);
$mi
=
new
MultipleIterator
(
MultipleIterator
::
MIT_NEED_ANY
);
$mi
=
new
MultipleIterator
(
MultipleIterator
::
MIT_NEED_ANY
);
$mi
->
attachIterator
(
new
ArrayIterator
(
$this
->
expected
CommandStarted
Events
));
$mi
->
attachIterator
(
new
ArrayIterator
(
$this
->
expectedEvents
));
$mi
->
attachIterator
(
new
ArrayIterator
(
$this
->
commandStarted
Events
));
$mi
->
attachIterator
(
new
ArrayIterator
(
$this
->
actual
Events
));
foreach
(
$mi
as
$events
)
{
foreach
(
$mi
as
$events
)
{
list
(
$expectedEvent
,
$actualEvent
)
=
$events
;
list
(
$expectedEventAndClass
,
$actualEvent
)
=
$events
;
$test
->
assertInternalType
(
'object'
,
$expectedEvent
);
list
(
$expectedEvent
,
$expectedClass
)
=
$expectedEventAndClass
;
$test
->
assertInstanceOf
(
CommandStartedEvent
::
class
,
$actualEvent
);
$test
->
assertInstanceOf
(
$expectedClass
,
$actualEvent
);
if
(
isset
(
$expectedEvent
->
command_name
))
{
if
(
isset
(
$expectedEvent
->
command_name
))
{
$test
->
assertSame
(
$expectedEvent
->
command_name
,
$actualEvent
->
getCommandName
());
$test
->
assertSame
(
$expectedEvent
->
command_name
,
$actualEvent
->
getCommandName
());
...
@@ -107,14 +146,16 @@ class CommandExpectations implements CommandSubscriber
...
@@ -107,14 +146,16 @@ class CommandExpectations implements CommandSubscriber
}
}
if
(
isset
(
$expectedEvent
->
command
))
{
if
(
isset
(
$expectedEvent
->
command
))
{
$test
->
assertInstanceOf
(
CommandStartedEvent
::
class
,
$actualEvent
);
$expectedCommand
=
$expectedEvent
->
command
;
$expectedCommand
=
$expectedEvent
->
command
;
$context
->
replaceCommandSessionPlaceholder
(
$expectedCommand
);
$context
->
replaceCommandSessionPlaceholder
(
$expectedCommand
);
$test
->
assert
SameCommand
(
$expectedCommand
,
$actualEvent
->
getCommand
());
$test
->
assert
CommandMatches
(
$expectedCommand
,
$actualEvent
->
getCommand
());
}
}
}
}
private
function
__construct
()
if
(
isset
(
$expectedEvent
->
reply
))
{
{
$test
->
assertInstanceOf
(
CommandSucceededEvent
::
class
,
$actualEvent
);
$test
->
assertCommandReplyMatches
(
$expectedEvent
->
reply
,
$actualEvent
->
getReply
());
}
}
}
}
}
}
tests/SpecTests/CommandMonitoringSpecTest.php
0 → 100644
View file @
fd53a1a2
<?php
namespace
MongoDB\Tests\SpecTests
;
use
stdClass
;
/**
* Command monitoring spec tests.
*
* @see https://github.com/mongodb/specifications/tree/master/source/command-monitoring
*/
class
CommandMonitoringSpecTest
extends
FunctionalTestCase
{
/**
* Assert that the expected and actual command documents match.
*
* Note: this method may modify the $expected object.
*
* @param stdClass $expected Expected command document
* @param stdClass $actual Actual command document
*/
public
static
function
assertCommandMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
if
(
isset
(
$expected
->
getMore
)
&&
$expected
->
getMore
===
42
)
{
static
::
assertObjectHasAttribute
(
'getMore'
,
$actual
);
static
::
assertThat
(
$actual
->
getMore
,
static
::
logicalOr
(
static
::
isInstanceOf
(
Int64
::
class
),
static
::
isType
(
'integer'
)
));
unset
(
$expected
->
getMore
);
}
if
(
isset
(
$expected
->
killCursors
)
&&
isset
(
$expected
->
cursors
)
&&
is_array
(
$expected
->
cursors
))
{
static
::
assertObjectHasAttribute
(
'cursors'
,
$actual
);
static
::
assertInternalType
(
'array'
,
$actual
->
cursors
);
foreach
(
$expected
->
cursors
as
$i
=>
$cursorId
)
{
static
::
assertArrayHasKey
(
$i
,
$actual
->
cursors
);
if
(
$cursorId
===
42
)
{
static
::
assertThat
(
$actual
->
cursors
[
$i
],
static
::
logicalOr
(
static
::
isInstanceOf
(
Int64
::
class
),
static
::
isType
(
'integer'
)
));
}
}
unset
(
$expected
->
cursors
);
}
static
::
assertDocumentsMatch
(
$expected
,
$actual
);
}
/**
* Assert that the expected and actual command reply documents match.
*
* Note: this method may modify the $expectedReply object.
*
* @param stdClass $expected Expected command reply document
* @param stdClass $actual Actual command reply document
*/
public
static
function
assertCommandReplyMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
if
(
isset
(
$expected
->
cursor
->
id
)
&&
$expected
->
cursor
->
id
===
42
)
{
static
::
assertObjectHasAttribute
(
'cursor'
,
$actual
);
static
::
assertInternalType
(
'object'
,
$actual
->
cursor
);
static
::
assertObjectHasAttribute
(
'id'
,
$actual
->
cursor
);
static
::
assertThat
(
$actual
->
cursor
->
id
,
static
::
logicalOr
(
static
::
isInstanceOf
(
Int64
::
class
),
static
::
isType
(
'integer'
)
));
unset
(
$expected
->
cursor
->
id
);
}
if
(
isset
(
$expected
->
cursorsUnknown
)
&&
is_array
(
$expected
->
cursorsUnknown
))
{
static
::
assertObjectHasAttribute
(
'cursorsUnknown'
,
$actual
);
static
::
assertInternalType
(
'array'
,
$actual
->
cursorsUnknown
);
foreach
(
$expected
->
cursorsUnknown
as
$i
=>
$cursorId
)
{
static
::
assertArrayHasKey
(
$i
,
$actual
->
cursorsUnknown
);
if
(
$cursorId
===
42
)
{
static
::
assertThat
(
$actual
->
cursorsUnknown
[
$i
],
static
::
logicalOr
(
static
::
isInstanceOf
(
Int64
::
class
),
static
::
isType
(
'integer'
)
));
}
}
unset
(
$expected
->
cursorsUnknown
);
}
if
(
isset
(
$expected
->
ok
)
&&
is_numeric
(
$expected
->
ok
))
{
static
::
assertObjectHasAttribute
(
'ok'
,
$actual
);
static
::
assertInternalType
(
'numeric'
,
$actual
->
ok
);
static
::
assertEquals
(
$expected
->
ok
,
$actual
->
ok
);
unset
(
$expected
->
ok
);
}
if
(
isset
(
$expected
->
writeErrors
)
&&
is_array
(
$expected
->
writeErrors
))
{
static
::
assertObjectHasAttribute
(
'writeErrors'
,
$actual
);
static
::
assertInternalType
(
'array'
,
$actual
->
writeErrors
);
foreach
(
$expected
->
writeErrors
as
$i
=>
$expectedWriteError
)
{
static
::
assertArrayHasKey
(
$i
,
$actual
->
writeErrors
);
$actualWriteError
=
$actual
->
writeErrors
[
$i
];
if
(
isset
(
$expectedWriteError
->
code
)
&&
$expectedWriteError
->
code
===
42
)
{
static
::
assertObjectHasAttribute
(
'code'
,
$actualWriteError
);
static
::
assertThat
(
$actualWriteError
->
code
,
static
::
logicalOr
(
static
::
isInstanceOf
(
Int64
::
class
),
static
::
isType
(
'integer'
)
));
unset
(
$expected
->
writeErrors
[
$i
]
->
code
);
}
if
(
isset
(
$expectedWriteError
->
errmsg
)
&&
$expectedWriteError
->
errmsg
===
''
)
{
static
::
assertObjectHasAttribute
(
'errmsg'
,
$actualWriteError
);
static
::
assertInternalType
(
'string'
,
$actualWriteError
->
errmsg
);
static
::
assertNotEmpty
(
$actualWriteError
->
errmsg
);
unset
(
$expected
->
writeErrors
[
$i
]
->
errmsg
);
}
}
}
static
::
assertDocumentsMatch
(
$expected
,
$actual
);
}
/**
* Execute an individual test case from the specification.
*
* @dataProvider provideTests
* @param string $name Test name
* @param stdClass $test Individual "tests[]" document
* @param array $data Top-level "data" array to initialize collection
* @param string $databaseName Name of database under test
* @param string $collectionName Name of collection under test
*/
public
function
testCommandMonitoring
(
$name
,
stdClass
$test
,
array
$data
,
$databaseName
=
null
,
$collectionName
=
null
)
{
$this
->
setName
(
$name
);
$this
->
checkServerRequirements
(
$this
->
createRunOn
(
$test
));
$databaseName
=
isset
(
$databaseName
)
?
$databaseName
:
$this
->
getDatabaseName
();
$collectionName
=
isset
(
$collectionName
)
?
$collectionName
:
$this
->
getCollectionName
();
$context
=
Context
::
fromCommandMonitoring
(
$test
,
$databaseName
,
$collectionName
);
$this
->
setContext
(
$context
);
$this
->
dropTestAndOutcomeCollections
();
$this
->
insertDataFixtures
(
$data
);
if
(
isset
(
$test
->
expectations
))
{
$commandExpectations
=
CommandExpectations
::
fromCommandMonitoring
(
$test
->
expectations
);
$commandExpectations
->
startMonitoring
();
}
Operation
::
fromCommandMonitoring
(
$test
->
operation
)
->
assert
(
$this
,
$context
);
if
(
isset
(
$commandExpectations
))
{
$commandExpectations
->
stopMonitoring
();
$commandExpectations
->
assert
(
$this
,
$context
);
}
}
public
function
provideTests
()
{
$testArgs
=
[];
foreach
(
glob
(
__DIR__
.
'/command-monitoring/*.json'
)
as
$filename
)
{
$json
=
$this
->
decodeJson
(
file_get_contents
(
$filename
));
$group
=
basename
(
$filename
,
'.json'
);
$data
=
isset
(
$json
->
data
)
?
$json
->
data
:
[];
$databaseName
=
isset
(
$json
->
database_name
)
?
$json
->
database_name
:
null
;
$collectionName
=
isset
(
$json
->
collection_name
)
?
$json
->
collection_name
:
null
;
foreach
(
$json
->
tests
as
$test
)
{
$name
=
$group
.
': '
.
$test
->
description
;
$testArgs
[]
=
[
$name
,
$test
,
$data
,
$databaseName
,
$collectionName
];
}
}
return
$testArgs
;
}
/**
* Convert the server and topology requirements to a standard "runOn" array
* used by other specifications.
*
* @param stdClass $test
* @return array
*/
private
function
createRunOn
(
stdClass
$test
)
{
$req
=
new
stdClass
;
$topologies
=
[
self
::
TOPOLOGY_SINGLE
,
self
::
TOPOLOGY_REPLICASET
,
self
::
TOPOLOGY_SHARDED
];
/* Append ".99" as patch version, since command monitoring tests expect
* the minor version to be an inclusive upper bound. */
if
(
isset
(
$test
->
ignore_if_server_version_greater_than
))
{
$req
->
maxServerVersion
=
$test
->
ignore_if_server_version_greater_than
.
'.99'
;
}
if
(
isset
(
$test
->
ignore_if_server_version_less_than
))
{
$req
->
minServerVersion
=
$test
->
ignore_if_server_version_less_than
;
}
if
(
isset
(
$test
->
ignore_if_topology_type
))
{
$req
->
topology
=
array_diff
(
$topologies
,
$test
->
ignore_if_topology_type
);
}
return
[
$req
];
}
}
tests/SpecTests/Context.php
View file @
fd53a1a2
...
@@ -35,6 +35,15 @@ final class Context
...
@@ -35,6 +35,15 @@ final class Context
$this
->
outcomeCollectionName
=
$collectionName
;
$this
->
outcomeCollectionName
=
$collectionName
;
}
}
public
static
function
fromCommandMonitoring
(
stdClass
$test
,
$databaseName
,
$collectionName
)
{
$o
=
new
self
(
$databaseName
,
$collectionName
);
$o
->
client
=
new
Client
(
FunctionalTestCase
::
getUri
());
return
$o
;
}
public
static
function
fromRetryableWrites
(
stdClass
$test
,
$databaseName
,
$collectionName
)
public
static
function
fromRetryableWrites
(
stdClass
$test
,
$databaseName
,
$collectionName
)
{
{
$o
=
new
self
(
$databaseName
,
$collectionName
);
$o
=
new
self
(
$databaseName
,
$collectionName
);
...
...
tests/SpecTests/DocumentsMatchConstraint.php
0 → 100644
View file @
fd53a1a2
<?php
namespace
MongoDB\Tests\SpecTests
;
use
MongoDB\Model\BSONArray
;
use
MongoDB\Model\BSONDocument
;
use
PHPUnit\Framework\Constraint\Constraint
;
use
ArrayObject
;
use
InvalidArgumentException
;
use
RuntimeException
;
use
stdClass
;
/**
* Constraint that checks if one document matches another.
*
* The expected value is passed in the constructor.
*/
class
DocumentsMatchConstraint
extends
Constraint
{
private
$ignoreExtraKeysInRoot
=
false
;
private
$ignoreExtraKeysInEmbedded
=
false
;
/* TODO: This is not currently used, but was preserved from the design of
* TestCase::assertMatchesDocument(), which would sort keys and then compare
* documents as JSON strings. If the TODO item in matches() is implemented
* to make document comparisons more efficient, we may consider supporting
* this option. */
private
$sortKeys
=
false
;
private
$value
;
/**
* Creates a new constraint.
*
* @param array|object $value
* @param boolean $ignoreExtraKeysInRoot If true, ignore extra keys within the root document
* @param boolean $ignoreExtraKeysInEmbedded If true, ignore extra keys within embedded documents
*
*/
public
function
__construct
(
$value
,
$ignoreExtraKeysInRoot
=
false
,
$ignoreExtraKeysInEmbedded
=
false
)
{
parent
::
__construct
();
$this
->
value
=
$this
->
prepareBSON
(
$value
,
true
,
$this
->
sortKeys
);
$this
->
ignoreExtraKeysInRoot
=
$ignoreExtraKeysInRoot
;
$this
->
ignoreExtraKeysInEmbedded
=
$ignoreExtraKeysInEmbedded
;
}
/**
* Returns a string representation of the constraint.
*
* @return string
*/
public
function
toString
()
{
return
'matches '
.
json_encode
(
$this
->
value
);
}
/**
* Evaluates the constraint for parameter $other. Returns true if the
* constraint is met, false otherwise.
*
* @param mixed $other
* @return boolean
*/
protected
function
matches
(
$other
)
{
/* TODO: If ignoreExtraKeys and sortKeys are both false, then we may be
* able to skip preparation, convert both documents to extended JSON,
* and compare strings.
*
* If ignoreExtraKeys is false and sortKeys is true, we still be able to
* compare JSON strings but will still require preparation to sort keys
* in all documents and sub-documents. */
$other
=
$this
->
prepareBSON
(
$other
,
true
,
$this
->
sortKeys
);
try
{
$this
->
assertEquals
(
$this
->
value
,
$other
,
$this
->
ignoreExtraKeysInRoot
);
}
catch
(
RuntimeException
$e
)
{
return
false
;
}
return
true
;
}
/**
* Compares two documents recursively.
*
* @param ArrayObject $expected
* @param ArrayObject $actual
* @param boolean $ignoreExtraKeys
* @throws RuntimeException if the documents do not match
*/
private
function
assertEquals
(
ArrayObject
$expected
,
ArrayObject
$actual
,
$ignoreExtraKeys
)
{
if
(
get_class
(
$expected
)
!==
get_class
(
$actual
))
{
throw
new
RuntimeException
(
sprintf
(
'$expected is %s but $actual is %s'
,
get_class
(
$expected
),
get_class
(
$actual
)));
}
foreach
(
$expected
as
$key
=>
$expectedValue
)
{
$actualHasKey
=
$actual
->
offsetExists
(
$key
);
if
(
!
$actualHasKey
)
{
throw
new
RuntimeException
(
'$actual is missing key: '
.
$key
);
}
$actualValue
=
$actual
[
$key
];
if
((
$expectedValue
instanceof
BSONArray
&&
$actualValue
instanceof
BSONArray
)
||
(
$expectedValue
instanceof
BSONDocument
&&
$actualValue
instanceof
BSONDocument
))
{
$this
->
assertEquals
(
$expectedValue
,
$actualValue
,
$this
->
ignoreExtraKeysInEmbedded
);
continue
;
}
if
(
gettype
(
$expectedValue
)
!=
gettype
(
$actualValue
)
||
$expectedValue
!=
$actualValue
)
{
throw
new
RuntimeException
(
'$expectedValue != $actualValue for key: '
.
$key
);
}
}
if
(
$ignoreExtraKeys
)
{
return
;
}
foreach
(
$actual
as
$key
=>
$value
)
{
if
(
!
$expected
->
offsetExists
(
$key
))
{
throw
new
RuntimeException
(
'$actual has extra key: '
.
$key
);
}
}
}
/**
* Prepare a BSON document or array for comparison.
*
* The argument will be converted to a BSONArray or BSONDocument based on
* its type and keys. Keys within documents will optionally be sorted. Each
* value within the array or document will then be prepared recursively.
*
* @param array|object $bson
* @param boolean $isRoot If true, ensure an array value is converted to a document
* @param boolean $sortKeys
* @return BSONDocument|BSONArray
* @throws InvalidArgumentException if $bson is not an array or object
*/
private
function
prepareBSON
(
$bson
,
$isRoot
,
$sortKeys
=
false
)
{
if
(
!
is_array
(
$bson
)
&&
!
is_object
(
$bson
))
{
throw
new
InvalidArgumentException
(
'$bson is not an array or object'
);
}
if
(
$isRoot
&&
is_array
(
$bson
))
{
$bson
=
(
object
)
$bson
;
}
if
(
$bson
instanceof
BSONArray
||
(
is_array
(
$bson
)
&&
$bson
===
array_values
(
$bson
)))
{
if
(
!
$bson
instanceof
BSONArray
)
{
$bson
=
new
BSONArray
(
$bson
);
}
}
else
{
if
(
!
$bson
instanceof
BSONDocument
)
{
$bson
=
new
BSONDocument
((
array
)
$bson
);
}
if
(
$sortKeys
)
{
$bson
->
ksort
();
}
}
foreach
(
$bson
as
$key
=>
$value
)
{
if
(
$value
instanceof
BSONArray
||
(
is_array
(
$value
)
&&
$value
===
array_values
(
$value
)))
{
$bson
[
$key
]
=
$this
->
prepareBSON
(
$value
,
false
,
$sortKeys
);
continue
;
}
if
(
$value
instanceof
BSONDocument
||
$value
instanceof
stdClass
||
is_array
(
$value
))
{
$bson
[
$key
]
=
$this
->
prepareBSON
(
$value
,
false
,
$sortKeys
);
continue
;
}
}
return
$bson
;
}
}
tests/SpecTests/DocumentsMatchConstraintTest.php
0 → 100644
View file @
fd53a1a2
<?php
namespace
MongoDB\Tests\SpecTests
;
use
PHPUnit\Framework\TestCase
;
class
DocumentsMatchConstraintTest
extends
TestCase
{
public
function
testIgnoreExtraKeysInRoot
()
{
$c
=
new
DocumentsMatchConstraint
([
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
]],
true
,
false
);
$this
->
assertResult
(
false
,
$c
,
[
'x'
=>
1
,
'y'
=>
2
],
'Incorrect value'
);
$this
->
assertResult
(
true
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
]],
'Exact match'
);
$this
->
assertResult
(
true
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
],
'z'
=>
3
],
'Extra keys in root are permitted'
);
$this
->
assertResult
(
false
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
,
'c'
=>
3
]],
'Extra keys in embedded are not permitted'
);
$this
->
assertResult
(
true
,
$c
,
[
'y'
=>
[
'b'
=>
2
,
'a'
=>
1
],
'x'
=>
1
],
'Root and embedded key order is not significant'
);
// Arrays are always intepretted as root documents
$c
=
new
DocumentsMatchConstraint
([
1
,
[
'a'
=>
1
]],
true
,
false
);
$this
->
assertResult
(
false
,
$c
,
[
1
,
2
],
'Incorrect value'
);
$this
->
assertResult
(
true
,
$c
,
[
1
,
[
'a'
=>
1
]],
'Exact match'
);
$this
->
assertResult
(
true
,
$c
,
[
1
,
[
'a'
=>
1
],
3
],
'Extra keys in root are permitted'
);
$this
->
assertResult
(
false
,
$c
,
[
1
,
[
'a'
=>
1
,
'b'
=>
2
]],
'Extra keys in embedded are not permitted'
);
}
public
function
testIgnoreExtraKeysInEmbedded
()
{
$c
=
new
DocumentsMatchConstraint
([
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
]],
false
,
true
);
$this
->
assertResult
(
false
,
$c
,
[
'x'
=>
1
,
'y'
=>
2
],
'Incorrect value'
);
$this
->
assertResult
(
false
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
3
]],
'Incorrect value'
);
$this
->
assertResult
(
true
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
]],
'Exact match'
);
$this
->
assertResult
(
false
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
],
'z'
=>
3
],
'Extra keys in root are not permitted'
);
$this
->
assertResult
(
true
,
$c
,
[
'x'
=>
1
,
'y'
=>
[
'a'
=>
1
,
'b'
=>
2
,
'c'
=>
3
]],
'Extra keys in embedded are permitted'
);
$this
->
assertResult
(
true
,
$c
,
[
'y'
=>
[
'b'
=>
2
,
'a'
=>
1
],
'x'
=>
1
],
'Root and embedded Key order is not significant'
);
// Arrays are always intepretted as root documents
$c
=
new
DocumentsMatchConstraint
([
1
,
[
'a'
=>
1
]],
false
,
true
);
$this
->
assertResult
(
false
,
$c
,
[
1
,
2
],
'Incorrect value'
);
$this
->
assertResult
(
true
,
$c
,
[
1
,
[
'a'
=>
1
]],
'Exact match'
);
$this
->
assertResult
(
false
,
$c
,
[
1
,
[
'a'
=>
1
],
3
],
'Extra keys in root are not permitted'
);
$this
->
assertResult
(
true
,
$c
,
[
1
,
[
'a'
=>
1
,
'b'
=>
2
]],
'Extra keys in embedded are permitted'
);
$this
->
assertResult
(
false
,
$c
,
[
1
,
[
'a'
=>
2
]],
'Keys must have the correct value'
);
}
private
function
assertResult
(
$expectedResult
,
DocumentsMatchConstraint
$constraint
,
$value
,
$message
)
{
$this
->
assertSame
(
$expectedResult
,
$constraint
->
evaluate
(
$value
,
''
,
true
),
$message
);
}
}
tests/SpecTests/FunctionalTestCase.php
View file @
fd53a1a2
...
@@ -60,7 +60,34 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase
...
@@ -60,7 +60,34 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase
* @param stdClass $expectedCommand Expected command document
* @param stdClass $expectedCommand Expected command document
* @param stdClass $actualCommand Actual command document
* @param stdClass $actualCommand Actual command document
*/
*/
abstract
public
function
assertSameCommand
(
stdClass
$expectedCommand
,
stdClass
$actualCommand
);
abstract
public
static
function
assertCommandMatches
(
stdClass
$expected
,
stdClass
$actual
);
/**
* Assert that the expected and actual command reply documents match.
*
* Note: Spec tests that do not assert command started events may throw an
* exception in lieu of implementing this method.
*
* @param stdClass $expected Expected command reply document
* @param stdClass $actual Actual command reply document
*/
abstract
public
static
function
assertCommandReplyMatches
(
stdClass
$expected
,
stdClass
$actual
);
/**
* Asserts that two given documents match.
*
* Extra keys in the actual value's document(s) will be ignored.
*
* @param array|object $expectedDocument
* @param array|object $actualDocument
* @param string $message
*/
protected
static
function
assertDocumentsMatch
(
$expectedDocument
,
$actualDocument
,
$message
=
''
)
{
$constraint
=
new
DocumentsMatchConstraint
(
$expectedDocument
,
true
,
true
);
static
::
assertThat
(
$actualDocument
,
$constraint
,
$message
);
}
/**
/**
* Assert data within the outcome collection.
* Assert data within the outcome collection.
...
...
tests/SpecTests/Operation.php
View file @
fd53a1a2
...
@@ -3,11 +3,12 @@
...
@@ -3,11 +3,12 @@
namespace
MongoDB\Tests\SpecTests
;
namespace
MongoDB\Tests\SpecTests
;
use
MongoDB\Collection
;
use
MongoDB\Collection
;
use
MongoDB\Operation\FindOneAndReplace
;
use
MongoDB\Driver\Cursor
;
use
MongoDB\Operation\FindOneAndUpdate
;
use
MongoDB\Driver\Session
;
use
MongoDB\Driver\Session
;
use
MongoDB\Driver\Exception\BulkWriteException
;
use
MongoDB\Driver\Exception\BulkWriteException
;
use
MongoDB\Driver\Exception\Exception
;
use
MongoDB\Driver\Exception\Exception
;
use
MongoDB\Operation\FindOneAndReplace
;
use
MongoDB\Operation\FindOneAndUpdate
;
use
LogicException
;
use
LogicException
;
use
stdClass
;
use
stdClass
;
...
@@ -43,6 +44,17 @@ final class Operation
...
@@ -43,6 +44,17 @@ final class Operation
}
}
}
}
public
static
function
fromCommandMonitoring
(
stdClass
$operation
)
{
$o
=
new
self
(
$operation
);
if
(
isset
(
$operation
->
collectionOptions
))
{
$o
->
collectionOptions
=
(
array
)
$operation
->
collectionOptions
;
}
return
$o
;
}
public
static
function
fromRetryableWrites
(
stdClass
$operation
,
stdClass
$outcome
)
public
static
function
fromRetryableWrites
(
stdClass
$operation
,
stdClass
$outcome
)
{
{
$o
=
new
self
(
$operation
);
$o
=
new
self
(
$operation
);
...
@@ -84,6 +96,14 @@ final class Operation
...
@@ -84,6 +96,14 @@ final class Operation
try
{
try
{
$result
=
$this
->
execute
(
$context
);
$result
=
$this
->
execute
(
$context
);
/* Eagerly iterate the results of a cursor. This both allows an
* exception to be thrown sooner and ensures that any expected
* getMore command(s) can be observed even if a ResultExpectation
* is not used (e.g. Command Monitoring spec). */
if
(
$result
instanceof
Cursor
)
{
$result
=
$result
->
toArray
();
}
}
catch
(
Exception
$e
)
{
}
catch
(
Exception
$e
)
{
$exception
=
$e
;
$exception
=
$e
;
}
}
...
@@ -93,8 +113,13 @@ final class Operation
...
@@ -93,8 +113,13 @@ final class Operation
$result
=
$exception
->
getWriteResult
();
$result
=
$exception
->
getWriteResult
();
}
}
$this
->
errorExpectation
->
assert
(
$test
,
$exception
);
if
(
isset
(
$this
->
errorExpectation
))
{
$this
->
resultExpectation
->
assert
(
$test
,
$result
);
$this
->
errorExpectation
->
assert
(
$test
,
$exception
);
}
if
(
isset
(
$this
->
resultExpectation
))
{
$this
->
resultExpectation
->
assert
(
$test
,
$result
);
}
}
}
/**
/**
...
...
tests/SpecTests/RetryableWritesSpecTest.php
View file @
fd53a1a2
...
@@ -12,11 +12,16 @@ use stdClass;
...
@@ -12,11 +12,16 @@ use stdClass;
*/
*/
class
RetryableWritesSpecTest
extends
FunctionalTestCase
class
RetryableWritesSpecTest
extends
FunctionalTestCase
{
{
public
function
assertSameCommand
(
stdClass
$expectedCommand
,
stdClass
$actualCommand
)
public
static
function
assertCommandMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
{
throw
new
LogicException
(
'Retryable writes spec tests do not assert CommandStartedEvents'
);
throw
new
LogicException
(
'Retryable writes spec tests do not assert CommandStartedEvents'
);
}
}
public
static
function
assertCommandReplyMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
throw
new
LogicException
(
'Retryable writes spec tests do not assert CommandSucceededEvents'
);
}
/**
/**
* Execute an individual test case from the specification.
* Execute an individual test case from the specification.
*
*
...
...
tests/SpecTests/TransactionsSpecTest.php
View file @
fd53a1a2
...
@@ -56,89 +56,62 @@ class TransactionsSpecTest extends FunctionalTestCase
...
@@ -56,89 +56,62 @@ class TransactionsSpecTest extends FunctionalTestCase
parent
::
tearDown
();
parent
::
tearDown
();
}
}
/**
* Kill all sessions on the cluster.
*
* This will clean up any open transactions that may remain from a
* previously failed test. For sharded clusters, this command will be run
* on all mongos nodes.
*/
private
static
function
killAllSessions
()
{
$manager
=
new
Manager
(
static
::
getUri
());
$primary
=
$manager
->
selectServer
(
new
ReadPreference
(
'primary'
));
$servers
=
(
$primary
->
getType
()
===
Server
::
TYPE_MONGOS
)
?
$manager
->
getServers
()
:
[
$primary
];
foreach
(
$servers
as
$server
)
{
try
{
// Skip servers that do not support sessions
if
(
!
isset
(
$server
->
getInfo
()[
'logicalSessionTimeoutMinutes'
]))
{
continue
;
}
$server
->
executeCommand
(
'admin'
,
new
Command
([
'killAllSessions'
=>
[]]));
}
catch
(
ServerException
$e
)
{
// Interrupted error is safe to ignore (see: SERVER-38335)
if
(
$e
->
getCode
()
!=
self
::
INTERRUPTED
)
{
throw
$e
;
}
}
}
}
/**
/**
* Assert that the expected and actual command documents match.
* Assert that the expected and actual command documents match.
*
*
* Note: this method may modify the $expected
Command
object.
* Note: this method may modify the $expected object.
*
*
* @param stdClass $expected
Command
Expected command document
* @param stdClass $expected Expected command document
* @param stdClass $actual
Command
Actual command document
* @param stdClass $actual Actual command document
*/
*/
public
function
assertSameCommand
(
stdClass
$expectedCommand
,
stdClass
$actualCommand
)
public
static
function
assertCommandMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
{
if
(
isset
(
$expected
Command
->
getMore
)
&&
$expectedComman
d
->
getMore
===
42
)
{
if
(
isset
(
$expected
->
getMore
)
&&
$expecte
d
->
getMore
===
42
)
{
$this
->
assertObjectHasAttribute
(
'getMore'
,
$actualCommand
);
static
::
assertObjectHasAttribute
(
'getMore'
,
$actual
);
$this
->
assertThat
(
$actualCommand
->
getMore
,
$this
->
logicalOr
(
static
::
assertThat
(
$actual
->
getMore
,
static
::
logicalOr
(
$this
->
isInstanceOf
(
Int64
::
class
),
static
::
isInstanceOf
(
Int64
::
class
),
$this
->
isType
(
'integer'
)
static
::
isType
(
'integer'
)
));
));
unset
(
$expected
Command
->
getMore
);
unset
(
$expected
->
getMore
);
}
}
if
(
isset
(
$expected
Command
->
recoveryToken
)
&&
$expectedComman
d
->
recoveryToken
===
42
)
{
if
(
isset
(
$expected
->
recoveryToken
)
&&
$expecte
d
->
recoveryToken
===
42
)
{
$this
->
assertObjectHasAttribute
(
'recoveryToken'
,
$actualCommand
);
static
::
assertObjectHasAttribute
(
'recoveryToken'
,
$actual
);
$this
->
assertInternalType
(
'object'
,
$actualCommand
->
recoveryToken
);
static
::
assertInternalType
(
'object'
,
$actual
->
recoveryToken
);
unset
(
$expected
Command
->
recoveryToken
);
unset
(
$expected
->
recoveryToken
);
}
}
if
(
isset
(
$expected
Command
->
readConcern
->
afterClusterTime
)
&&
$expectedComman
d
->
readConcern
->
afterClusterTime
===
42
)
{
if
(
isset
(
$expected
->
readConcern
->
afterClusterTime
)
&&
$expecte
d
->
readConcern
->
afterClusterTime
===
42
)
{
$this
->
assertObjectHasAttribute
(
'readConcern'
,
$actualCommand
);
static
::
assertObjectHasAttribute
(
'readConcern'
,
$actual
);
$this
->
assertInternalType
(
'object'
,
$actualCommand
->
readConcern
);
static
::
assertInternalType
(
'object'
,
$actual
->
readConcern
);
$this
->
assertObjectHasAttribute
(
'afterClusterTime'
,
$actualCommand
->
readConcern
);
static
::
assertObjectHasAttribute
(
'afterClusterTime'
,
$actual
->
readConcern
);
$this
->
assertInstanceOf
(
Timestamp
::
class
,
$actualCommand
->
readConcern
->
afterClusterTime
);
static
::
assertInstanceOf
(
Timestamp
::
class
,
$actual
->
readConcern
->
afterClusterTime
);
unset
(
$expected
Command
->
readConcern
->
afterClusterTime
);
unset
(
$expected
->
readConcern
->
afterClusterTime
);
/* If "afterClusterTime" was the only assertion for "readConcern",
/* If "afterClusterTime" was the only assertion for "readConcern",
* unset the field to avoid expecting an empty document later. */
* unset the field to avoid expecting an empty document later. */
if
(
get_object_vars
(
$expected
Command
->
readConcern
)
===
[])
{
if
(
get_object_vars
(
$expected
->
readConcern
)
===
[])
{
unset
(
$expected
Command
->
readConcern
);
unset
(
$expected
->
readConcern
);
}
}
}
}
/* TODO: Determine if forcing a new libmongoc client in Context is
/* TODO: Determine if forcing a new libmongoc client in Context is
* preferable to skipping the txnNumber assertion. */
* preferable to skipping the txnNumber assertion. */
//unset($expected
Command
['txnNumber']);
//unset($expected['txnNumber']);
foreach
(
$expected
Command
as
$key
=>
$value
)
{
foreach
(
$expected
as
$key
=>
$value
)
{
if
(
$value
===
null
)
{
if
(
$value
===
null
)
{
$this
->
assertObjectNotHasAttribute
(
$key
,
$actualCommand
);
static
::
assertObjectNotHasAttribute
(
$key
,
$actual
);
unset
(
$expected
Command
->
{
$key
});
unset
(
$expected
->
{
$key
});
}
}
}
}
$this
->
assertMatchesDocument
(
$expectedCommand
,
$actualCommand
);
static
::
assertDocumentsMatch
(
$expected
,
$actual
);
}
public
static
function
assertCommandReplyMatches
(
stdClass
$expected
,
stdClass
$actual
)
{
throw
new
LogicException
(
'Transactions spec tests do not assert CommandSucceededEvents'
);
}
}
/**
/**
...
@@ -242,6 +215,38 @@ class TransactionsSpecTest extends FunctionalTestCase
...
@@ -242,6 +215,38 @@ class TransactionsSpecTest extends FunctionalTestCase
$database
->
createCollection
(
$context
->
collectionName
,
$context
->
defaultWriteOptions
);
$database
->
createCollection
(
$context
->
collectionName
,
$context
->
defaultWriteOptions
);
}
}
/**
* Kill all sessions on the cluster.
*
* This will clean up any open transactions that may remain from a
* previously failed test. For sharded clusters, this command will be run
* on all mongos nodes.
*/
private
static
function
killAllSessions
()
{
$manager
=
new
Manager
(
static
::
getUri
());
$primary
=
$manager
->
selectServer
(
new
ReadPreference
(
'primary'
));
$servers
=
(
$primary
->
getType
()
===
Server
::
TYPE_MONGOS
)
?
$manager
->
getServers
()
:
[
$primary
];
foreach
(
$servers
as
$server
)
{
try
{
// Skip servers that do not support sessions
if
(
!
isset
(
$server
->
getInfo
()[
'logicalSessionTimeoutMinutes'
]))
{
continue
;
}
$server
->
executeCommand
(
'admin'
,
new
Command
([
'killAllSessions'
=>
[]]));
}
catch
(
ServerException
$e
)
{
// Interrupted error is safe to ignore (see: SERVER-38335)
if
(
$e
->
getCode
()
!=
self
::
INTERRUPTED
)
{
throw
$e
;
}
}
}
}
/**
/**
* Work around potential error executing distinct on sharded clusters.
* Work around potential error executing distinct on sharded clusters.
*
*
...
...
tests/SpecTests/command-monitoring/bulkWrite.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful mixed bulk write"
,
"operation"
:
{
"name"
:
"bulkWrite"
,
"arguments"
:
{
"requests"
:
[
{
"name"
:
"insertOne"
,
"arguments"
:
{
"document"
:
{
"_id"
:
4
,
"x"
:
44
}
}
},
{
"name"
:
"updateOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
3
},
"update"
:
{
"$set"
:
{
"x"
:
333
}
}
}
}
]
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test"
,
"documents"
:
[
{
"_id"
:
4
,
"x"
:
44
}
],
"ordered"
:
true
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"insert"
}
},
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"updates"
:
[
{
"q"
:
{
"_id"
:
3
},
"u"
:
{
"$set"
:
{
"x"
:
333
}
}
}
],
"ordered"
:
true
},
"command_name"
:
"update"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"update"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/command.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful command"
,
"operation"
:
{
"name"
:
"count"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
1
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"count"
:
"test"
,
"query"
:
{
"_id"
:
1
}
},
"command_name"
:
"count"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"count"
}
}
]
},
{
"description"
:
"A failed command event"
,
"operation"
:
{
"name"
:
"count"
,
"arguments"
:
{
"filter"
:
{
"$or"
:
true
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"count"
:
"test"
,
"query"
:
{
"$or"
:
true
}
},
"command_name"
:
"count"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_failed_event"
:
{
"command_name"
:
"count"
}
}
]
},
{
"description"
:
"A successful command with a non-primary read preference"
,
"operation"
:
{
"name"
:
"count"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
1
}
},
"read_preference"
:
{
"mode"
:
"primaryPreferred"
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"count"
:
"test"
,
"query"
:
{
"_id"
:
1
}
},
"command_name"
:
"count"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"count"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/deleteMany.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful delete many"
,
"operation"
:
{
"name"
:
"deleteMany"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$gt"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"delete"
:
"test"
,
"deletes"
:
[
{
"q"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"limit"
:
0
}
],
"ordered"
:
true
},
"command_name"
:
"delete"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
2
},
"command_name"
:
"delete"
}
}
]
},
{
"description"
:
"A successful delete many command with write errors"
,
"operation"
:
{
"name"
:
"deleteMany"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$nothing"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"delete"
:
"test"
,
"deletes"
:
[
{
"q"
:
{
"_id"
:
{
"$nothing"
:
1
}
},
"limit"
:
0
}
],
"ordered"
:
true
},
"command_name"
:
"delete"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
0
,
"writeErrors"
:
[
{
"index"
:
0
,
"code"
:
42
,
"errmsg"
:
""
}
]
},
"command_name"
:
"delete"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/deleteOne.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful delete one"
,
"operation"
:
{
"name"
:
"deleteOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$gt"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"delete"
:
"test"
,
"deletes"
:
[
{
"q"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"limit"
:
1
}
],
"ordered"
:
true
},
"command_name"
:
"delete"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"delete"
}
}
]
},
{
"description"
:
"A successful delete one command with write errors"
,
"operation"
:
{
"name"
:
"deleteOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$nothing"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"delete"
:
"test"
,
"deletes"
:
[
{
"q"
:
{
"_id"
:
{
"$nothing"
:
1
}
},
"limit"
:
1
}
],
"ordered"
:
true
},
"command_name"
:
"delete"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
0
,
"writeErrors"
:
[
{
"index"
:
0
,
"code"
:
42
,
"errmsg"
:
""
}
]
},
"command_name"
:
"delete"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/find.json
0 → 100644
View file @
fd53a1a2
This diff is collapsed.
Click to expand it.
tests/SpecTests/command-monitoring/insertMany.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful insert many"
,
"operation"
:
{
"name"
:
"insertMany"
,
"arguments"
:
{
"documents"
:
[
{
"_id"
:
2
,
"x"
:
22
}
]
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test"
,
"documents"
:
[
{
"_id"
:
2
,
"x"
:
22
}
],
"ordered"
:
true
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"insert"
}
}
]
},
{
"description"
:
"A successful insert many command with write errors"
,
"operation"
:
{
"name"
:
"insertMany"
,
"arguments"
:
{
"documents"
:
[
{
"_id"
:
1
,
"x"
:
11
}
]
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test"
,
"documents"
:
[
{
"_id"
:
1
,
"x"
:
11
}
],
"ordered"
:
true
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
0
,
"writeErrors"
:
[
{
"index"
:
0
,
"code"
:
42
,
"errmsg"
:
""
}
]
},
"command_name"
:
"insert"
}
}
]
},
{
"description"
:
"A successful unordered insert many"
,
"operation"
:
{
"name"
:
"insertMany"
,
"arguments"
:
{
"documents"
:
[
{
"_id"
:
2
,
"x"
:
22
}
],
"options"
:
{
"ordered"
:
false
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test"
,
"documents"
:
[
{
"_id"
:
2
,
"x"
:
22
}
],
"ordered"
:
false
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"insert"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/insertOne.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful insert one"
,
"operation"
:
{
"name"
:
"insertOne"
,
"arguments"
:
{
"document"
:
{
"_id"
:
2
,
"x"
:
22
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test"
,
"documents"
:
[
{
"_id"
:
2
,
"x"
:
22
}
],
"ordered"
:
true
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"insert"
}
}
]
},
{
"description"
:
"A successful insert one command with write errors"
,
"operation"
:
{
"name"
:
"insertOne"
,
"arguments"
:
{
"document"
:
{
"_id"
:
1
,
"x"
:
11
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test"
,
"documents"
:
[
{
"_id"
:
1
,
"x"
:
11
}
],
"ordered"
:
true
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
0
,
"writeErrors"
:
[
{
"index"
:
0
,
"code"
:
42
,
"errmsg"
:
""
}
]
},
"command_name"
:
"insert"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/unacknowledgedBulkWrite.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
}
],
"collection_name"
:
"test-unacknowledged-bulk-write"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful unordered bulk write with an unacknowledged write concern"
,
"comment"
:
"On a 2.4 server, no GLE is sent and requires a client-side manufactured reply"
,
"operation"
:
{
"name"
:
"bulkWrite"
,
"collectionOptions"
:
{
"writeConcern"
:
{
"w"
:
0
}
},
"arguments"
:
{
"requests"
:
[
{
"name"
:
"insertOne"
,
"arguments"
:
{
"document"
:
{
"_id"
:
"unorderedBulkWriteInsertW0"
,
"x"
:
44
}
}
}
],
"options"
:
{
"ordered"
:
false
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"insert"
:
"test-unacknowledged-bulk-write"
,
"documents"
:
[
{
"_id"
:
"unorderedBulkWriteInsertW0"
,
"x"
:
44
}
],
"ordered"
:
false
,
"writeConcern"
:
{
"w"
:
0
}
},
"command_name"
:
"insert"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
},
"command_name"
:
"insert"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/updateMany.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful update many"
,
"operation"
:
{
"name"
:
"updateMany"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"update"
:
{
"$inc"
:
{
"x"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"ordered"
:
true
,
"updates"
:
[
{
"q"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"u"
:
{
"$inc"
:
{
"x"
:
1
}
},
"multi"
:
true
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
2
},
"command_name"
:
"update"
}
}
]
},
{
"description"
:
"A successful update many command with write errors"
,
"operation"
:
{
"name"
:
"updateMany"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"update"
:
{
"$nothing"
:
{
"x"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"ordered"
:
true
,
"updates"
:
[
{
"q"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"u"
:
{
"$nothing"
:
{
"x"
:
1
}
},
"multi"
:
true
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
0
,
"writeErrors"
:
[
{
"index"
:
0
,
"code"
:
42
,
"errmsg"
:
""
}
]
},
"command_name"
:
"update"
}
}
]
}
]
}
tests/SpecTests/command-monitoring/updateOne.json
0 → 100644
View file @
fd53a1a2
{
"data"
:
[
{
"_id"
:
1
,
"x"
:
11
},
{
"_id"
:
2
,
"x"
:
22
},
{
"_id"
:
3
,
"x"
:
33
}
],
"collection_name"
:
"test"
,
"database_name"
:
"command-monitoring-tests"
,
"tests"
:
[
{
"description"
:
"A successful update one"
,
"operation"
:
{
"name"
:
"updateOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"update"
:
{
"$inc"
:
{
"x"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"ordered"
:
true
,
"updates"
:
[
{
"q"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"u"
:
{
"$inc"
:
{
"x"
:
1
}
}
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
},
"command_name"
:
"update"
}
}
]
},
{
"description"
:
"A successful update one with upsert when the upserted id is not an object id"
,
"operation"
:
{
"name"
:
"updateOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
4
},
"update"
:
{
"$inc"
:
{
"x"
:
1
}
},
"upsert"
:
true
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"ordered"
:
true
,
"updates"
:
[
{
"q"
:
{
"_id"
:
4
},
"u"
:
{
"$inc"
:
{
"x"
:
1
}
},
"upsert"
:
true
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
1
,
"upserted"
:
[
{
"index"
:
0
,
"_id"
:
4
}
]
},
"command_name"
:
"update"
}
}
]
},
{
"description"
:
"A successful update one command with write errors"
,
"operation"
:
{
"name"
:
"updateOne"
,
"arguments"
:
{
"filter"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"update"
:
{
"$nothing"
:
{
"x"
:
1
}
}
}
},
"expectations"
:
[
{
"command_started_event"
:
{
"command"
:
{
"update"
:
"test"
,
"ordered"
:
true
,
"updates"
:
[
{
"q"
:
{
"_id"
:
{
"$gt"
:
1
}
},
"u"
:
{
"$nothing"
:
{
"x"
:
1
}
}
}
]
},
"command_name"
:
"update"
,
"database_name"
:
"command-monitoring-tests"
}
},
{
"command_succeeded_event"
:
{
"reply"
:
{
"ok"
:
1
,
"n"
:
0
,
"writeErrors"
:
[
{
"index"
:
0
,
"code"
:
42
,
"errmsg"
:
""
}
]
},
"command_name"
:
"update"
}
}
]
}
]
}
tests/bootstrap.php
View file @
fd53a1a2
...
@@ -13,3 +13,7 @@ if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
...
@@ -13,3 +13,7 @@ if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
if
(
!
class_exists
(
'PHPUnit\Framework\Error\Warning'
))
{
if
(
!
class_exists
(
'PHPUnit\Framework\Error\Warning'
))
{
class_alias
(
'PHPUnit_Framework_Error_Warning'
,
'PHPUnit\Framework\Error\Warning'
);
class_alias
(
'PHPUnit_Framework_Error_Warning'
,
'PHPUnit\Framework\Error\Warning'
);
}
}
if
(
!
class_exists
(
'PHPUnit\Framework\Constraint\Constraint'
))
{
class_alias
(
'PHPUnit_Framework_Constraint'
,
'PHPUnit\Framework\Constraint\Constraint'
);
}
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