Merge "Make statsd sampling rates configurable"
[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
26 class KafkaHandlerTest extends MediaWikiTestCase {
27
28 protected function setUp() {
29 if ( !class_exists( 'Monolog\Handler\AbstractProcessingHandler' )
30 || !class_exists( 'Kafka\Produce' )
31 ) {
32 $this->markTestSkipped( 'Monolog and Kafka are required for the KafkaHandlerTest' );
33 }
34
35 parent::setUp();
36 }
37
38 public function topicNamingProvider() {
39 return [
40 [ [], 'monolog_foo' ],
41 [ [ 'alias' => [ 'foo' => 'bar' ] ], 'bar' ]
42 ];
43 }
44
45 /**
46 * @dataProvider topicNamingProvider
47 */
48 public function testTopicNaming( $options, $expect ) {
49 $produce = $this->getMockBuilder( 'Kafka\Produce' )
50 ->disableOriginalConstructor()
51 ->getMock();
52 $produce->expects( $this->any() )
53 ->method( 'getAvailablePartitions' )
54 ->will( $this->returnValue( [ 'A' ] ) );
55 $produce->expects( $this->once() )
56 ->method( 'setMessages' )
57 ->with( $expect, $this->anything(), $this->anything() );
58 $produce->expects( $this->any() )
59 ->method( 'send' )
60 ->will( $this->returnValue( true ) );
61
62 $handler = new KafkaHandler( $produce, $options );
63 $handler->handle( [
64 'channel' => 'foo',
65 'level' => Logger::EMERGENCY,
66 'extra' => [],
67 'context' => [],
68 ] );
69 }
70
71 public function swallowsExceptionsWhenRequested() {
72 return [
73 // defaults to false
74 [ [], true ],
75 // also try false explicitly
76 [ [ 'swallowExceptions' => false ], true ],
77 // turn it on
78 [ [ 'swallowExceptions' => true ], false ],
79 ];
80 }
81
82 /**
83 * @dataProvider swallowsExceptionsWhenRequested
84 */
85 public function testGetAvailablePartitionsException( $options, $expectException ) {
86 $produce = $this->getMockBuilder( 'Kafka\Produce' )
87 ->disableOriginalConstructor()
88 ->getMock();
89 $produce->expects( $this->any() )
90 ->method( 'getAvailablePartitions' )
91 ->will( $this->throwException( new \Kafka\Exception ) );
92 $produce->expects( $this->any() )
93 ->method( 'send' )
94 ->will( $this->returnValue( true ) );
95
96 if ( $expectException ) {
97 $this->setExpectedException( 'Kafka\Exception' );
98 }
99
100 $handler = new KafkaHandler( $produce, $options );
101 $handler->handle( [
102 'channel' => 'foo',
103 'level' => Logger::EMERGENCY,
104 'extra' => [],
105 'context' => [],
106 ] );
107
108 if ( !$expectException ) {
109 $this->assertTrue( true, 'no exception was thrown' );
110 }
111 }
112
113 /**
114 * @dataProvider swallowsExceptionsWhenRequested
115 */
116 public function testSendException( $options, $expectException ) {
117 $produce = $this->getMockBuilder( 'Kafka\Produce' )
118 ->disableOriginalConstructor()
119 ->getMock();
120 $produce->expects( $this->any() )
121 ->method( 'getAvailablePartitions' )
122 ->will( $this->returnValue( [ 'A' ] ) );
123 $produce->expects( $this->any() )
124 ->method( 'send' )
125 ->will( $this->throwException( new \Kafka\Exception ) );
126
127 if ( $expectException ) {
128 $this->setExpectedException( 'Kafka\Exception' );
129 }
130
131 $handler = new KafkaHandler( $produce, $options );
132 $handler->handle( [
133 'channel' => 'foo',
134 'level' => Logger::EMERGENCY,
135 'extra' => [],
136 'context' => [],
137 ] );
138
139 if ( !$expectException ) {
140 $this->assertTrue( true, 'no exception was thrown' );
141 }
142 }
143
144 public function testHandlesNullFormatterResult() {
145 $produce = $this->getMockBuilder( 'Kafka\Produce' )
146 ->disableOriginalConstructor()
147 ->getMock();
148 $produce->expects( $this->any() )
149 ->method( 'getAvailablePartitions' )
150 ->will( $this->returnValue( [ 'A' ] ) );
151 $mockMethod = $produce->expects( $this->exactly( 2 ) )
152 ->method( 'setMessages' );
153 $produce->expects( $this->any() )
154 ->method( 'send' )
155 ->will( $this->returnValue( true ) );
156 // evil hax
157 \TestingAccessWrapper::newFromObject( $mockMethod )->matcher->parametersMatcher =
158 new \PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters( [
159 [ $this->anything(), $this->anything(), [ 'words' ] ],
160 [ $this->anything(), $this->anything(), [ 'lines' ] ]
161 ] );
162
163 $formatter = $this->getMock( 'Monolog\Formatter\FormatterInterface' );
164 $formatter->expects( $this->any() )
165 ->method( 'format' )
166 ->will( $this->onConsecutiveCalls( 'words', null, 'lines' ) );
167
168 $handler = new KafkaHandler( $produce, [] );
169 $handler->setFormatter( $formatter );
170 for ( $i = 0; $i < 3; ++$i ) {
171 $handler->handle( [
172 'channel' => 'foo',
173 'level' => Logger::EMERGENCY,
174 'extra' => [],
175 'context' => [],
176 ] );
177 }
178 }
179
180 public function testBatchHandlesNullFormatterResult() {
181 $produce = $this->getMockBuilder( 'Kafka\Produce' )
182 ->disableOriginalConstructor()
183 ->getMock();
184 $produce->expects( $this->any() )
185 ->method( 'getAvailablePartitions' )
186 ->will( $this->returnValue( [ 'A' ] ) );
187 $produce->expects( $this->once() )
188 ->method( 'setMessages' )
189 ->with( $this->anything(), $this->anything(), [ 'words', 'lines' ] );
190 $produce->expects( $this->any() )
191 ->method( 'send' )
192 ->will( $this->returnValue( true ) );
193
194 $formatter = $this->getMock( 'Monolog\Formatter\FormatterInterface' );
195 $formatter->expects( $this->any() )
196 ->method( 'format' )
197 ->will( $this->onConsecutiveCalls( 'words', null, 'lines' ) );
198
199 $handler = new KafkaHandler( $produce, [] );
200 $handler->setFormatter( $formatter );
201 $handler->handleBatch( [
202 [
203 'channel' => 'foo',
204 'level' => Logger::EMERGENCY,
205 'extra' => [],
206 'context' => [],
207 ],
208 [
209 'channel' => 'foo',
210 'level' => Logger::EMERGENCY,
211 'extra' => [],
212 'context' => [],
213 ],
214 [
215 'channel' => 'foo',
216 'level' => Logger::EMERGENCY,
217 'extra' => [],
218 'context' => [],
219 ],
220 ] );
221 }
222 }