Skip to content

Commit ead90db

Browse files
committed
Factorize search indexes waiting helper
1 parent 8e114b5 commit ead90db

File tree

4 files changed

+74
-31
lines changed

4 files changed

+74
-31
lines changed

docs/includes/fundamentals/as-avs/AtlasSearchTest.php

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use MongoDB\Collection;
1212
use MongoDB\Driver\Exception\ServerException;
1313
use MongoDB\Laravel\Schema\Builder;
14+
use MongoDB\Laravel\Tests\AtlasSearchIndexManagement;
1415
use MongoDB\Laravel\Tests\TestCase;
1516
use PHPUnit\Framework\Attributes\Group;
1617

@@ -19,11 +20,12 @@
1920
use function rand;
2021
use function range;
2122
use function srand;
22-
use function usleep;
2323

2424
#[Group('atlas-search')]
2525
class AtlasSearchTest extends TestCase
2626
{
27+
use AtlasSearchIndexManagement;
28+
2729
private array $vectors;
2830

2931
protected function setUp(): void
@@ -51,10 +53,7 @@ protected function setUp(): void
5153
['title' => 'D', 'plot' => 'Stranded on a distant planet, astronauts must repair their ship before supplies run out.'],
5254
]));
5355

54-
// Waits for the search index created in the previous test to be deleted
55-
while ($moviesCollection->listSearchIndexes()->count()) {
56-
usleep(1000);
57-
}
56+
$this->waitForSearchIndexesDropped($moviesCollection);
5857

5958
try {
6059
$moviesCollection->createSearchIndex([
@@ -87,14 +86,7 @@ protected function setUp(): void
8786
throw $e;
8887
}
8988

90-
// Waits for the index to be ready
91-
do {
92-
$ready = true;
93-
usleep(10_000);
94-
foreach ($moviesCollection->listSearchIndexes() as $index) {
95-
$ready = $ready && $index['queryable'];
96-
}
97-
} while (! $ready);
89+
$this->waitForSearchIndexesReady($moviesCollection);
9890
}
9991

10092
/**
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace MongoDB\Laravel\Tests;
4+
5+
use MongoDB\Collection;
6+
use RuntimeException;
7+
8+
use function hrtime;
9+
use function usleep;
10+
11+
/**
12+
* Helpers for managing Atlas Search indexes in tests with awaiting mechanism.
13+
*/
14+
trait AtlasSearchIndexManagement
15+
{
16+
/**
17+
* Waits for the search index created in the previous test to be deleted
18+
*/
19+
public function waitForSearchIndexesDropped(Collection $collection)
20+
{
21+
$timeout = hrtime()[0] + 30;
22+
// Waits for the search index created in the previous test to be deleted
23+
while ($collection->listSearchIndexes()->count()) {
24+
if (hrtime()[0] > $timeout) {
25+
throw new RuntimeException('Timed out waiting for search indexes to be dropped');
26+
}
27+
28+
usleep(1000);
29+
}
30+
}
31+
32+
/**
33+
* Waits for all search indexes to be ready
34+
*/
35+
public function waitForSearchIndexesReady(Collection $collection)
36+
{
37+
$timeout = hrtime()[0] + 30;
38+
do {
39+
if (hrtime()[0] > $timeout) {
40+
throw new RuntimeException('Timed out waiting for search indexes to be ready');
41+
}
42+
43+
usleep(1000);
44+
$ready = true;
45+
foreach ($collection->listSearchIndexes() as $index) {
46+
$ready = $ready && $index['queryable'];
47+
}
48+
} while (! $ready);
49+
}
50+
}

tests/AtlasSearchTest.php

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
use function rand;
2020
use function range;
2121
use function srand;
22-
use function usleep;
2322
use function usort;
2423

2524
#[Group('atlas-search')]
2625
class AtlasSearchTest extends TestCase
2726
{
27+
use AtlasSearchIndexManagement;
28+
2829
private array $vectors;
2930

3031
public function setUp(): void
@@ -59,10 +60,7 @@ public function setUp(): void
5960
]));
6061

6162
try {
62-
// Waits for the search index created in the previous test to be deleted
63-
while ($collection->listSearchIndexes()->count()) {
64-
usleep(1000);
65-
}
63+
$this->waitForSearchIndexesDropped($collection);
6664

6765
$collection->createSearchIndex([
6866
'mappings' => [
@@ -95,14 +93,7 @@ public function setUp(): void
9593
throw $e;
9694
}
9795

98-
// Wait for the index to be ready
99-
do {
100-
$ready = true;
101-
usleep(1000);
102-
foreach ($collection->listSearchIndexes() as $index) {
103-
$ready = $ready && $index['queryable'];
104-
}
105-
} while (! $ready);
96+
$this->waitForSearchIndexesReady($collection);
10697
}
10798

10899
public function tearDown(): void

tests/Scout/ScoutIntegrationTest.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Support\LazyCollection;
88
use Laravel\Scout\ScoutServiceProvider;
99
use LogicException;
10+
use MongoDB\Laravel\Tests\AtlasSearchIndexManagement;
1011
use MongoDB\Laravel\Tests\Scout\Models\ScoutUser;
1112
use MongoDB\Laravel\Tests\Scout\Models\SearchableInSameNamespace;
1213
use MongoDB\Laravel\Tests\TestCase;
@@ -17,6 +18,7 @@
1718
use function array_merge;
1819
use function count;
1920
use function env;
21+
use function hrtime;
2022
use function iterator_to_array;
2123
use function Orchestra\Testbench\artisan;
2224
use function range;
@@ -26,6 +28,8 @@
2628
#[Group('atlas-search')]
2729
class ScoutIntegrationTest extends TestCase
2830
{
31+
use AtlasSearchIndexManagement;
32+
2933
#[Override]
3034
protected function getPackageProviders($app): array
3135
{
@@ -96,25 +100,29 @@ public function setUp(): void
96100
/** This test create the search index for tests performing search */
97101
public function testItCanCreateTheCollection()
98102
{
103+
$this->skipIfSearchIndexManagementIsNotSupported();
104+
99105
$collection = DB::connection('mongodb')->getCollection('prefix_scout_users');
100106
$collection->drop();
107+
$this->waitForSearchIndexesDropped($collection);
101108

102109
// Recreate the indexes using the artisan commands
103110
// Ensure they return a success exit code (0)
104111
self::assertSame(0, artisan($this, 'scout:delete-index', ['name' => ScoutUser::class]));
105-
self::assertSame(0, artisan($this, 'scout:index', ['name' => ScoutUser::class]));
106112
self::assertSame(0, artisan($this, 'scout:import', ['model' => ScoutUser::class]));
113+
self::assertSame(0, artisan($this, 'scout:index', ['name' => ScoutUser::class]));
107114

108115
self::assertSame(44, $collection->countDocuments());
109116

110117
$searchIndexes = $collection->listSearchIndexes(['name' => 'scout', 'typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']]);
111118
self::assertCount(1, $searchIndexes);
112119
self::assertSame(['mappings' => ['dynamic' => true, 'fields' => ['bool_field' => ['type' => 'boolean']]]], iterator_to_array($searchIndexes)[0]['latestDefinition']);
113120

121+
$this->waitForSearchIndexesReady($collection);
122+
114123
// Wait for all documents to be indexed asynchronously
115-
$i = 1000;
124+
$timeout = hrtime()[0] + 30;
116125
while (true) {
117-
usleep(10_000);
118126
$indexedDocuments = $collection->aggregate([
119127
['$search' => ['index' => 'scout', 'exists' => ['path' => 'name']]],
120128
])->toArray();
@@ -123,9 +131,11 @@ public function testItCanCreateTheCollection()
123131
break;
124132
}
125133

126-
if ($i-- === 0) {
127-
self::fail('Documents not indexed');
134+
if (hrtime()[0] > $timeout) {
135+
self::fail('Timed out waiting for documents to be indexed');
128136
}
137+
138+
usleep(1000);
129139
}
130140

131141
self::assertCount(44, $indexedDocuments);

0 commit comments

Comments
 (0)