3 use MediaWiki\MediaWikiServices
;
5 class DeferredUpdatesTest
extends MediaWikiTestCase
{
8 * @covers DeferredUpdates::addUpdate
9 * @covers DeferredUpdates::push
10 * @covers DeferredUpdates::doUpdates
11 * @covers DeferredUpdates::execute
12 * @covers DeferredUpdates::runUpdate
14 public function testAddAndRun() {
15 $update = $this->getMockBuilder( DeferrableUpdate
::class )
16 ->setMethods( [ 'doUpdate' ] )->getMock();
17 $update->expects( $this->once() )->method( 'doUpdate' );
19 DeferredUpdates
::addUpdate( $update );
20 DeferredUpdates
::doUpdates();
24 * @covers DeferredUpdates::addUpdate
25 * @covers DeferredUpdates::push
27 public function testAddMergeable() {
28 $this->setMwGlobals( 'wgCommandLineMode', false );
30 $update1 = $this->getMockBuilder( MergeableUpdate
::class )
31 ->setMethods( [ 'merge', 'doUpdate' ] )->getMock();
32 $update1->expects( $this->once() )->method( 'merge' );
33 $update1->expects( $this->never() )->method( 'doUpdate' );
35 $update2 = $this->getMockBuilder( MergeableUpdate
::class )
36 ->setMethods( [ 'merge', 'doUpdate' ] )->getMock();
37 $update2->expects( $this->never() )->method( 'merge' );
38 $update2->expects( $this->never() )->method( 'doUpdate' );
40 DeferredUpdates
::addUpdate( $update1 );
41 DeferredUpdates
::addUpdate( $update2 );
45 * @covers DeferredUpdates::addCallableUpdate
46 * @covers MWCallableUpdate::getOrigin
48 public function testAddCallableUpdate() {
49 $this->setMwGlobals( 'wgCommandLineMode', true );
52 DeferredUpdates
::addCallableUpdate( function () use ( &$ran ) {
55 DeferredUpdates
::doUpdates();
57 $this->assertSame( 1, $ran, 'Update ran' );
61 * @covers DeferredUpdates::getPendingUpdates
62 * @covers DeferredUpdates::clearPendingUpdates
64 public function testGetPendingUpdates() {
65 // Prevent updates from running
66 $this->setMwGlobals( 'wgCommandLineMode', false );
68 $pre = DeferredUpdates
::PRESEND
;
69 $post = DeferredUpdates
::POSTSEND
;
70 $all = DeferredUpdates
::ALL
;
72 $update = $this->getMock( DeferrableUpdate
::class );
73 $update->expects( $this->never() )
74 ->method( 'doUpdate' );
76 DeferredUpdates
::addUpdate( $update, $pre );
77 $this->assertCount( 1, DeferredUpdates
::getPendingUpdates( $pre ) );
78 $this->assertCount( 0, DeferredUpdates
::getPendingUpdates( $post ) );
79 $this->assertCount( 1, DeferredUpdates
::getPendingUpdates( $all ) );
80 $this->assertCount( 1, DeferredUpdates
::getPendingUpdates() );
81 DeferredUpdates
::clearPendingUpdates();
82 $this->assertCount( 0, DeferredUpdates
::getPendingUpdates() );
84 DeferredUpdates
::addUpdate( $update, $post );
85 $this->assertCount( 0, DeferredUpdates
::getPendingUpdates( $pre ) );
86 $this->assertCount( 1, DeferredUpdates
::getPendingUpdates( $post ) );
87 $this->assertCount( 1, DeferredUpdates
::getPendingUpdates( $all ) );
88 $this->assertCount( 1, DeferredUpdates
::getPendingUpdates() );
89 DeferredUpdates
::clearPendingUpdates();
90 $this->assertCount( 0, DeferredUpdates
::getPendingUpdates() );
94 * @covers DeferredUpdates::doUpdates
95 * @covers DeferredUpdates::execute
96 * @covers DeferredUpdates::addUpdate
98 public function testDoUpdatesWeb() {
99 $this->setMwGlobals( 'wgCommandLineMode', false );
102 '1' => "deferred update 1;\n",
103 '2' => "deferred update 2;\n",
104 '2-1' => "deferred update 1 within deferred update 2;\n",
105 '2-2' => "deferred update 2 within deferred update 2;\n",
106 '3' => "deferred update 3;\n",
107 '3-1' => "deferred update 1 within deferred update 3;\n",
108 '3-2' => "deferred update 2 within deferred update 3;\n",
109 '3-1-1' => "deferred update 1 within deferred update 1 within deferred update 3;\n",
110 '3-2-1' => "deferred update 1 within deferred update 2 with deferred update 3;\n",
112 DeferredUpdates
::addCallableUpdate(
113 function () use ( $updates ) {
117 DeferredUpdates
::addCallableUpdate(
118 function () use ( $updates ) {
120 DeferredUpdates
::addCallableUpdate(
121 function () use ( $updates ) {
122 echo $updates['2-1'];
125 DeferredUpdates
::addCallableUpdate(
126 function () use ( $updates ) {
127 echo $updates['2-2'];
132 DeferredUpdates
::addCallableUpdate(
133 function () use ( $updates ) {
135 DeferredUpdates
::addCallableUpdate(
136 function () use ( $updates ) {
137 echo $updates['3-1'];
138 DeferredUpdates
::addCallableUpdate(
139 function () use ( $updates ) {
140 echo $updates['3-1-1'];
145 DeferredUpdates
::addCallableUpdate(
146 function () use ( $updates ) {
147 echo $updates['3-2'];
148 DeferredUpdates
::addCallableUpdate(
149 function () use ( $updates ) {
150 echo $updates['3-2-1'];
158 $this->assertEquals( 3, DeferredUpdates
::pendingUpdatesCount() );
160 $this->expectOutputString( implode( '', $updates ) );
162 DeferredUpdates
::doUpdates();
166 DeferredUpdates
::addCallableUpdate(
167 function () use ( &$x ) {
170 DeferredUpdates
::PRESEND
172 DeferredUpdates
::addCallableUpdate(
173 function () use ( &$y ) {
176 DeferredUpdates
::POSTSEND
179 $this->assertNull( $x, "Update not run yet" );
180 $this->assertNull( $y, "Update not run yet" );
182 DeferredUpdates
::doUpdates( 'run', DeferredUpdates
::PRESEND
);
183 $this->assertEquals( "Sherity", $x, "PRESEND update ran" );
184 $this->assertNull( $y, "POSTSEND update not run yet" );
186 DeferredUpdates
::doUpdates( 'run', DeferredUpdates
::POSTSEND
);
187 $this->assertEquals( "Marychu", $y, "POSTSEND update ran" );
191 * @covers DeferredUpdates::doUpdates
192 * @covers DeferredUpdates::execute
193 * @covers DeferredUpdates::addUpdate
195 public function testDoUpdatesCLI() {
196 $this->setMwGlobals( 'wgCommandLineMode', true );
198 '1' => "deferred update 1;\n",
199 '2' => "deferred update 2;\n",
200 '2-1' => "deferred update 1 within deferred update 2;\n",
201 '2-2' => "deferred update 2 within deferred update 2;\n",
202 '3' => "deferred update 3;\n",
203 '3-1' => "deferred update 1 within deferred update 3;\n",
204 '3-2' => "deferred update 2 within deferred update 3;\n",
205 '3-1-1' => "deferred update 1 within deferred update 1 within deferred update 3;\n",
206 '3-2-1' => "deferred update 1 within deferred update 2 with deferred update 3;\n",
210 wfGetLBFactory()->commitMasterChanges( __METHOD__
);
212 DeferredUpdates
::addCallableUpdate(
213 function () use ( $updates ) {
217 DeferredUpdates
::addCallableUpdate(
218 function () use ( $updates ) {
220 DeferredUpdates
::addCallableUpdate(
221 function () use ( $updates ) {
222 echo $updates['2-1'];
225 DeferredUpdates
::addCallableUpdate(
226 function () use ( $updates ) {
227 echo $updates['2-2'];
232 DeferredUpdates
::addCallableUpdate(
233 function () use ( $updates ) {
235 DeferredUpdates
::addCallableUpdate(
236 function () use ( $updates ) {
237 echo $updates['3-1'];
238 DeferredUpdates
::addCallableUpdate(
239 function () use ( $updates ) {
240 echo $updates['3-1-1'];
245 DeferredUpdates
::addCallableUpdate(
246 function () use ( $updates ) {
247 echo $updates['3-2'];
248 DeferredUpdates
::addCallableUpdate(
249 function () use ( $updates ) {
250 echo $updates['3-2-1'];
258 $this->expectOutputString( implode( '', $updates ) );
260 DeferredUpdates
::doUpdates();
264 * @covers DeferredUpdates::doUpdates
265 * @covers DeferredUpdates::execute
266 * @covers DeferredUpdates::addUpdate
268 public function testPresendAddOnPostsendRun() {
269 $this->setMwGlobals( 'wgCommandLineMode', true );
274 wfGetLBFactory()->commitMasterChanges( __METHOD__
);
276 DeferredUpdates
::addCallableUpdate(
277 function () use ( &$x, &$y ) {
279 DeferredUpdates
::addCallableUpdate(
280 function () use ( &$y ) {
283 DeferredUpdates
::PRESEND
286 DeferredUpdates
::POSTSEND
289 DeferredUpdates
::doUpdates();
291 $this->assertTrue( $x, "Outer POSTSEND update ran" );
292 $this->assertTrue( $y, "Nested PRESEND update ran" );
296 * @covers DeferredUpdates::runUpdate
298 public function testRunUpdateTransactionScope() {
299 $this->setMwGlobals( 'wgCommandLineMode', false );
301 $lbFactory = MediaWikiServices
::getInstance()->getDBLoadBalancerFactory();
302 $this->assertFalse( $lbFactory->hasTransactionRound(), 'Initial state' );
305 DeferredUpdates
::addCallableUpdate( function () use ( &$ran, $lbFactory ) {
307 $this->assertTrue( $lbFactory->hasTransactionRound(), 'Has transaction' );
309 DeferredUpdates
::doUpdates();
311 $this->assertSame( 1, $ran, 'Update ran' );
312 $this->assertFalse( $lbFactory->hasTransactionRound(), 'Final state' );
316 * @covers DeferredUpdates::runUpdate
317 * @covers TransactionRoundDefiningUpdate::getOrigin
319 public function testRunOuterScopeUpdate() {
320 $this->setMwGlobals( 'wgCommandLineMode', false );
322 $lbFactory = MediaWikiServices
::getInstance()->getDBLoadBalancerFactory();
323 $this->assertFalse( $lbFactory->hasTransactionRound(), 'Initial state' );
326 DeferredUpdates
::addUpdate( new TransactionRoundDefiningUpdate(
327 function () use ( &$ran, $lbFactory ) {
329 $this->assertFalse( $lbFactory->hasTransactionRound(), 'No transaction' );
332 DeferredUpdates
::doUpdates();
334 $this->assertSame( 1, $ran, 'Update ran' );