MediaWiki  1.23.1
JobQueueTest.php
Go to the documentation of this file.
1 <?php
2 
9  protected $key;
11 
12  function __construct( $name = null, array $data = array(), $dataName = '' ) {
13  parent::__construct( $name, $data, $dataName );
14 
15  $this->tablesUsed[] = 'job';
16  }
17 
18  protected function setUp() {
19  global $wgJobTypeConf;
20  parent::setUp();
21 
22  $this->setMwGlobals( 'wgMemc', new HashBagOStuff() );
23 
24  if ( $this->getCliArg( 'use-jobqueue=' ) ) {
25  $name = $this->getCliArg( 'use-jobqueue=' );
26  if ( !isset( $wgJobTypeConf[$name] ) ) {
27  throw new MWException( "No \$wgJobTypeConf entry for '$name'." );
28  }
29  $baseConfig = $wgJobTypeConf[$name];
30  } else {
31  $baseConfig = array( 'class' => 'JobQueueDB' );
32  }
33  $baseConfig['type'] = 'null';
34  $baseConfig['wiki'] = wfWikiID();
35  $variants = array(
36  'queueRand' => array( 'order' => 'random', 'claimTTL' => 0 ),
37  'queueRandTTL' => array( 'order' => 'random', 'claimTTL' => 10 ),
38  'queueTimestamp' => array( 'order' => 'timestamp', 'claimTTL' => 0 ),
39  'queueTimestampTTL' => array( 'order' => 'timestamp', 'claimTTL' => 10 ),
40  'queueFifo' => array( 'order' => 'fifo', 'claimTTL' => 0 ),
41  'queueFifoTTL' => array( 'order' => 'fifo', 'claimTTL' => 10 ),
42  );
43  foreach ( $variants as $q => $settings ) {
44  try {
45  $this->$q = JobQueue::factory( $settings + $baseConfig );
46  if ( !( $this->$q instanceof JobQueueDB ) ) {
47  $this->$q->setTestingPrefix( 'unittests-' . wfRandomString( 32 ) );
48  }
49  } catch ( MWException $e ) {
50  // unsupported?
51  // @todo What if it was another error?
52  };
53  }
54  }
55 
56  protected function tearDown() {
57  parent::tearDown();
58  foreach (
59  array(
60  'queueRand', 'queueRandTTL', 'queueTimestamp', 'queueTimestampTTL',
61  'queueFifo', 'queueFifoTTL'
62  ) as $q
63  ) {
64  if ( $this->$q ) {
65  $this->$q->delete();
66  }
67  $this->$q = null;
68  }
69  }
70 
75  public function testGetWiki( $queue, $recycles, $desc ) {
76  $queue = $this->$queue;
77  if ( !$queue ) {
78  $this->markTestSkipped( $desc );
79  }
80  $this->assertEquals( wfWikiID(), $queue->getWiki(), "Proper wiki ID ($desc)" );
81  }
82 
87  public function testGetType( $queue, $recycles, $desc ) {
88  $queue = $this->$queue;
89  if ( !$queue ) {
90  $this->markTestSkipped( $desc );
91  }
92  $this->assertEquals( 'null', $queue->getType(), "Proper job type ($desc)" );
93  }
94 
99  public function testBasicOperations( $queue, $recycles, $desc ) {
100  $queue = $this->$queue;
101  if ( !$queue ) {
102  $this->markTestSkipped( $desc );
103  }
104 
105  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
106 
107  $queue->flushCaches();
108  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
109  $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
110 
111  $this->assertTrue( $queue->push( $this->newJob() ), "Push worked ($desc)" );
112  $this->assertTrue( $queue->batchPush( array( $this->newJob() ) ), "Push worked ($desc)" );
113 
114  $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
115 
116  $queue->flushCaches();
117  $this->assertEquals( 2, $queue->getSize(), "Queue size is correct ($desc)" );
118  $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
119  $jobs = iterator_to_array( $queue->getAllQueuedJobs() );
120  $this->assertEquals( 2, count( $jobs ), "Queue iterator size is correct ($desc)" );
121 
122  $job1 = $queue->pop();
123  $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
124 
125  $queue->flushCaches();
126  $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
127 
128  $queue->flushCaches();
129  if ( $recycles ) {
130  $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
131  } else {
132  $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
133  }
134 
135  $job2 = $queue->pop();
136  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
137  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
138 
139  $queue->flushCaches();
140  if ( $recycles ) {
141  $this->assertEquals( 2, $queue->getAcquiredCount(), "Active job count ($desc)" );
142  } else {
143  $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
144  }
145 
146  $queue->ack( $job1 );
147 
148  $queue->flushCaches();
149  if ( $recycles ) {
150  $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
151  } else {
152  $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
153  }
154 
155  $queue->ack( $job2 );
156 
157  $queue->flushCaches();
158  $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
159 
160  $this->assertTrue( $queue->batchPush( array( $this->newJob(), $this->newJob() ) ),
161  "Push worked ($desc)" );
162  $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
163 
164  $queue->delete();
165  $queue->flushCaches();
166  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
167  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
168  }
169 
174  public function testBasicDeduplication( $queue, $recycles, $desc ) {
175  $queue = $this->$queue;
176  if ( !$queue ) {
177  $this->markTestSkipped( $desc );
178  }
179 
180  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
181 
182  $queue->flushCaches();
183  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
184  $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
185 
186  $this->assertTrue(
187  $queue->batchPush(
188  array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() )
189  ),
190  "Push worked ($desc)" );
191 
192  $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
193 
194  $queue->flushCaches();
195  $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
196  $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
197 
198  $this->assertTrue(
199  $queue->batchPush(
200  array( $this->newDedupedJob(), $this->newDedupedJob(), $this->newDedupedJob() )
201  ),
202  "Push worked ($desc)"
203  );
204 
205  $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
206 
207  $queue->flushCaches();
208  $this->assertEquals( 1, $queue->getSize(), "Queue size is correct ($desc)" );
209  $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
210 
211  $job1 = $queue->pop();
212  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
213 
214  $queue->flushCaches();
215  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
216  if ( $recycles ) {
217  $this->assertEquals( 1, $queue->getAcquiredCount(), "Active job count ($desc)" );
218  } else {
219  $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
220  }
221 
222  $queue->ack( $job1 );
223 
224  $queue->flushCaches();
225  $this->assertEquals( 0, $queue->getAcquiredCount(), "Active job count ($desc)" );
226  }
227 
232  public function testRootDeduplication( $queue, $recycles, $desc ) {
233  $queue = $this->$queue;
234  if ( !$queue ) {
235  $this->markTestSkipped( $desc );
236  }
237 
238  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
239 
240  $queue->flushCaches();
241  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
242  $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
243 
244  $id = wfRandomString( 32 );
245  $root1 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
246  for ( $i = 0; $i < 5; ++$i ) {
247  $this->assertTrue( $queue->push( $this->newJob( 0, $root1 ) ), "Push worked ($desc)" );
248  }
249  $queue->deduplicateRootJob( $this->newJob( 0, $root1 ) );
250  sleep( 1 ); // roo job timestamp will increase
251  $root2 = Job::newRootJobParams( "nulljobspam:$id" ); // task ID/timestamp
252  $this->assertNotEquals( $root1['rootJobTimestamp'], $root2['rootJobTimestamp'],
253  "Root job signatures have different timestamps." );
254  for ( $i = 0; $i < 5; ++$i ) {
255  $this->assertTrue( $queue->push( $this->newJob( 0, $root2 ) ), "Push worked ($desc)" );
256  }
257  $queue->deduplicateRootJob( $this->newJob( 0, $root2 ) );
258 
259  $this->assertFalse( $queue->isEmpty(), "Queue is not empty ($desc)" );
260 
261  $queue->flushCaches();
262  $this->assertEquals( 10, $queue->getSize(), "Queue size is correct ($desc)" );
263  $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
264 
265  $dupcount = 0;
266  $jobs = array();
267  do {
268  $job = $queue->pop();
269  if ( $job ) {
270  $jobs[] = $job;
271  $queue->ack( $job );
272  }
273  if ( $job instanceof DuplicateJob ) {
274  ++$dupcount;
275  }
276  } while ( $job );
277 
278  $this->assertEquals( 10, count( $jobs ), "Correct number of jobs popped ($desc)" );
279  $this->assertEquals( 5, $dupcount, "Correct number of duplicate jobs popped ($desc)" );
280  }
281 
286  public function testJobOrder( $queue, $recycles, $desc ) {
287  $queue = $this->$queue;
288  if ( !$queue ) {
289  $this->markTestSkipped( $desc );
290  }
291 
292  $this->assertTrue( $queue->isEmpty(), "Queue is empty ($desc)" );
293 
294  $queue->flushCaches();
295  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
296  $this->assertEquals( 0, $queue->getAcquiredCount(), "Queue is empty ($desc)" );
297 
298  for ( $i = 0; $i < 10; ++$i ) {
299  $this->assertTrue( $queue->push( $this->newJob( $i ) ), "Push worked ($desc)" );
300  }
301 
302  for ( $i = 0; $i < 10; ++$i ) {
303  $job = $queue->pop();
304  $this->assertTrue( $job instanceof Job, "Jobs popped from queue ($desc)" );
305  $params = $job->getParams();
306  $this->assertEquals( $i, $params['i'], "Job popped from queue is FIFO ($desc)" );
307  $queue->ack( $job );
308  }
309 
310  $this->assertFalse( $queue->pop(), "Queue is not empty ($desc)" );
311 
312  $queue->flushCaches();
313  $this->assertEquals( 0, $queue->getSize(), "Queue is empty ($desc)" );
314  $this->assertEquals( 0, $queue->getAcquiredCount(), "No jobs active ($desc)" );
315  }
316 
317  public static function provider_queueLists() {
318  return array(
319  array( 'queueRand', false, 'Random queue without ack()' ),
320  array( 'queueRandTTL', true, 'Random queue with ack()' ),
321  array( 'queueTimestamp', false, 'Time ordered queue without ack()' ),
322  array( 'queueTimestampTTL', true, 'Time ordered queue with ack()' ),
323  array( 'queueFifo', false, 'FIFO ordered queue without ack()' ),
324  array( 'queueFifoTTL', true, 'FIFO ordered queue with ack()' )
325  );
326  }
327 
328  public static function provider_fifoQueueLists() {
329  return array(
330  array( 'queueFifo', false, 'Ordered queue without ack()' ),
331  array( 'queueFifoTTL', true, 'Ordered queue with ack()' )
332  );
333  }
334 
335  function newJob( $i = 0, $rootJob = array() ) {
336  return new NullJob( Title::newMainPage(),
337  array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 0, 'i' => $i ) + $rootJob );
338  }
339 
340  function newDedupedJob( $i = 0, $rootJob = array() ) {
341  return new NullJob( Title::newMainPage(),
342  array( 'lives' => 0, 'usleep' => 0, 'removeDuplicates' => 1, 'i' => $i ) + $rootJob );
343  }
344 }
JobQueueTest\$key
$key
Definition: JobQueueTest.php:9
JobQueueTest\provider_fifoQueueLists
static provider_fifoQueueLists()
Definition: JobQueueTest.php:328
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
HashBagOStuff
This is a test of the interface, mainly.
Definition: HashBagOStuff.php:30
JobQueueTest\$queueRandTTL
$queueRandTTL
Definition: JobQueueTest.php:10
Title\newMainPage
static newMainPage()
Create a new Title for the Main Page.
Definition: Title.php:441
JobQueueTest\testGetWiki
testGetWiki( $queue, $recycles, $desc)
@dataProvider provider_queueLists @covers JobQueue::getWiki
Definition: JobQueueTest.php:75
$params
$params
Definition: styleTest.css.php:40
MediaWikiTestCase\getCliArg
getCliArg( $offset)
Definition: MediaWikiTestCase.php:658
NullJob
Degenerate job that does nothing, but can optionally replace itself in the queue and/or sleep for a b...
Definition: NullJob.php:47
JobQueueTest\testBasicDeduplication
testBasicDeduplication( $queue, $recycles, $desc)
@dataProvider provider_queueLists @covers JobQueue
Definition: JobQueueTest.php:174
JobQueueDB
Class to handle job queues stored in the DB.
Definition: JobQueueDB.php:30
JobQueueTest\$queueFifoTTL
$queueFifoTTL
Definition: JobQueueTest.php:10
Job
Class to both describe a background job and handle jobs.
Definition: Job.php:31
JobQueueTest\testJobOrder
testJobOrder( $queue, $recycles, $desc)
@dataProvider provider_fifoQueueLists @covers JobQueue
Definition: JobQueueTest.php:286
MWException
MediaWiki exception.
Definition: MWException.php:26
MediaWikiTestCase\setMwGlobals
setMwGlobals( $pairs, $value=null)
Definition: MediaWikiTestCase.php:302
MediaWikiTestCase
Definition: MediaWikiTestCase.php:6
JobQueueTest\__construct
__construct( $name=null, array $data=array(), $dataName='')
Definition: JobQueueTest.php:12
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
JobQueueTest\setUp
setUp()
Definition: JobQueueTest.php:18
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
Job\newRootJobParams
static newRootJobParams( $key)
Definition: Job.php:239
DuplicateJob
No-op job that does nothing.
Definition: DuplicateJob.php:29
JobQueueTest\testBasicOperations
testBasicOperations( $queue, $recycles, $desc)
@dataProvider provider_queueLists @covers JobQueue
Definition: JobQueueTest.php:99
JobQueueTest\$queueFifo
$queueFifo
Definition: JobQueueTest.php:10
wfWikiID
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
Definition: GlobalFunctions.php:3604
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
JobQueueTest\provider_queueLists
static provider_queueLists()
Definition: JobQueueTest.php:317
JobQueueTest\testGetType
testGetType( $queue, $recycles, $desc)
@dataProvider provider_queueLists @covers JobQueue::getType
Definition: JobQueueTest.php:87
JobQueue\factory
static factory(array $params)
Get a job queue object of the specified type.
Definition: JobQueue.php:105
JobQueueTest\testRootDeduplication
testRootDeduplication( $queue, $recycles, $desc)
@dataProvider provider_queueLists @covers JobQueue
Definition: JobQueueTest.php:232
JobQueueTest\newJob
newJob( $i=0, $rootJob=array())
Definition: JobQueueTest.php:335
JobQueueTest\newDedupedJob
newDedupedJob( $i=0, $rootJob=array())
Definition: JobQueueTest.php:340
JobQueueTest\$queueRand
$queueRand
Definition: JobQueueTest.php:10
JobQueueTest\tearDown
tearDown()
Definition: JobQueueTest.php:56
$job
if(count( $args)< 1) $job
Definition: recompressTracked.php:42
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
JobQueueTest
@group JobQueue @group medium @group Database
Definition: JobQueueTest.php:8
$e
if( $useReadline) $e
Definition: eval.php:66
wfRandomString
wfRandomString( $length=32)
Get a random string containing a number of pseudo-random hex characters.
Definition: GlobalFunctions.php:300