Skip to content

Commit 7b150c8

Browse files
jmikolaGromNaN
authored andcommitted
Prose test 11
1 parent bc45571 commit 7b150c8

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\SpecTests\Crud;
4+
5+
use MongoDB\Client;
6+
use MongoDB\ClientBulkWrite;
7+
use MongoDB\Driver\Monitoring\CommandFailedEvent;
8+
use MongoDB\Driver\Monitoring\CommandStartedEvent;
9+
use MongoDB\Driver\Monitoring\CommandSubscriber;
10+
use MongoDB\Driver\Monitoring\CommandSucceededEvent;
11+
use MongoDB\Tests\SpecTests\FunctionalTestCase;
12+
13+
use function str_repeat;
14+
15+
/**
16+
* Prose test 11: MongoClient.bulkWrite batch splits when the addition of a new namespace exceeds the maximum message size
17+
*
18+
* @see https://github.com/mongodb/specifications/tree/master/source/crud/tests#11-mongoclientbulkwrite-batch-splits-when-the-addition-of-a-new-namespace-exceeds-the-maximum-message-size
19+
*/
20+
class Prose11_BulkWriteBatchSplitsWhenNamespaceExceedsMessageSizeTest extends FunctionalTestCase
21+
{
22+
private Client $client;
23+
private ClientBulkWrite $bulkWrite;
24+
private int $numModels;
25+
26+
public function setUp(): void
27+
{
28+
parent::setUp();
29+
30+
if ($this->isServerless()) {
31+
$this->markTestSkipped('bulkWrite command is not supported');
32+
}
33+
34+
$this->skipIfServerVersion('<', '8.0', 'bulkWrite command is not supported');
35+
36+
$this->client = self::createTestClient();
37+
38+
$hello = $this->getPrimaryServer()->getInfo();
39+
self::assertIsInt($maxBsonObjectSize = $hello['maxBsonObjectSize'] ?? null);
40+
self::assertIsInt($maxMessageSizeBytes = $hello['maxMessageSizeBytes'] ?? null);
41+
42+
$opsBytes = $maxMessageSizeBytes - 1122;
43+
$this->numModels = (int) ($opsBytes / $maxBsonObjectSize);
44+
$remainderBytes = $opsBytes % $maxBsonObjectSize;
45+
46+
// Use namespaces specific to the test, as they are relevant to batch calculations
47+
$this->dropCollection('db', 'coll');
48+
$collection = $this->client->selectCollection('db', 'coll');
49+
50+
$this->bulkWrite = ClientBulkWrite::createWithCollection($collection);
51+
52+
for ($i = 0; $i < $this->numModels; ++$i) {
53+
$this->bulkWrite->insertOne(['a' => str_repeat('b', $maxBsonObjectSize - 57)]);
54+
}
55+
56+
if ($remainderBytes >= 217) {
57+
++$this->numModels;
58+
$this->bulkWrite->insertOne(['a' => str_repeat('b', $remainderBytes - 57)]);
59+
}
60+
}
61+
62+
public function testNoBatchSplittingRequired(): void
63+
{
64+
$subscriber = $this->createSubscriber();
65+
$this->client->addSubscriber($subscriber);
66+
67+
$this->bulkWrite->insertOne(['a' => 'b']);
68+
69+
$result = $this->client->bulkWrite($this->bulkWrite);
70+
71+
self::assertSame($this->numModels + 1, $result->getInsertedCount());
72+
self::assertCount(1, $subscriber->commandStartedEvents);
73+
$command = $subscriber->commandStartedEvents[0]->getCommand();
74+
self::assertCount($this->numModels + 1, $command->ops);
75+
self::assertCount(1, $command->nsInfo);
76+
self::assertSame('db.coll', $command->nsInfo[0]->ns ?? null);
77+
}
78+
79+
public function testBatchSplittingRequired(): void
80+
{
81+
$subscriber = $this->createSubscriber();
82+
$this->client->addSubscriber($subscriber);
83+
84+
$secondCollectionName = str_repeat('c', 200);
85+
$this->dropCollection('db', $secondCollectionName);
86+
$secondCollection = $this->client->selectCollection('db', $secondCollectionName);
87+
$this->bulkWrite->withCollection($secondCollection)->insertOne(['a' => 'b']);
88+
89+
$result = $this->client->bulkWrite($this->bulkWrite);
90+
91+
self::assertSame($this->numModels + 1, $result->getInsertedCount());
92+
self::assertCount(2, $subscriber->commandStartedEvents);
93+
[$firstEvent, $secondEvent] = $subscriber->commandStartedEvents;
94+
95+
$firstCommand = $firstEvent->getCommand();
96+
self::assertCount($this->numModels, $firstCommand->ops);
97+
self::assertCount(1, $firstCommand->nsInfo);
98+
self::assertSame('db.coll', $firstCommand->nsInfo[0]->ns ?? null);
99+
100+
$secondCommand = $secondEvent->getCommand();
101+
self::assertCount(1, $secondCommand->ops);
102+
self::assertCount(1, $secondCommand->nsInfo);
103+
self::assertSame($secondCollection->getNamespace(), $secondCommand->nsInfo[0]->ns ?? null);
104+
}
105+
106+
private function createSubscriber(): CommandSubscriber
107+
{
108+
return new class implements CommandSubscriber {
109+
public array $commandStartedEvents = [];
110+
111+
public function commandStarted(CommandStartedEvent $event): void
112+
{
113+
if ($event->getCommandName() === 'bulkWrite') {
114+
$this->commandStartedEvents[] = $event;
115+
}
116+
}
117+
118+
public function commandSucceeded(CommandSucceededEvent $event): void
119+
{
120+
}
121+
122+
public function commandFailed(CommandFailedEvent $event): void
123+
{
124+
}
125+
};
126+
}
127+
}

0 commit comments

Comments
 (0)