Completed
Push — master ( 0d45ed...ea3502 )
by Nicolas
02:38
created

tests/BulkTest.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Elastica\Test;
4
5
use Elastica\Bulk;
6
use Elastica\Bulk\Action;
7
use Elastica\Bulk\Action\AbstractDocument;
8
use Elastica\Bulk\Action\CreateDocument;
9
use Elastica\Bulk\Action\IndexDocument;
10
use Elastica\Bulk\Action\UpdateDocument;
11
use Elastica\Bulk\Response;
12
use Elastica\Bulk\ResponseSet;
13
use Elastica\Document;
14
use Elastica\Exception\Bulk\ResponseException;
15
use Elastica\Exception\NotFoundException;
16
use Elastica\Script\Script;
17
use Elastica\Test\Base as BaseTest;
18
19
/**
20
 * @internal
21
 */
22
class BulkTest extends BaseTest
23
{
24
    /**
25
     * @group functional
26
     */
27
    public function testSend(): void
28
    {
29
        $index = $this->_createIndex();
30
        $indexName = $index->getName();
31
        $client = $index->getClient();
32
33
        $newDocument1 = new Document(1, ['name' => 'Mister Fantastic'], $index);
34
        $newDocument2 = new Document(2, ['name' => 'Invisible Woman']);
35
        $newDocument3 = new Document(3, ['name' => 'The Human Torch'], $index);
36
        $newDocument4 = new Document(null, ['name' => 'The Thing'], $index);
37
38
        $newDocument3->setOpType(Document::OP_TYPE_CREATE);
39
40
        $documents = [
41
            $newDocument1,
42
            $newDocument2,
43
            $newDocument3,
44
            $newDocument4,
45
        ];
46
47
        $bulk = new Bulk($client);
48
        $bulk->setIndex($index);
49
        $bulk->addDocuments($documents);
50
51
        $actions = $bulk->getActions();
52
53
        $this->assertInstanceOf(IndexDocument::class, $actions[0]);
54
        $this->assertEquals('index', $actions[0]->getOpType());
55
        $this->assertSame($newDocument1, $actions[0]->getDocument());
56
57
        $this->assertInstanceOf(IndexDocument::class, $actions[1]);
58
        $this->assertEquals('index', $actions[1]->getOpType());
59
        $this->assertSame($newDocument2, $actions[1]->getDocument());
60
61
        $this->assertInstanceOf(CreateDocument::class, $actions[2]);
62
        $this->assertEquals('create', $actions[2]->getOpType());
63
        $this->assertSame($newDocument3, $actions[2]->getDocument());
64
65
        $this->assertInstanceOf(IndexDocument::class, $actions[3]);
66
        $this->assertEquals('index', $actions[3]->getOpType());
67
        $this->assertSame($newDocument4, $actions[3]->getDocument());
68
69
        $data = $bulk->toArray();
70
71
        $expected = [
72
            ['index' => ['_id' => 1, '_index' => $indexName]],
73
            ['name' => 'Mister Fantastic'],
74
            ['index' => ['_id' => 2]],
75
            ['name' => 'Invisible Woman'],
76
            ['create' => ['_id' => 3, '_index' => $indexName]],
77
            ['name' => 'The Human Torch'],
78
            ['index' => ['_index' => $indexName]],
79
            ['name' => 'The Thing'],
80
        ];
81
        $this->assertEquals($expected, $data);
82
83
        $expected = '{"index":{"_id":"1","_index":"'.$indexName.'"}}
84
{"name":"Mister Fantastic"}
85
{"index":{"_id":"2"}}
86
{"name":"Invisible Woman"}
87
{"create":{"_id":"3","_index":"'.$indexName.'"}}
88
{"name":"The Human Torch"}
89
{"index":{"_index":"'.$indexName.'"}}
90
{"name":"The Thing"}
91
';
92
93
        $expected = \str_replace(PHP_EOL, "\n", $expected);
94
        $this->assertEquals($expected, (string) \str_replace(PHP_EOL, "\n", (string) $bulk));
95
96
        $response = $bulk->send();
97
98
        $this->assertInstanceOf(ResponseSet::class, $response);
99
100
        $this->assertTrue($response->isOk());
101
        $this->assertFalse($response->hasError());
102
103
        foreach ($response as $i => $bulkResponse) {
104
            $this->assertInstanceOf(Response::class, $bulkResponse);
105
            $this->assertTrue($bulkResponse->isOk());
106
            $this->assertFalse($bulkResponse->hasError());
107
            $this->assertSame($actions[$i], $bulkResponse->getAction());
108
        }
109
110
        $index->refresh();
111
112
        $this->assertEquals(4, $index->count());
113
114
        $bulk = new Bulk($client);
115
        $bulk->addDocument($newDocument3, Action::OP_TYPE_DELETE);
116
117
        $data = $bulk->toArray();
118
119
        $expected = [
120
            ['delete' => ['_index' => $indexName, '_id' => 3]],
121
        ];
122
        $this->assertEquals($expected, $data);
123
124
        $bulk->send();
125
126
        $index->refresh();
127
128
        $this->assertEquals(3, $index->count());
129
130
        try {
131
            $index->getDocument(3);
132
            $this->fail('Document #3 should be deleted');
133
        } catch (NotFoundException $e) {
134
            $this->assertTrue(true);
135
        }
136
    }
137
138
    /**
139
     * @group functional
140
     */
141
    public function testUnicodeBulkSend(): void
142
    {
143
        $index = $this->_createIndex();
144
        $client = $index->getClient();
145
146
        $newDocument1 = new Document(1, ['name' => 'Сегодня, я вижу, особенно грустен твой взгляд,'], $index);
147
        $newDocument2 = new Document(2, ['name' => 'И руки особенно тонки, колени обняв.']);
148
        $newDocument3 = new Document(3, ['name' => 'Послушай: далеко, далеко, на озере Чад / Изысканный бродит жираф.'], $index);
149
150
        $documents = [
151
            $newDocument1,
152
            $newDocument2,
153
            $newDocument3,
154
        ];
155
156
        $bulk = new Bulk($client);
157
        $bulk->setIndex($index);
158
        $bulk->addDocuments($documents);
159
160
        $actions = $bulk->getActions();
161
162
        $this->assertSame($newDocument1, $actions[0]->getDocument());
163
        $this->assertSame($newDocument2, $actions[1]->getDocument());
164
        $this->assertSame($newDocument3, $actions[2]->getDocument());
165
    }
166
167
    /**
168
     * @group functional
169
     */
170
    public function testSetIndex(): void
171
    {
172
        $client = $this->_getClient();
173
        $index = $client->getIndex('index');
174
175
        $index2 = $client->getIndex('index2');
176
177
        $bulk = new Bulk($client);
178
179
        $this->assertFalse($bulk->hasIndex());
180
181
        $bulk->setIndex($index);
182
        $this->assertTrue($bulk->hasIndex());
183
        $this->assertEquals('index', $bulk->getIndex());
184
185
        $bulk->setIndex($index2);
186
        $this->assertTrue($bulk->hasIndex());
187
        $this->assertEquals('index2', $bulk->getIndex());
188
189
        $bulk->setIndex($index);
190
        $this->assertTrue($bulk->hasIndex());
191
        $this->assertEquals('index', $bulk->getIndex());
192
    }
193
194
    /**
195
     * @group unit
196
     */
197
    public function testAddActions(): void
198
    {
199
        $client = $this->_getClient();
200
        $bulk = new Bulk($client);
201
202
        $action1 = new Action(Action::OP_TYPE_DELETE);
203
        $action1->setIndex('index');
204
        $action1->setId(1);
205
206
        $action2 = new Action(Action::OP_TYPE_INDEX);
207
        $action2->setIndex('index');
208
        $action2->setId(1);
209
        $action2->setSource(['name' => 'Batman']);
210
211
        $actions = [
212
            $action1,
213
            $action2,
214
        ];
215
216
        $bulk->addActions($actions);
217
218
        $getActions = $bulk->getActions();
219
220
        $this->assertSame($action1, $getActions[0]);
221
        $this->assertSame($action2, $getActions[1]);
222
    }
223
224
    /**
225
     * @group unit
226
     */
227
    public function testAddRawData(): void
228
    {
229
        $bulk = new Bulk($this->_getClient());
230
231
        $rawData = [
232
            ['index' => ['_index' => 'test', '_id' => '1']],
233
            ['user' => ['name' => 'hans']],
234
            ['delete' => ['_index' => 'test', '_id' => '2']],
235
            ['delete' => ['_index' => 'test', '_id' => '3']],
236
            ['create' => ['_index' => 'test', '_id' => '4']],
237
            ['user' => ['name' => 'mans']],
238
            ['delete' => ['_index' => 'test', '_id' => '5']],
239
        ];
240
241
        $bulk->addRawData($rawData);
242
243
        $actions = $bulk->getActions();
244
245
        $this->assertIsArray($actions);
246
        $this->assertCount(5, $actions);
247
248
        $this->assertInstanceOf(Action::class, $actions[0]);
249
        $this->assertEquals('index', $actions[0]->getOpType());
250
        $this->assertEquals($rawData[0]['index'], $actions[0]->getMetadata());
251
        $this->assertTrue($actions[0]->hasSource());
252
        $this->assertEquals($rawData[1], $actions[0]->getSource());
253
254
        $this->assertInstanceOf(Action::class, $actions[1]);
255
        $this->assertEquals('delete', $actions[1]->getOpType());
256
        $this->assertEquals($rawData[2]['delete'], $actions[1]->getMetadata());
257
        $this->assertFalse($actions[1]->hasSource());
258
259
        $this->assertInstanceOf(Action::class, $actions[2]);
260
        $this->assertEquals('delete', $actions[2]->getOpType());
261
        $this->assertEquals($rawData[3]['delete'], $actions[2]->getMetadata());
262
        $this->assertFalse($actions[2]->hasSource());
263
264
        $this->assertInstanceOf(Action::class, $actions[3]);
265
        $this->assertEquals('create', $actions[3]->getOpType());
266
        $this->assertEquals($rawData[4]['create'], $actions[3]->getMetadata());
267
        $this->assertTrue($actions[3]->hasSource());
268
        $this->assertEquals($rawData[5], $actions[3]->getSource());
269
270
        $this->assertInstanceOf(Action::class, $actions[4]);
271
        $this->assertEquals('delete', $actions[4]->getOpType());
272
        $this->assertEquals($rawData[6]['delete'], $actions[4]->getMetadata());
273
        $this->assertFalse($actions[4]->hasSource());
274
    }
275
276
    /**
277
     * @group unit
278
     * @dataProvider invalidRawDataProvider
279
     *
280
     * @param mixed $rawData
281
     * @param mixed $failMessage
282
     */
283
    public function testInvalidRawData($rawData, $failMessage): void
284
    {
285
        $this->expectException(\Elastica\Exception\InvalidException::class);
286
287
        $bulk = new Bulk($this->_getClient());
288
289
        $bulk->addRawData($rawData);
290
291
        $this->fail($failMessage);
292
    }
293
294
    public function invalidRawDataProvider()
295
    {
296
        return [
297
            [
298
                [
299
                    ['index' => ['_index' => 'test', '_id' => '1']],
300
                    ['user' => ['name' => 'hans']],
301
                    ['user' => ['name' => 'mans']],
302
                ],
303
                'Two sources for one action',
304
            ],
305
            [
306
                [
307
                    ['index' => ['_index' => 'test', '_id' => '1']],
308
                    ['user' => ['name' => 'hans']],
309
                    ['upsert' => ['_index' => 'test', '_id' => '2']],
310
                ],
311
                'Invalid optype for action',
312
            ],
313
            [
314
                [
315
                    ['user' => ['name' => 'mans']],
316
                ],
317
                'Source without action',
318
            ],
319
            [
320
                [
321
                    [],
322
                ],
323
                'Empty array',
324
            ],
325
            [
326
                [
327
                    'dummy',
328
                ],
329
                'String as data',
330
            ],
331
        ];
332
    }
333
334
    /**
335
     * @group functional
336
     */
337
    public function testErrorRequest(): void
338
    {
339
        $index = $this->_createIndex();
340
        $client = $index->getClient();
341
342
        $documents = [
343
            new Document(1, ['name' => 'Mister Fantastic'], $index),
344
            new Document(2, ['name' => 'Invisible Woman'], $index),
345
            new Document(2, ['name' => 'The Human Torch'], $index),
346
        ];
347
348
        $documents[2]->setOpType(Document::OP_TYPE_CREATE);
349
350
        $bulk = new Bulk($client);
351
        $bulk->addDocuments($documents);
352
353
        try {
354
            $bulk->send();
355
            $bulk->fail('3rd document create should produce error');
356
        } catch (ResponseException $e) {
357
            $error = $e->getResponseSet()->getFullError();
358
            $this->assertSame('version_conflict_engine_exception', $error['type']);
359
            $failures = $e->getFailures();
360
            $this->assertIsArray($failures);
361
            $this->assertArrayHasKey(0, $failures);
362
        }
363
    }
364
365
    /**
366
     * @group functional
367
     */
368
    public function testRawDocumentDataRequest(): void
369
    {
370
        $index = $this->_createIndex();
371
        $client = $index->getClient();
372
373
        $documents = [
374
            new Document(null, '{"name":"Mister Fantastic"}'),
375
            new Document(null, '{"name":"Invisible Woman"}'),
376
            new Document(null, '{"name":"The Human Torch"}'),
377
        ];
378
379
        $bulk = new Bulk($client);
380
        $bulk->addDocuments($documents);
381
        $bulk->setIndex($index);
382
383
        $expectedJson = '{"index":{}}
384
{"name":"Mister Fantastic"}
385
{"index":{}}
386
{"name":"Invisible Woman"}
387
{"index":{}}
388
{"name":"The Human Torch"}
389
';
390
        $expectedJson = \str_replace(PHP_EOL, "\n", $expectedJson);
391
        $this->assertEquals($expectedJson, $bulk->toString());
392
393
        $response = $bulk->send();
394
        $this->assertTrue($response->isOk());
395
396
        $index->refresh();
397
398
        $response = $index->search();
399
        $this->assertEquals(3, $response->count());
400
401
        foreach (['Mister', 'Invisible', 'Torch'] as $name) {
402
            $result = $index->search($name);
403
            $this->assertCount(1, $result->getResults());
404
        }
405
    }
406
407
    /**
408
     * @group functional
409
     */
410
    public function testUpdate(): void
411
    {
412
        $index = $this->_createIndex();
413
        $client = $index->getClient();
414
415
        $doc1 = new Document(1, ['name' => 'John'], $index);
416
        $doc2 = new Document(2, ['name' => 'Paul'], $index);
417
        $doc3 = new Document(3, ['name' => 'George'], $index);
418
        $doc4 = new Document(4, ['name' => 'Ringo'], $index);
419
        $documents = [$doc1, $doc2, $doc3, $doc4];
420
421
        //index some documents
422
        $bulk = new Bulk($client);
423
        $bulk->setIndex($index);
424
        $bulk->addDocuments($documents);
425
        $response = $bulk->send();
426
427
        $this->assertTrue($response->isOk());
428
        $this->assertFalse($response->hasError());
429
430
        $index->refresh();
431
432
        $doc = $index->getDocument(2);
0 ignored issues
show
$doc is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
433
434
        //test updating via document
435
        $doc2 = new Document(2, ['name' => 'The Walrus'], $index);
436
        $bulk = new Bulk($client);
437
        $bulk->setIndex($index);
438
        $updateAction = new UpdateDocument($doc2);
439
        $bulk->addAction($updateAction);
440
        $response = $bulk->send();
441
442
        $this->assertTrue($response->isOk());
443
        $this->assertFalse($response->hasError());
444
445
        $index->refresh();
446
447
        $doc = $index->getDocument(2);
448
        $docData = $doc->getData();
449
        $this->assertEquals('The Walrus', $docData['name']);
450
451
        //test updating via script
452
        $script = new Script('ctx._source.name += params.param1;', ['param1' => ' was Paul'], Script::LANG_PAINLESS, 2);
453
        $updateAction = AbstractDocument::create($script, Action::OP_TYPE_UPDATE);
454
        $bulk = new Bulk($client);
455
        $bulk->setIndex($index);
456
        $bulk->addAction($updateAction);
457
        $response = $bulk->send();
458
459
        $this->assertTrue($response->isOk());
460
        $this->assertFalse($response->hasError());
461
462
        $index->refresh();
463
464
        $doc2 = $index->getDocument(2);
465
        $this->assertEquals('The Walrus was Paul', $doc2->name);
466
467
        //test upsert
468
        $script = new Script('', [], null, 5);
469
        $doc = new Document('', ['counter' => 1]);
470
        $script->setUpsert($doc);
471
        $updateAction = AbstractDocument::create($script, Action::OP_TYPE_UPDATE);
472
        $bulk = new Bulk($client);
473
        $bulk->setIndex($index);
474
        $bulk->addAction($updateAction);
475
        $response = $bulk->send();
476
477
        $this->assertTrue($response->isOk());
478
        $this->assertFalse($response->hasError());
479
480
        $index->refresh();
481
        $doc = $index->getDocument(5);
482
        $this->assertEquals(1, $doc->counter);
483
484
        //test doc_as_upsert
485
        $doc = new Document(6, ['test' => 'test']);
486
        $doc->setDocAsUpsert(true);
487
        $updateAction = AbstractDocument::create($doc, Action::OP_TYPE_UPDATE);
488
        $bulk = new Bulk($client);
489
        $bulk->setIndex($index);
490
        $bulk->addAction($updateAction);
491
        $response = $bulk->send();
492
493
        $this->assertTrue($response->isOk());
494
        $this->assertFalse($response->hasError());
495
496
        $index->refresh();
497
        $doc = $index->getDocument(6);
498
        $this->assertEquals('test', $doc->test);
499
500
        //test doc_as_upsert with set of documents (use of addDocuments)
501
        $doc1 = new Document(7, ['test' => 'test1']);
502
        $doc1->setDocAsUpsert(true);
503
        $doc2 = new Document(8, ['test' => 'test2']);
504
        $doc2->setDocAsUpsert(true);
505
        $docs = [$doc1, $doc2];
506
        $bulk = new Bulk($client);
507
        $bulk->setIndex($index);
508
        $bulk->addDocuments($docs, Action::OP_TYPE_UPDATE);
509
        $response = $bulk->send();
510
511
        $this->assertTrue($response->isOk());
512
        $this->assertFalse($response->hasError());
513
514
        $index->refresh();
515
        $doc = $index->getDocument(7);
516
        $this->assertEquals('test1', $doc->test);
517
        $doc = $index->getDocument(8);
518
        $this->assertEquals('test2', $doc->test);
519
520
        //test updating via document with json string as data
521
        $doc3 = new Document(2, [], $index);
522
        $bulk = new Bulk($client);
523
        $bulk->setIndex($index);
524
        $doc3->setData('{"name" : "Paul it is"}');
525
        $updateAction = new UpdateDocument($doc3);
526
        $bulk->addAction($updateAction);
527
        $response = $bulk->send();
528
529
        $this->assertTrue($response->isOk());
530
        $this->assertFalse($response->hasError());
531
532
        $index->refresh();
533
534
        $doc = $index->getDocument(2);
535
        $docData = $doc->getData();
536
        $this->assertEquals('Paul it is', $docData['name']);
537
538
        $index->delete();
539
    }
540
541
    /**
542
     * @group functional
543
     */
544
    public function testUpsert(): void
545
    {
546
        $index = $this->_createIndex();
547
        $client = $index->getClient();
548
549
        $doc1 = new Document(1, ['name' => 'Pele'], $index);
550
        $doc2 = new Document(2, ['name' => 'Beckenbauer'], $index);
551
        $doc3 = new Document(3, ['name' => 'Baggio'], $index);
552
        $doc4 = new Document(4, ['name' => 'Cruyff'], $index);
553
        $documents = \array_map(function ($d) {
554
            $d->setDocAsUpsert(true);
555
556
            return $d;
557
        }, [$doc1, $doc2, $doc3, $doc4]);
558
559
        //index some documents
560
        $bulk = new Bulk($client);
561
        $bulk->setIndex($index);
562
        $bulk->addDocuments($documents);
563
        $response = $bulk->send();
564
565
        $this->assertTrue($response->isOk());
566
        $this->assertFalse($response->hasError());
567
568
        $index->refresh();
569
570
        //test updating via document
571
        $doc1 = new Document(1, ['name' => 'Maradona'], $index);
572
        $doc1->setDocAsUpsert(true);
573
        $bulk = new Bulk($client);
574
        $bulk->setIndex($index);
575
        $updateAction = new UpdateDocument($doc1);
576
        $bulk->addAction($updateAction);
577
        $response = $bulk->send();
578
579
        $this->assertTrue($response->isOk());
580
        $this->assertFalse($response->hasError());
581
582
        $index->refresh();
583
584
        $doc = $index->getDocument(1);
585
        $docData = $doc->getData();
586
        $this->assertEquals('Maradona', $docData['name']);
587
    }
588
589
    /**
590
     * @group unit
591
     */
592
    public function testGetPath(): void
593
    {
594
        $client = $this->_getClient();
595
        $bulk = new Bulk($client);
596
597
        $this->assertEquals('_bulk', $bulk->getPath());
598
599
        $indexName = 'testIndex';
600
601
        $bulk->setIndex($indexName);
602
        $this->assertEquals($indexName.'/_bulk', $bulk->getPath());
603
    }
604
605
    /**
606
     * @group functional
607
     */
608
    public function testRetry(): void
609
    {
610
        $index = $this->_createIndex();
611
        $client = $index->getClient();
612
613
        $doc1 = new Document(1, ['name' => 'Mister Fantastic'], $index);
614
        $doc1->setOpType(Action::OP_TYPE_UPDATE);
615
        $doc1->setRetryOnConflict(5);
616
617
        $bulk = new Bulk($client);
618
        $bulk->addDocument($doc1);
619
620
        $actions = $bulk->getActions();
621
622
        $metadata = $actions[0]->getMetadata();
623
        $this->assertEquals(5, $metadata['retry_on_conflict']);
624
625
        $script = new Script('');
626
        $script->setRetryOnConflict(5);
627
628
        $bulk = new Bulk($client);
629
        $bulk->addScript($script);
630
631
        $actions = $bulk->getActions();
632
633
        $metadata = $actions[0]->getMetadata();
634
        $this->assertEquals(5, $metadata['retry_on_conflict']);
635
    }
636
637
    /**
638
     * @group unit
639
     */
640
    public function testSetShardTimeout(): void
641
    {
642
        $bulk = new Bulk($this->_getClient());
643
        $this->assertInstanceOf(Bulk::class, $bulk->setShardTimeout(10));
644
    }
645
646
    /**
647
     * @group unit
648
     */
649
    public function testSetRequestParam(): void
650
    {
651
        $bulk = new Bulk($this->_getClient());
652
        $this->assertInstanceOf(Bulk::class, $bulk->setRequestParam('key', 'value'));
653
    }
654
655
    /**
656
     * @group benchmark
657
     */
658
    public function testMemoryUsage(): void
659
    {
660
        $index = $this->_createIndex();
661
662
        $data = [
663
            'text1' => 'Very long text for a string',
664
            'text2' => 'But this is not very long',
665
            'text3' => 'random or not random?',
666
        ];
667
668
        $startMemory = \memory_get_usage();
669
670
        for ($n = 1; $n < 10; ++$n) {
671
            $docs = [];
672
673
            for ($i = 1; $i <= 3000; ++$i) {
674
                $docs[] = new Document(\uniqid(), $data);
675
            }
676
677
            $index->addDocuments($docs);
678
            $docs = [];
679
        }
680
681
        unset($docs);
682
683
        $endMemory = \memory_get_usage();
684
685
        $this->assertLessThan(1.3, $endMemory / $startMemory);
686
    }
687
688
    /**
689
     * @group unit
690
     */
691
    public function testHasIndex(): void
692
    {
693
        $client = $this->_getClient();
694
        $bulk = new Bulk($client);
695
696
        $this->assertFalse($bulk->hasIndex());
697
        $bulk->setIndex('unittest');
698
        $this->assertTrue($bulk->hasIndex());
699
    }
700
}
701