Commit a452dd8b authored by Jeremy Mikola's avatar Jeremy Mikola

Merge pull request #564

parents cad17308 45190ee1
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
"php": ">=5.5", "php": ">=5.5",
"ext-hash": "*", "ext-hash": "*",
"ext-json": "*", "ext-json": "*",
"ext-mongodb": "^1.5.0" "ext-mongodb": "^1.5.2"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8.36 || ^6.4" "phpunit/phpunit": "^4.8.36 || ^6.4"
......
...@@ -12,6 +12,7 @@ use MongoDB\Exception\InvalidArgumentException; ...@@ -12,6 +12,7 @@ use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Operation\Count; use MongoDB\Operation\Count;
use MongoDB\Operation\MapReduce; use MongoDB\Operation\MapReduce;
use MongoDB\Tests\CommandObserver; use MongoDB\Tests\CommandObserver;
use Exception;
use stdClass; use stdClass;
/** /**
...@@ -104,6 +105,37 @@ class CollectionFunctionalTest extends FunctionalTestCase ...@@ -104,6 +105,37 @@ class CollectionFunctionalTest extends FunctionalTestCase
$this->assertEquals($this->getNamespace(), $this->collection->getNamespace()); $this->assertEquals($this->getNamespace(), $this->collection->getNamespace());
} }
public function testAggregateWithinTransaction()
{
$this->skipIfTransactionsAreNotSupported();
// Collection must be created before the transaction starts
$this->createCollection();
$session = $this->manager->startSession();
$session->startTransaction();
try {
$this->createFixtures(3, ['session' => $session]);
$cursor = $this->collection->aggregate(
[['$match' => ['_id' => ['$lt' => 3]]]],
['session' => $session]
);
$expected = [
['_id' => 1, 'x' => 11],
['_id' => 2, 'x' => 22],
];
$this->assertSameDocuments($expected, $cursor);
$session->commitTransaction();
} finally {
$session->endSession();
}
}
public function testCreateIndexSplitsCommandOptions() public function testCreateIndexSplitsCommandOptions()
{ {
if (version_compare($this->getServerVersion(), '3.6.0', '<')) { if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
...@@ -179,6 +211,37 @@ class CollectionFunctionalTest extends FunctionalTestCase ...@@ -179,6 +211,37 @@ class CollectionFunctionalTest extends FunctionalTestCase
$this->assertSameDocument($expected, $this->collection->findOne($filter, $options)); $this->assertSameDocument($expected, $this->collection->findOne($filter, $options));
} }
public function testFindWithinTransaction()
{
$this->skipIfTransactionsAreNotSupported();
// Collection must be created before the transaction starts
$this->createCollection();
$session = $this->manager->startSession();
$session->startTransaction();
try {
$this->createFixtures(3, ['session' => $session]);
$cursor = $this->collection->find(
['_id' => ['$lt' => 3]],
['session' => $session]
);
$expected = [
['_id' => 1, 'x' => 11],
['_id' => 2, 'x' => 22],
];
$this->assertSameDocuments($expected, $cursor);
$session->commitTransaction();
} finally {
$session->endSession();
}
}
public function testWithOptionsInheritsOptions() public function testWithOptionsInheritsOptions()
{ {
$collectionOptions = [ $collectionOptions = [
...@@ -252,8 +315,9 @@ class CollectionFunctionalTest extends FunctionalTestCase ...@@ -252,8 +315,9 @@ class CollectionFunctionalTest extends FunctionalTestCase
* Create data fixtures. * Create data fixtures.
* *
* @param integer $n * @param integer $n
* @param array $executeBulkWriteOptions
*/ */
private function createFixtures($n) private function createFixtures($n, array $executeBulkWriteOptions = [])
{ {
$bulkWrite = new BulkWrite(['ordered' => true]); $bulkWrite = new BulkWrite(['ordered' => true]);
...@@ -264,7 +328,7 @@ class CollectionFunctionalTest extends FunctionalTestCase ...@@ -264,7 +328,7 @@ class CollectionFunctionalTest extends FunctionalTestCase
]); ]);
} }
$result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite); $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite, $executeBulkWriteOptions);
$this->assertEquals($n, $result->getInsertedCount()); $this->assertEquals($n, $result->getInsertedCount());
} }
......
...@@ -30,13 +30,4 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase ...@@ -30,13 +30,4 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase
$this->dropCollection(); $this->dropCollection();
} }
private function dropCollection()
{
$options = version_compare($this->getServerVersion(), '3.4.0', '>=')
? ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)]
: [];
$this->collection->drop($options);
}
} }
...@@ -1496,14 +1496,4 @@ class DocumentationExamplesTest extends FunctionalTestCase ...@@ -1496,14 +1496,4 @@ class DocumentationExamplesTest extends FunctionalTestCase
{ {
$this->assertCollectionCount($this->getDatabaseName() . '.' . $this->getCollectionName(), $count); $this->assertCollectionCount($this->getDatabaseName() . '.' . $this->getCollectionName(), $count);
} }
private function dropCollection()
{
$options = version_compare($this->getServerVersion(), '3.4.0', '>=')
? ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)]
: [];
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
$operation->execute($this->getPrimaryServer());
}
} }
...@@ -8,7 +8,10 @@ use MongoDB\Driver\Manager; ...@@ -8,7 +8,10 @@ use MongoDB\Driver\Manager;
use MongoDB\Driver\ReadPreference; use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Query; use MongoDB\Driver\Query;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\Exception\CommandException; use MongoDB\Driver\Exception\CommandException;
use MongoDB\Operation\CreateCollection;
use MongoDB\Operation\DropCollection;
use stdClass; use stdClass;
use UnexpectedValueException; use UnexpectedValueException;
...@@ -48,6 +51,44 @@ abstract class FunctionalTestCase extends TestCase ...@@ -48,6 +51,44 @@ abstract class FunctionalTestCase extends TestCase
$this->assertEquals((string) $expectedObjectId, (string) $actualObjectId); $this->assertEquals((string) $expectedObjectId, (string) $actualObjectId);
} }
/**
* Creates the test collection with the specified options.
*
* If the "writeConcern" option is not specified but is supported by the
* server, a majority write concern will be used. This is helpful for tests
* using transactions or secondary reads.
*
* @param array $options
*/
protected function createCollection(array $options = [])
{
if (version_compare($this->getServerVersion(), '3.4.0', '>=')) {
$options += ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)];
}
$operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
$operation->execute($this->getPrimaryServer());
}
/**
* Drops the test collection with the specified options.
*
* If the "writeConcern" option is not specified but is supported by the
* server, a majority write concern will be used. This is helpful for tests
* using transactions or secondary reads.
*
* @param array $options
*/
protected function dropCollection(array $options = [])
{
if (version_compare($this->getServerVersion(), '3.4.0', '>=')) {
$options += ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)];
}
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
$operation->execute($this->getPrimaryServer());
}
protected function getFeatureCompatibilityVersion(ReadPreference $readPreference = null) protected function getFeatureCompatibilityVersion(ReadPreference $readPreference = null)
{ {
if ($this->isShardedCluster()) { if ($this->isShardedCluster()) {
......
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
namespace MongoDB\Tests\Operation; namespace MongoDB\Tests\Operation;
use MongoDB\Driver\BulkWrite; use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\WriteConcern; use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\Exception\RuntimeException; use MongoDB\Driver\Exception\RuntimeException;
use MongoDB\Operation\Aggregate; use MongoDB\Operation\Aggregate;
use MongoDB\Tests\CommandObserver; use MongoDB\Tests\CommandObserver;
use ArrayIterator; use ArrayIterator;
use Exception;
use stdClass; use stdClass;
class AggregateFunctionalTest extends FunctionalTestCase class AggregateFunctionalTest extends FunctionalTestCase
...@@ -274,12 +276,48 @@ class AggregateFunctionalTest extends FunctionalTestCase ...@@ -274,12 +276,48 @@ class AggregateFunctionalTest extends FunctionalTestCase
]; ];
} }
public function testReadPreferenceWithinTransaction()
{
$this->skipIfTransactionsAreNotSupported();
// Collection must be created before the transaction starts
$this->createCollection();
$session = $this->manager->startSession();
$session->startTransaction();
try {
$this->createFixtures(3, ['session' => $session]);
$pipeline = [['$match' => ['_id' => ['$lt' => 3]]]];
$options = [
'readPreference' => new ReadPreference('primary'),
'session' => $session,
];
$operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, $options);
$cursor = $operation->execute($this->getPrimaryServer());
$expected = [
['_id' => 1, 'x' => ['foo' => 'bar']],
['_id' => 2, 'x' => ['foo' => 'bar']],
];
$this->assertSameDocuments($expected, $cursor);
$session->commitTransaction();
} finally {
$session->endSession();
}
}
/** /**
* Create data fixtures. * Create data fixtures.
* *
* @param integer $n * @param integer $n
* @param array $executeBulkWriteOptions
*/ */
private function createFixtures($n) private function createFixtures($n, array $executeBulkWriteOptions = [])
{ {
$bulkWrite = new BulkWrite(['ordered' => true]); $bulkWrite = new BulkWrite(['ordered' => true]);
...@@ -290,7 +328,7 @@ class AggregateFunctionalTest extends FunctionalTestCase ...@@ -290,7 +328,7 @@ class AggregateFunctionalTest extends FunctionalTestCase
]); ]);
} }
$result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite); $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite, $executeBulkWriteOptions);
$this->assertEquals($n, $result->getInsertedCount()); $this->assertEquals($n, $result->getInsertedCount());
} }
......
...@@ -3,11 +3,13 @@ ...@@ -3,11 +3,13 @@
namespace MongoDB\Tests\Operation; namespace MongoDB\Tests\Operation;
use MongoDB\Driver\BulkWrite; use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\WriteConcern;
use MongoDB\Operation\CreateCollection; use MongoDB\Operation\CreateCollection;
use MongoDB\Operation\CreateIndexes; use MongoDB\Operation\CreateIndexes;
use MongoDB\Operation\DropCollection;
use MongoDB\Operation\Find; use MongoDB\Operation\Find;
use MongoDB\Tests\CommandObserver; use MongoDB\Tests\CommandObserver;
use Exception;
use stdClass; use stdClass;
class FindFunctionalTest extends FunctionalTestCase class FindFunctionalTest extends FunctionalTestCase
...@@ -217,12 +219,48 @@ class FindFunctionalTest extends FunctionalTestCase ...@@ -217,12 +219,48 @@ class FindFunctionalTest extends FunctionalTestCase
$this->assertFalse($it->valid()); $this->assertFalse($it->valid());
} }
public function testReadPreferenceWithinTransaction()
{
$this->skipIfTransactionsAreNotSupported();
// Collection must be created before the transaction starts
$this->createCollection();
$session = $this->manager->startSession();
$session->startTransaction();
try {
$this->createFixtures(3, ['session' => $session]);
$filter = ['_id' => ['$lt' => 3]];
$options = [
'readPreference' => new ReadPreference('primary'),
'session' => $session,
];
$operation = new Find($this->getDatabaseName(), $this->getCollectionName(), $filter, $options);
$cursor = $operation->execute($this->getPrimaryServer());
$expected = [
['_id' => 1, 'x' => ['foo' => 'bar']],
['_id' => 2, 'x' => ['foo' => 'bar']],
];
$this->assertSameDocuments($expected, $cursor);
$session->commitTransaction();
} finally {
$session->endSession();
}
}
/** /**
* Create data fixtures. * Create data fixtures.
* *
* @param integer $n * @param integer $n
* @param array $executeBulkWriteOptions
*/ */
private function createFixtures($n) private function createFixtures($n, array $executeBulkWriteOptions = [])
{ {
$bulkWrite = new BulkWrite(['ordered' => true]); $bulkWrite = new BulkWrite(['ordered' => true]);
...@@ -233,7 +271,7 @@ class FindFunctionalTest extends FunctionalTestCase ...@@ -233,7 +271,7 @@ class FindFunctionalTest extends FunctionalTestCase
]); ]);
} }
$result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite); $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite, $executeBulkWriteOptions);
$this->assertEquals($n, $result->getInsertedCount()); $this->assertEquals($n, $result->getInsertedCount());
} }
......
...@@ -44,14 +44,4 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase ...@@ -44,14 +44,4 @@ abstract class FunctionalTestCase extends BaseFunctionalTestCase
{ {
return $this->manager->startSession(); return $this->manager->startSession();
} }
private function dropCollection()
{
$options = version_compare($this->getServerVersion(), '3.4.0', '>=')
? ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)]
: [];
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
$operation->execute($this->getPrimaryServer());
}
} }
...@@ -4,7 +4,6 @@ namespace MongoDB\Tests\Operation; ...@@ -4,7 +4,6 @@ namespace MongoDB\Tests\Operation;
use MongoDB\BSON\Javascript; use MongoDB\BSON\Javascript;
use MongoDB\Driver\BulkWrite; use MongoDB\Driver\BulkWrite;
use MongoDB\Operation\CreateCollection;
use MongoDB\Operation\DropCollection; use MongoDB\Operation\DropCollection;
use MongoDB\Operation\Find; use MongoDB\Operation\Find;
use MongoDB\Operation\MapReduce; use MongoDB\Operation\MapReduce;
...@@ -15,8 +14,8 @@ class MapReduceFunctionalTest extends FunctionalTestCase ...@@ -15,8 +14,8 @@ class MapReduceFunctionalTest extends FunctionalTestCase
{ {
public function testDefaultReadConcernIsOmitted() public function testDefaultReadConcernIsOmitted()
{ {
$operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName()); // Collection must exist for mapReduce command
$operation->execute($this->getPrimaryServer()); $this->createCollection();
(new CommandObserver)->observe( (new CommandObserver)->observe(
function() { function() {
...@@ -39,8 +38,8 @@ class MapReduceFunctionalTest extends FunctionalTestCase ...@@ -39,8 +38,8 @@ class MapReduceFunctionalTest extends FunctionalTestCase
public function testDefaultWriteConcernIsOmitted() public function testDefaultWriteConcernIsOmitted()
{ {
$operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName()); // Collection must exist for mapReduce command
$operation->execute($this->getPrimaryServer()); $this->createCollection();
(new CommandObserver)->observe( (new CommandObserver)->observe(
function() { function() {
......
...@@ -3,15 +3,13 @@ ...@@ -3,15 +3,13 @@
namespace MongoDB\Tests\Operation; namespace MongoDB\Tests\Operation;
use MongoDB\Operation\ModifyCollection; use MongoDB\Operation\ModifyCollection;
use MongoDB\Operation\CreateCollection;
use MongoDB\Operation\CreateIndexes; use MongoDB\Operation\CreateIndexes;
class ModifyCollectionFunctionalTest extends FunctionalTestCase class ModifyCollectionFunctionalTest extends FunctionalTestCase
{ {
public function testCollMod() public function testCollMod()
{ {
$operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName()); $this->createCollection();
$operation->execute($this->getPrimaryServer());
$indexes = [['key' => ['lastAccess' => 1], 'expireAfterSeconds' => 3]]; $indexes = [['key' => ['lastAccess' => 1], 'expireAfterSeconds' => 3]];
$createIndexes = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes); $createIndexes = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
......
...@@ -9,9 +9,7 @@ use MongoDB\Driver\ReadPreference; ...@@ -9,9 +9,7 @@ use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Server; use MongoDB\Driver\Server;
use MongoDB\Driver\Exception\ConnectionTimeoutException; use MongoDB\Driver\Exception\ConnectionTimeoutException;
use MongoDB\Exception\ResumeTokenException; use MongoDB\Exception\ResumeTokenException;
use MongoDB\Operation\CreateCollection;
use MongoDB\Operation\DatabaseCommand; use MongoDB\Operation\DatabaseCommand;
use MongoDB\Operation\DropCollection;
use MongoDB\Operation\InsertOne; use MongoDB\Operation\InsertOne;
use MongoDB\Operation\Watch; use MongoDB\Operation\Watch;
use MongoDB\Tests\CommandObserver; use MongoDB\Tests\CommandObserver;
...@@ -727,8 +725,8 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -727,8 +725,8 @@ class WatchFunctionalTest extends FunctionalTestCase
public function testSessionFreed() public function testSessionFreed()
{ {
$operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName()); // Create collection so we can drop it later
$operation->execute($this->getPrimaryServer()); $this->createCollection();
$operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions); $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
$changeStream = $operation->execute($this->getPrimaryServer()); $changeStream = $operation->execute($this->getPrimaryServer());
...@@ -740,8 +738,7 @@ class WatchFunctionalTest extends FunctionalTestCase ...@@ -740,8 +738,7 @@ class WatchFunctionalTest extends FunctionalTestCase
$this->assertNotNull($rp->getValue($changeStream)); $this->assertNotNull($rp->getValue($changeStream));
// Invalidate the cursor to verify that resumeCallable is unset when the cursor is exhausted. // Invalidate the cursor to verify that resumeCallable is unset when the cursor is exhausted.
$operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName()); $this->dropCollection();
$operation->execute($this->getPrimaryServer());
$changeStream->next(); $changeStream->next();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment