]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / monolog / monolog / tests / Monolog / Handler / ElasticSearchHandlerTest.php
1 <?php
2
3 /*
4  * This file is part of the Monolog package.
5  *
6  * (c) Jordi Boggiano <j.boggiano@seld.be>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Monolog\Handler;
13
14 use Monolog\Formatter\ElasticaFormatter;
15 use Monolog\Formatter\NormalizerFormatter;
16 use Monolog\TestCase;
17 use Monolog\Logger;
18 use Elastica\Client;
19 use Elastica\Request;
20 use Elastica\Response;
21
22 class ElasticSearchHandlerTest extends TestCase
23 {
24     /**
25      * @var Client mock
26      */
27     protected $client;
28
29     /**
30      * @var array Default handler options
31      */
32     protected $options = array(
33         'index' => 'my_index',
34         'type'  => 'doc_type',
35     );
36
37     public function setUp()
38     {
39         // Elastica lib required
40         if (!class_exists("Elastica\Client")) {
41             $this->markTestSkipped("ruflin/elastica not installed");
42         }
43
44         // base mock Elastica Client object
45         $this->client = $this->getMockBuilder('Elastica\Client')
46             ->setMethods(array('addDocuments'))
47             ->disableOriginalConstructor()
48             ->getMock();
49     }
50
51     /**
52      * @covers Monolog\Handler\ElasticSearchHandler::write
53      * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
54      * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
55      * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
56      */
57     public function testHandle()
58     {
59         // log message
60         $msg = array(
61             'level' => Logger::ERROR,
62             'level_name' => 'ERROR',
63             'channel' => 'meh',
64             'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
65             'datetime' => new \DateTime("@0"),
66             'extra' => array(),
67             'message' => 'log',
68         );
69
70         // format expected result
71         $formatter = new ElasticaFormatter($this->options['index'], $this->options['type']);
72         $expected = array($formatter->format($msg));
73
74         // setup ES client mock
75         $this->client->expects($this->any())
76             ->method('addDocuments')
77             ->with($expected);
78
79         // perform tests
80         $handler = new ElasticSearchHandler($this->client, $this->options);
81         $handler->handle($msg);
82         $handler->handleBatch(array($msg));
83     }
84
85     /**
86      * @covers Monolog\Handler\ElasticSearchHandler::setFormatter
87      */
88     public function testSetFormatter()
89     {
90         $handler = new ElasticSearchHandler($this->client);
91         $formatter = new ElasticaFormatter('index_new', 'type_new');
92         $handler->setFormatter($formatter);
93         $this->assertInstanceOf('Monolog\Formatter\ElasticaFormatter', $handler->getFormatter());
94         $this->assertEquals('index_new', $handler->getFormatter()->getIndex());
95         $this->assertEquals('type_new', $handler->getFormatter()->getType());
96     }
97
98     /**
99      * @covers                   Monolog\Handler\ElasticSearchHandler::setFormatter
100      * @expectedException        InvalidArgumentException
101      * @expectedExceptionMessage ElasticSearchHandler is only compatible with ElasticaFormatter
102      */
103     public function testSetFormatterInvalid()
104     {
105         $handler = new ElasticSearchHandler($this->client);
106         $formatter = new NormalizerFormatter();
107         $handler->setFormatter($formatter);
108     }
109
110     /**
111      * @covers Monolog\Handler\ElasticSearchHandler::__construct
112      * @covers Monolog\Handler\ElasticSearchHandler::getOptions
113      */
114     public function testOptions()
115     {
116         $expected = array(
117             'index' => $this->options['index'],
118             'type' => $this->options['type'],
119             'ignore_error' => false,
120         );
121         $handler = new ElasticSearchHandler($this->client, $this->options);
122         $this->assertEquals($expected, $handler->getOptions());
123     }
124
125     /**
126      * @covers       Monolog\Handler\ElasticSearchHandler::bulkSend
127      * @dataProvider providerTestConnectionErrors
128      */
129     public function testConnectionErrors($ignore, $expectedError)
130     {
131         $clientOpts = array('host' => '127.0.0.1', 'port' => 1);
132         $client = new Client($clientOpts);
133         $handlerOpts = array('ignore_error' => $ignore);
134         $handler = new ElasticSearchHandler($client, $handlerOpts);
135
136         if ($expectedError) {
137             $this->setExpectedException($expectedError[0], $expectedError[1]);
138             $handler->handle($this->getRecord());
139         } else {
140             $this->assertFalse($handler->handle($this->getRecord()));
141         }
142     }
143
144     /**
145      * @return array
146      */
147     public function providerTestConnectionErrors()
148     {
149         return array(
150             array(false, array('RuntimeException', 'Error sending messages to Elasticsearch')),
151             array(true, false),
152         );
153     }
154
155     /**
156      * Integration test using localhost Elastic Search server
157      *
158      * @covers Monolog\Handler\ElasticSearchHandler::__construct
159      * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
160      * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
161      * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
162      */
163     public function testHandleIntegration()
164     {
165         $msg = array(
166             'level' => Logger::ERROR,
167             'level_name' => 'ERROR',
168             'channel' => 'meh',
169             'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
170             'datetime' => new \DateTime("@0"),
171             'extra' => array(),
172             'message' => 'log',
173         );
174
175         $expected = $msg;
176         $expected['datetime'] = $msg['datetime']->format(\DateTime::ISO8601);
177         $expected['context'] = array(
178             'class' => '[object] (stdClass: {})',
179             'foo' => 7,
180             0 => 'bar',
181         );
182
183         $client = new Client();
184         $handler = new ElasticSearchHandler($client, $this->options);
185         try {
186             $handler->handleBatch(array($msg));
187         } catch (\RuntimeException $e) {
188             $this->markTestSkipped("Cannot connect to Elastic Search server on localhost");
189         }
190
191         // check document id from ES server response
192         $documentId = $this->getCreatedDocId($client->getLastResponse());
193         $this->assertNotEmpty($documentId, 'No elastic document id received');
194
195         // retrieve document source from ES and validate
196         $document = $this->getDocSourceFromElastic(
197             $client,
198             $this->options['index'],
199             $this->options['type'],
200             $documentId
201         );
202         $this->assertEquals($expected, $document);
203
204         // remove test index from ES
205         $client->request("/{$this->options['index']}", Request::DELETE);
206     }
207
208     /**
209      * Return last created document id from ES response
210      * @param  Response    $response Elastica Response object
211      * @return string|null
212      */
213     protected function getCreatedDocId(Response $response)
214     {
215         $data = $response->getData();
216         if (!empty($data['items'][0]['create']['_id'])) {
217             return $data['items'][0]['create']['_id'];
218         }
219     }
220
221     /**
222      * Retrieve document by id from Elasticsearch
223      * @param  Client $client     Elastica client
224      * @param  string $index
225      * @param  string $type
226      * @param  string $documentId
227      * @return array
228      */
229     protected function getDocSourceFromElastic(Client $client, $index, $type, $documentId)
230     {
231         $resp = $client->request("/{$index}/{$type}/{$documentId}", Request::GET);
232         $data = $resp->getData();
233         if (!empty($data['_source'])) {
234             return $data['_source'];
235         }
236
237         return array();
238     }
239 }