Merge "Send 500 http status code, instead of 200, for DBConnectionErrors"
[lhc/web/wiklou.git] / tests / phpunit / includes / debug / logger / monolog / KafkaHandlerTest.php
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21 namespace MediaWiki\Logger\Monolog;
22
23 use MediaWikiTestCase;
24 use Monolog\Logger;
25 use Wikimedia\TestingAccessWrapper;
26
27 class KafkaHandlerTest extends MediaWikiTestCase {
28
29 protected function setUp() {
30 if ( !class_exists( 'Monolog\Handler\AbstractProcessingHandler' )
31 || !class_exists( 'Kafka\Produce' )
32 ) {
33 $this->markTestSkipped( 'Monolog and Kafka are required for the KafkaHandlerTest' );
34 }
35
36 parent::setUp();
37 }
38
39 public function topicNamingProvider() {
40 return [
41 [ [], 'monolog_foo' ],
42 [ [ 'alias' => [ 'foo' => 'bar' ] ], 'bar' ]
43 ];
44 }
45
46 /**
47 * @dataProvider topicNamingProvider
48 */
49 public function testTopicNaming( $options, $expect ) {
50 $produce = $this->getMockBuilder( 'Kafka\Produce' )
51 ->disableOriginalConstructor()
52 ->getMock();
53 $produce->expects( $this->any() )
54 ->method( 'getAvailablePartitions' )
55 ->will( $this->returnValue( [ 'A' ] ) );
56 $produce->expects( $this->once() )
57 ->method( 'setMessages' )
58 ->with( $expect, $this->anything(), $this->anything() );
59 $produce->expects( $this->any() )
60 ->method( 'send' )
61 ->will( $this->returnValue( true ) );
62
63 $handler = new KafkaHandler( $produce, $options );
64 $handler->handle( [
65 'channel' => 'foo',
66 'level' => Logger::EMERGENCY,
67 'extra' => [],
68 'context' => [],
69 ] );
70 }
71
72 public function swallowsExceptionsWhenRequested() {
73 return [
74 // defaults to false
75 [ [], true ],
76 // also try false explicitly
77 [ [ 'swallowExceptions' => false ], true ],
78 // turn it on
79 [ [ 'swallowExceptions' => true ], false ],
80 ];
81 }
82
83 /**
84 * @dataProvider swallowsExceptionsWhenRequested
85 */
86 public function testGetAvailablePartitionsException( $options, $expectException ) {
87 $produce = $this->getMockBuilder( 'Kafka\Produce' )
88 ->disableOriginalConstructor()
89 ->getMock();
90 $produce->expects( $this->any() )
91 ->method( 'getAvailablePartitions' )
92 ->will( $this->throwException( new \Kafka\Exception ) );
93 $produce->expects( $this->any() )
94 ->method( 'send' )
95 ->will( $this->returnValue( true ) );
96
97 if ( $expectException ) {
98 $this->setExpectedException( 'Kafka\Exception' );
99 }
100
101 $handler = new KafkaHandler( $produce, $options );
102 $handler->handle( [
103 'channel' => 'foo',
104 'level' => Logger::EMERGENCY,
105 'extra' => [],
106 'context' => [],
107 ] );
108
109 if ( !$expectException ) {
110 $this->assertTrue( true, 'no exception was thrown' );
111 }
112 }
113
114 /**
115 * @dataProvider swallowsExceptionsWhenRequested
116 */
117 public function testSendException( $options, $expectException ) {
118 $produce = $this->getMockBuilder( 'Kafka\Produce' )
119 ->disableOriginalConstructor()
120 ->getMock();
121 $produce->expects( $this->any() )
122 ->method( 'getAvailablePartitions' )
123 ->will( $this->returnValue( [ 'A' ] ) );
124 $produce->expects( $this->any() )
125 ->method( 'send' )
126 ->will( $this->throwException( new \Kafka\Exception ) );
127
128 if ( $expectException ) {
129 $this->setExpectedException( 'Kafka\Exception' );
130 }
131
132 $handler = new KafkaHandler( $produce, $options );
133 $handler->handle( [
134 'channel' => 'foo',
135 'level' => Logger::EMERGENCY,
136 'extra' => [],
137 'context' => [],
138 ] );
139
140 if ( !$expectException ) {
141 $this->assertTrue( true, 'no exception was thrown' );
142 }
143 }
144
145 public function testHandlesNullFormatterResult() {
146 $produce = $this->getMockBuilder( 'Kafka\Produce' )
147 ->disableOriginalConstructor()
148 ->getMock();
149 $produce->expects( $this->any() )
150 ->method( 'getAvailablePartitions' )
151 ->will( $this->returnValue( [ 'A' ] ) );
152 $mockMethod = $produce->expects( $this->exactly( 2 ) )
153 ->method( 'setMessages' );
154 $produce->expects( $this->any() )
155 ->method( 'send' )
156 ->will( $this->returnValue( true ) );
157 // evil hax
158 TestingAccessWrapper::newFromObject( $mockMethod )->matcher->parametersMatcher =
159 new \PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters( [
160 [ $this->anything(), $this->anything(), [ 'words' ] ],
161 [ $this->anything(), $this->anything(), [ 'lines' ] ]
162 ] );
163
164 $formatter = $this->createMock( 'Monolog\Formatter\FormatterInterface' );
165 $formatter->expects( $this->any() )
166 ->method( 'format' )
167 ->will( $this->onConsecutiveCalls( 'words', null, 'lines' ) );
168
169 $handler = new KafkaHandler( $produce, [] );
170 $handler->setFormatter( $formatter );
171 for ( $i = 0; $i < 3; ++$i ) {
172 $handler->handle( [
173 'channel' => 'foo',
174 'level' => Logger::EMERGENCY,
175 'extra' => [],
176 'context' => [],
177 ] );
178 }
179 }
180
181 public function testBatchHandlesNullFormatterResult() {
182 $produce = $this->getMockBuilder( 'Kafka\Produce' )
183 ->disableOriginalConstructor()
184 ->getMock();
185 $produce->expects( $this->any() )
186 ->method( 'getAvailablePartitions' )
187 ->will( $this->returnValue( [ 'A' ] ) );
188 $produce->expects( $this->once() )
189 ->method( 'setMessages' )
190 ->with( $this->anything(), $this->anything(), [ 'words', 'lines' ] );
191 $produce->expects( $this->any() )
192 ->method( 'send' )
193 ->will( $this->returnValue( true ) );
194
195 $formatter = $this->createMock( 'Monolog\Formatter\FormatterInterface' );
196 $formatter->expects( $this->any() )
197 ->method( 'format' )
198 ->will( $this->onConsecutiveCalls( 'words', null, 'lines' ) );
199
200 $handler = new KafkaHandler( $produce, [] );
201 $handler->setFormatter( $formatter );
202 $handler->handleBatch( [
203 [
204 'channel' => 'foo',
205 'level' => Logger::EMERGENCY,
206 'extra' => [],
207 'context' => [],
208 ],
209 [
210 'channel' => 'foo',
211 'level' => Logger::EMERGENCY,
212 'extra' => [],
213 'context' => [],
214 ],
215 [
216 'channel' => 'foo',
217 'level' => Logger::EMERGENCY,
218 'extra' => [],
219 'context' => [],
220 ],
221 ] );
222 }
223 }