* Fixed 'success' value of doOperations() Status to match documentation.
[lhc/web/wiklou.git] / tests / phpunit / includes / filerepo / FileBackendTest.php
1 <?php
2
3 // @TODO: fix empty dir leakage
4 class FileBackendTest extends MediaWikiTestCase {
5 private $backend, $multiBackend;
6 private $filesToPrune, $pathsToPrune;
7
8 function setUp() {
9 parent::setUp();
10 $tmpDir = wfTempDir() . '/' . time() . '-' . mt_rand();
11 $this->singleBackend = new FSFileBackend( array(
12 'name' => 'localtesting',
13 'lockManager' => 'fsLockManager',
14 'containerPaths' => array(
15 'cont1' => "$tmpDir/localtesting/cont1",
16 'cont2' => "$tmpDir/localtesting/cont2" )
17 ) );
18 $this->multiBackend = new FileBackendMultiWrite( array(
19 'name' => 'localtesting',
20 'lockManager' => 'fsLockManager',
21 'backends' => array(
22 array(
23 'name' => 'localmutlitesting1',
24 'class' => 'FSFileBackend',
25 'lockManager' => 'nullLockManager',
26 'containerPaths' => array(
27 'cont1' => "$tmpDir/localtestingmulti1/cont1",
28 'cont2' => "$tmpDir/localtestingmulti1/cont2" ),
29 'isMultiMaster' => false
30 ),
31 array(
32 'name' => 'localmutlitesting2',
33 'class' => 'FSFileBackend',
34 'lockManager' => 'nullLockManager',
35 'containerPaths' => array(
36 'cont1' => "$tmpDir/localtestingmulti2/cont1",
37 'cont2' => "$tmpDir/localtestingmulti2/cont2" ),
38 'isMultiMaster' => true
39 )
40 )
41 ) );
42 $this->filesToPrune = $this->pathsToPrune = array();
43 }
44
45 private function baseStorePath() {
46 return 'mwstore://localtesting';
47 }
48
49 private function backendClass() {
50 return get_class( $this->backend );
51 }
52
53 /**
54 * @dataProvider provider_testStore
55 */
56 public function testStore( $op, $source, $dest ) {
57 $this->filesToPrune[] = $source;
58 $this->pathsToPrune[] = $dest;
59
60 $this->backend = $this->singleBackend;
61 $this->doTestStore( $op, $source, $dest );
62 $this->tearDownFiles();
63
64 $this->backend = $this->multiBackend;
65 $this->doTestStore( $op, $source, $dest );
66 $this->tearDownFiles();
67 }
68
69 function doTestStore( $op, $source, $dest ) {
70 $backendName = $this->backendClass();
71
72 file_put_contents( $source, "Unit test file" );
73 $status = $this->backend->doOperation( $op );
74
75 $this->assertEquals( array(), $status->errors,
76 "Store from $source to $dest succeeded without warnings ($backendName)." );
77 $this->assertEquals( true, $status->isOK(),
78 "Store from $source to $dest succeeded ($backendName)." );
79 $this->assertEquals( array( 0 => true ), $status->success,
80 "Store from $source to $dest has proper 'success' field in Status ($backendName)." );
81 $this->assertEquals( true, file_exists( $source ),
82 "Source file $source still exists ($backendName)." );
83 $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ),
84 "Destination file $dest exists ($backendName)." );
85
86 $this->assertEquals( filesize( $source ),
87 $this->backend->getFileSize( array( 'src' => $dest ) ),
88 "Destination file $dest has correct size ($backendName)." );
89
90 $props1 = FSFile::getPropsFromPath( $source );
91 $props2 = $this->backend->getFileProps( array( 'src' => $dest ) );
92 $this->assertEquals( $props1, $props2,
93 "Source and destination have the same props ($backendName)." );
94 }
95
96 public function provider_testStore() {
97 $cases = array();
98
99 $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath();
100 $toPath = $this->baseStorePath() . '/cont1/fun/obj1.txt';
101 $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath );
102 $cases[] = array(
103 $op, // operation
104 $tmpName, // source
105 $toPath, // dest
106 );
107
108 $op['overwriteDest'] = true;
109 $cases[] = array(
110 $op, // operation
111 $tmpName, // source
112 $toPath, // dest
113 );
114
115 return $cases;
116 }
117
118 /**
119 * @dataProvider provider_testCopy
120 */
121 public function testCopy( $op, $source, $dest ) {
122 $this->pathsToPrune[] = $source;
123 $this->pathsToPrune[] = $dest;
124
125 $this->backend = $this->singleBackend;
126 $this->doTestCopy( $op, $source, $dest );
127 $this->tearDownFiles();
128
129 $this->backend = $this->multiBackend;
130 $this->doTestCopy( $op, $source, $dest );
131 $this->tearDownFiles();
132 }
133
134 function doTestCopy( $op, $source, $dest ) {
135 $backendName = $this->backendClass();
136
137 $status = $this->backend->doOperation(
138 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
139 $this->assertEquals( true, $status->isOK(),
140 "Creation of file at $source succeeded ($backendName)." );
141
142 $status = $this->backend->doOperation( $op );
143 $this->assertEquals( array(), $status->errors,
144 "Copy from $source to $dest succeeded without warnings ($backendName)." );
145 $this->assertEquals( true, $status->isOK(),
146 "Copy from $source to $dest succeeded ($backendName)." );
147 $this->assertEquals( array( 0 => true ), $status->success,
148 "Copy from $source to $dest has proper 'success' field in Status ($backendName)." );
149 $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $source ) ),
150 "Source file $source still exists ($backendName)." );
151 $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ),
152 "Destination file $dest exists after copy ($backendName)." );
153
154 $this->assertEquals(
155 $this->backend->getFileSize( array( 'src' => $source ) ),
156 $this->backend->getFileSize( array( 'src' => $dest ) ),
157 "Destination file $dest has correct size ($backendName)." );
158
159 $props1 = $this->backend->getFileProps( array( 'src' => $source ) );
160 $props2 = $this->backend->getFileProps( array( 'src' => $dest ) );
161 $this->assertEquals( $props1, $props2,
162 "Source and destination have the same props ($backendName)." );
163 }
164
165 public function provider_testCopy() {
166 $cases = array();
167
168 $source = $this->baseStorePath() . '/cont1/file.txt';
169 $dest = $this->baseStorePath() . '/cont2/fileMoved.txt';
170
171 $op = array( 'op' => 'copy', 'src' => $source, 'dst' => $dest );
172 $cases[] = array(
173 $op, // operation
174 $source, // source
175 $dest, // dest
176 );
177
178 $op['overwriteDest'] = true;
179 $cases[] = array(
180 $op, // operation
181 $source, // source
182 $dest, // dest
183 );
184
185 return $cases;
186 }
187
188 /**
189 * @dataProvider provider_testMove
190 */
191 public function testMove( $op, $source, $dest ) {
192 $this->pathsToPrune[] = $source;
193 $this->pathsToPrune[] = $dest;
194
195 $this->backend = $this->singleBackend;
196 $this->doTestMove( $op, $source, $dest );
197 $this->tearDownFiles();
198
199 $this->backend = $this->multiBackend;
200 $this->doTestMove( $op, $source, $dest );
201 $this->tearDownFiles();
202 }
203
204 public function doTestMove( $op, $source, $dest ) {
205 $backendName = $this->backendClass();
206
207 $status = $this->backend->doOperation(
208 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
209 $this->assertEquals( true, $status->isOK(),
210 "Creation of file at $source succeeded ($backendName)." );
211
212 $status = $this->backend->doOperation( $op );
213 $this->assertEquals( array(), $status->errors,
214 "Move from $source to $dest succeeded without warnings ($backendName)." );
215 $this->assertEquals( true, $status->isOK(),
216 "Move from $source to $dest succeeded ($backendName)." );
217 $this->assertEquals( array( 0 => true ), $status->success,
218 "Move from $source to $dest has proper 'success' field in Status ($backendName)." );
219 $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ),
220 "Source file $source does not still exists ($backendName)." );
221 $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ),
222 "Destination file $dest exists after move ($backendName)." );
223
224 $this->assertNotEquals(
225 $this->backend->getFileSize( array( 'src' => $source ) ),
226 $this->backend->getFileSize( array( 'src' => $dest ) ),
227 "Destination file $dest has correct size ($backendName)." );
228
229 $props1 = $this->backend->getFileProps( array( 'src' => $source ) );
230 $props2 = $this->backend->getFileProps( array( 'src' => $dest ) );
231 $this->assertEquals( false, $props1['fileExists'],
232 "Source file does not exist accourding to props ($backendName)." );
233 $this->assertEquals( true, $props2['fileExists'],
234 "Destination file exists accourding to props ($backendName)." );
235 }
236
237 public function provider_testMove() {
238 $cases = array();
239
240 $source = $this->baseStorePath() . '/cont1/file.txt';
241 $dest = $this->baseStorePath() . '/cont2/fileMoved.txt';
242
243 $op = array( 'op' => 'move', 'src' => $source, 'dst' => $dest );
244 $cases[] = array(
245 $op, // operation
246 $source, // source
247 $dest, // dest
248 );
249
250 $op['overwriteDest'] = true;
251 $cases[] = array(
252 $op, // operation
253 $source, // source
254 $dest, // dest
255 );
256
257 return $cases;
258 }
259
260 /**
261 * @dataProvider provider_testDelete
262 */
263 public function testDelete( $op, $source, $withSource, $okStatus ) {
264 $this->pathsToPrune[] = $source;
265
266 $this->backend = $this->singleBackend;
267 $this->doTestDelete( $op, $source, $withSource, $okStatus );
268 $this->tearDownFiles();
269
270 $this->backend = $this->multiBackend;
271 $this->doTestDelete( $op, $source, $withSource, $okStatus );
272 $this->tearDownFiles();
273 }
274
275 public function doTestDelete( $op, $source, $withSource, $okStatus ) {
276 $backendName = $this->backendClass();
277
278 if ( $withSource ) {
279 $status = $this->backend->doOperation(
280 array( 'op' => 'create', 'content' => 'blahblah', 'dst' => $source ) );
281 $this->assertEquals( true, $status->isOK(),
282 "Creation of file at $source succeeded ($backendName)." );
283 }
284
285 $status = $this->backend->doOperation( $op );
286 if ( $okStatus ) {
287 $this->assertEquals( array(), $status->errors,
288 "Deletion of file at $source succeeded without warnings ($backendName)." );
289 $this->assertEquals( true, $status->isOK(),
290 "Deletion of file at $source succeeded ($backendName)." );
291 $this->assertEquals( array( 0 => true ), $status->success,
292 "Deletion of file at $source has proper 'success' field in Status ($backendName)." );
293 } else {
294 $this->assertEquals( false, $status->isOK(),
295 "Deletion of file at $source failed ($backendName)." );
296 }
297
298 $this->assertEquals( false, $this->backend->fileExists( array( 'src' => $source ) ),
299 "Source file $source does not exist after move ($backendName)." );
300
301 $this->assertFalse(
302 $this->backend->getFileSize( array( 'src' => $source ) ),
303 "Source file $source has correct size (false) ($backendName)." );
304
305 $props1 = $this->backend->getFileProps( array( 'src' => $source ) );
306 $this->assertFalse( $props1['fileExists'],
307 "Source file $source does not exist according to props ($backendName)." );
308 }
309
310 public function provider_testDelete() {
311 $cases = array();
312
313 $source = $this->baseStorePath() . '/cont1/myfacefile.txt';
314
315 $op = array( 'op' => 'delete', 'src' => $source );
316 $cases[] = array(
317 $op, // operation
318 $source, // source
319 true, // with source
320 true // succeeds
321 );
322
323 $cases[] = array(
324 $op, // operation
325 $source, // source
326 false, // without source
327 false // fails
328 );
329
330 $op['ignoreMissingSource'] = true;
331 $cases[] = array(
332 $op, // operation
333 $source, // source
334 false, // without source
335 true // succeeds
336 );
337
338 return $cases;
339 }
340
341 /**
342 * @dataProvider provider_testCreate
343 */
344 public function testCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) {
345 $this->pathsToPrune[] = $dest;
346
347 $this->backend = $this->singleBackend;
348 $this->doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize );
349 $this->tearDownFiles();
350
351 $this->backend = $this->multiBackend;
352 $this->doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize );
353 $this->tearDownFiles();
354 }
355
356 public function doTestCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) {
357 $backendName = $this->backendClass();
358
359 $oldText = 'blah...blah...waahwaah';
360 if ( $alreadyExists ) {
361 $status = $this->backend->doOperation(
362 array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) );
363 $this->assertEquals( true, $status->isOK(),
364 "Creation of file at $dest succeeded ($backendName)." );
365 }
366
367 $status = $this->backend->doOperation( $op );
368 if ( $okStatus ) {
369 $this->assertEquals( array(), $status->errors,
370 "Creation of file at $dest succeeded without warnings ($backendName)." );
371 $this->assertEquals( true, $status->isOK(),
372 "Creation of file at $dest succeeded ($backendName)." );
373 $this->assertEquals( array( 0 => true ), $status->success,
374 "Creation of file at $dest has proper 'success' field in Status ($backendName)." );
375 } else {
376 $this->assertEquals( false, $status->isOK(),
377 "Creation of file at $dest failed ($backendName)." );
378 }
379
380 $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ),
381 "Destination file $dest exists after creation ($backendName)." );
382
383 $props1 = $this->backend->getFileProps( array( 'src' => $dest ) );
384 $this->assertEquals( true, $props1['fileExists'],
385 "Destination file $dest exists according to props ($backendName)." );
386 if ( $okStatus ) { // file content is what we saved
387 $this->assertEquals( $newSize, $props1['size'],
388 "Destination file $dest has expected size according to props ($backendName)." );
389 $this->assertEquals( $newSize,
390 $this->backend->getFileSize( array( 'src' => $dest ) ),
391 "Destination file $dest has correct size ($backendName)." );
392 } else { // file content is some other previous text
393 $this->assertEquals( strlen( $oldText ), $props1['size'],
394 "Destination file $dest has original size according to props ($backendName)." );
395 $this->assertEquals( strlen( $oldText ),
396 $this->backend->getFileSize( array( 'src' => $dest ) ),
397 "Destination file $dest has original size according to props ($backendName)." );
398 }
399 }
400
401 /**
402 * @dataProvider provider_testCreate
403 */
404 public function provider_testCreate() {
405 $cases = array();
406
407 $source = $this->baseStorePath() . '/cont2/myspacefile.txt';
408
409 $dummyText = 'hey hey';
410 $op = array( 'op' => 'create', 'content' => $dummyText, 'dst' => $source );
411 $cases[] = array(
412 $op, // operation
413 $source, // source
414 false, // no dest already exists
415 true, // succeeds
416 strlen( $dummyText )
417 );
418
419 $cases[] = array(
420 $op, // operation
421 $source, // source
422 true, // dest already exists
423 false, // fails
424 strlen( $dummyText )
425 );
426
427 $op['overwriteDest'] = true;
428 $cases[] = array(
429 $op, // operation
430 $source, // source
431 true, // dest already exists
432 true, // succeeds
433 strlen( $dummyText )
434 );
435
436 return $cases;
437 }
438
439 /**
440 * @dataProvider provider_testConcatenate
441 */
442 public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
443 $this->pathsToPrune = array_merge( $this->pathsToPrune, $srcs );
444 $this->filesToPrune[] = $op['dst'];
445
446 $this->backend = $this->singleBackend;
447 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
448 $this->tearDownFiles();
449
450 $this->backend = $this->multiBackend;
451 $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
452 $this->tearDownFiles();
453 }
454
455 public function doTestConcatenate( $params, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
456 $backendName = $this->backendClass();
457
458 $expContent = '';
459 // Create sources
460 $ops = array();
461 foreach ( $srcs as $i => $source ) {
462 $ops[] = array(
463 'op' => 'create', // operation
464 'dst' => $source, // source
465 'content' => $srcsContent[$i]
466 );
467 $expContent .= $srcsContent[$i];
468 }
469 $status = $this->backend->doOperations( $ops );
470
471 $this->assertEquals( true, $status->isOK(),
472 "Creation of source files succeeded ($backendName)." );
473
474 $dest = $params['dst'];
475 if ( $alreadyExists ) {
476 $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false;
477 $this->assertEquals( true, $ok,
478 "Creation of file at $dest succeeded ($backendName)." );
479 } else {
480 $ok = file_put_contents( $dest, '' ) !== false;
481 $this->assertEquals( true, $ok,
482 "Creation of 0-byte file at $dest succeeded ($backendName)." );
483 }
484
485 // Combine the files into one
486 $status = $this->backend->concatenate( $params );
487 if ( $okStatus ) {
488 $this->assertEquals( array(), $status->errors,
489 "Creation of concat file at $dest succeeded without warnings ($backendName)." );
490 $this->assertEquals( true, $status->isOK(),
491 "Creation of concat file at $dest succeeded ($backendName)." );
492 } else {
493 $this->assertEquals( false, $status->isOK(),
494 "Creation of concat file at $dest failed ($backendName)." );
495 }
496
497 if ( $okStatus ) {
498 $this->assertEquals( true, is_file( $dest ),
499 "Dest concat file $dest exists after creation ($backendName)." );
500 } else {
501 $this->assertEquals( true, is_file( $dest ),
502 "Dest concat file $dest exists after failed creation ($backendName)." );
503 }
504
505 $contents = file_get_contents( $dest );
506 $this->assertNotEquals( false, $contents, "File at $dest exists ($backendName)." );
507
508 if ( $okStatus ) {
509 $this->assertEquals( $expContent, $contents,
510 "Concat file at $dest has correct contents ($backendName)." );
511 } else {
512 $this->assertNotEquals( $expContent, $contents,
513 "Concat file at $dest has correct contents ($backendName)." );
514 }
515 }
516
517 function provider_testConcatenate() {
518 $cases = array();
519
520 $rand = mt_rand( 0, 2000000000 ) . time();
521 $dest = wfTempDir() . "/randomfile!$rand.txt";
522 $srcs = array(
523 $this->baseStorePath() . '/cont1/file1.txt',
524 $this->baseStorePath() . '/cont1/file2.txt',
525 $this->baseStorePath() . '/cont1/file3.txt',
526 $this->baseStorePath() . '/cont1/file4.txt',
527 $this->baseStorePath() . '/cont1/file5.txt',
528 $this->baseStorePath() . '/cont1/file6.txt',
529 $this->baseStorePath() . '/cont1/file7.txt',
530 $this->baseStorePath() . '/cont1/file8.txt',
531 $this->baseStorePath() . '/cont1/file9.txt',
532 $this->baseStorePath() . '/cont1/file10.txt'
533 );
534 $content = array(
535 'egfage',
536 'ageageag',
537 'rhokohlr',
538 'shgmslkg',
539 'kenga',
540 'owagmal',
541 'kgmae',
542 'g eak;g',
543 'lkaem;a',
544 'legma'
545 );
546 $params = array( 'srcs' => $srcs, 'dst' => $dest );
547
548 $cases[] = array(
549 $params, // operation
550 $srcs, // sources
551 $content, // content for each source
552 false, // no dest already exists
553 true, // succeeds
554 );
555
556 $cases[] = array(
557 $params, // operation
558 $srcs, // sources
559 $content, // content for each source
560 true, // dest already exists
561 false, // succeeds
562 );
563
564 return $cases;
565 }
566
567 /**
568 * @dataProvider provider_testGetFileContents
569 */
570 public function testGetFileContents( $src, $content ) {
571 $this->pathsToPrune[] = $src;
572
573 $this->backend = $this->singleBackend;
574 $this->doTestGetFileContents( $src, $content );
575 $this->tearDownFiles();
576
577 $this->backend = $this->multiBackend;
578 $this->doTestGetFileContents( $src, $content );
579 $this->tearDownFiles();
580 }
581
582 /**
583 * @dataProvider provider_testGetFileContents
584 */
585 public function doTestGetFileContents( $src, $content ) {
586 $backendName = $this->backendClass();
587
588 $status = $this->backend->doOperation(
589 array( 'op' => 'create', 'content' => $content, 'dst' => $src ) );
590 $this->assertEquals( true, $status->isOK(),
591 "Creation of file at $src succeeded ($backendName)." );
592
593 $newContents = $this->backend->getFileContents( array( 'src' => $src ) );
594 $this->assertNotEquals( false, $newContents,
595 "Read of file at $src succeeded ($backendName)." );
596
597 $this->assertEquals( $content, $newContents,
598 "Contents read match data at $src ($backendName)." );
599 }
600
601 function provider_testGetFileContents() {
602 $cases = array();
603
604 $base = $this->baseStorePath();
605 $cases[] = array( "$base/cont1/b/z/some_file.txt", "some file contents" );
606 $cases[] = array( "$base/cont1/b/some-other_file.txt", "more file contents" );
607
608 return $cases;
609 }
610
611 /**
612 * @dataProvider provider_testGetLocalCopy
613 */
614 public function testGetLocalCopy( $src, $content ) {
615 $this->pathsToPrune[] = $src;
616
617 $this->backend = $this->singleBackend;
618 $this->doTestGetLocalCopy( $src, $content );
619 $this->tearDownFiles();
620
621 $this->backend = $this->multiBackend;
622 $this->doTestGetLocalCopy( $src, $content );
623 $this->tearDownFiles();
624 }
625
626 public function doTestGetLocalCopy( $src, $content ) {
627 $backendName = $this->backendClass();
628
629 $status = $this->backend->doOperation(
630 array( 'op' => 'create', 'content' => $content, 'dst' => $src ) );
631 $this->assertEquals( true, $status->isOK(),
632 "Creation of file at $src succeeded ($backendName)." );
633
634 $tmpFile = $this->backend->getLocalCopy( array( 'src' => $src ) );
635 $this->assertNotNull( $tmpFile,
636 "Creation of local copy of $src succeeded ($backendName)." );
637
638 $contents = file_get_contents( $tmpFile->getPath() );
639 $this->assertNotEquals( false, $contents, "Local copy of $src exists ($backendName)." );
640 }
641
642 function provider_testGetLocalCopy() {
643 $cases = array();
644
645 $base = $this->baseStorePath();
646 $cases[] = array( "$base/cont1/a/z/some_file.txt", "some file contents" );
647 $cases[] = array( "$base/cont1/a/some-other_file.txt", "more file contents" );
648
649 return $cases;
650 }
651
652 /**
653 * @dataProvider provider_testGetLocalReference
654 */
655 public function testGetLocalReference( $src, $content ) {
656 $this->pathsToPrune[] = $src;
657
658 $this->backend = $this->singleBackend;
659 $this->doTestGetLocalReference( $src, $content );
660 $this->tearDownFiles();
661
662 $this->backend = $this->multiBackend;
663 $this->doTestGetLocalReference( $src, $content );
664 $this->tearDownFiles();
665 }
666
667 public function doTestGetLocalReference( $src, $content ) {
668 $backendName = $this->backendClass();
669
670 $status = $this->backend->doOperation(
671 array( 'op' => 'create', 'content' => $content, 'dst' => $src ) );
672 $this->assertEquals( true, $status->isOK(),
673 "Creation of file at $src succeeded ($backendName)." );
674
675 $tmpFile = $this->backend->getLocalReference( array( 'src' => $src ) );
676 $this->assertNotNull( $tmpFile,
677 "Creation of local copy of $src succeeded ($backendName)." );
678
679 $contents = file_get_contents( $tmpFile->getPath() );
680 $this->assertNotEquals( false, $contents, "Local copy of $src exists ($backendName)." );
681 }
682
683 function provider_testGetLocalReference() {
684 $cases = array();
685
686 $base = $this->baseStorePath();
687 $cases[] = array( "$base/cont1/a/z/some_file.txt", "some file contents" );
688 $cases[] = array( "$base/cont1/a/some-other_file.txt", "more file contents" );
689
690 return $cases;
691 }
692
693 // @TODO: testPrepare
694
695 // @TODO: testSecure
696
697 // @TODO: testClean
698
699 // @TODO: testDoOperations
700
701 public function testGetFileList() {
702 $this->backend = $this->singleBackend;
703 $this->doTestGetFileList();
704 $this->tearDownFiles();
705
706 $this->backend = $this->multiBackend;
707 $this->doTestGetFileList();
708 $this->tearDownFiles();
709 }
710
711 public function doTestGetFileList() {
712 $backendName = $this->backendClass();
713
714 $base = $this->baseStorePath();
715 $files = array(
716 "$base/cont1/test1.txt",
717 "$base/cont1/test2.txt",
718 "$base/cont1/test3.txt",
719 "$base/cont1/subdir1/test1.txt",
720 "$base/cont1/subdir1/test2.txt",
721 "$base/cont1/subdir2/test3.txt",
722 "$base/cont1/subdir2/test4.txt",
723 "$base/cont1/subdir2/subdir/test1.txt",
724 "$base/cont1/subdir2/subdir/test2.txt",
725 "$base/cont1/subdir2/subdir/test3.txt",
726 "$base/cont1/subdir2/subdir/test4.txt",
727 "$base/cont1/subdir2/subdir/test5.txt",
728 "$base/cont1/subdir2/subdir/sub/test0.txt",
729 "$base/cont1/subdir2/subdir/sub/120-px-file.txt",
730 );
731 $this->pathsToPrune = array_merge( $this->pathsToPrune, $files );
732
733 // Add the files
734 $ops = array();
735 foreach ( $files as $file ) {
736 $ops[] = array( 'op' => 'create', 'content' => 'xxy', 'dst' => $file );
737 }
738 $status = $this->backend->doOperations( $ops );
739 $this->assertEquals( true, $status->isOK(),
740 "Creation of files succeeded ($backendName)." );
741
742 // Expected listing
743 $expected = array(
744 "test1.txt",
745 "test2.txt",
746 "test3.txt",
747 "subdir1/test1.txt",
748 "subdir1/test2.txt",
749 "subdir2/test3.txt",
750 "subdir2/test4.txt",
751 "subdir2/subdir/test1.txt",
752 "subdir2/subdir/test2.txt",
753 "subdir2/subdir/test3.txt",
754 "subdir2/subdir/test4.txt",
755 "subdir2/subdir/test5.txt",
756 "subdir2/subdir/sub/test0.txt",
757 "subdir2/subdir/sub/120-px-file.txt",
758 );
759 sort( $expected );
760
761 // Actual listing (no trailing slash)
762 $list = array();
763 $iter = $this->backend->getFileList( array( 'dir' => "$base/cont1" ) );
764 foreach ( $iter as $file ) {
765 $list[] = $file;
766 }
767 sort( $list );
768
769 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
770
771 // Actual listing (with trailing slash)
772 $list = array();
773 $iter = $this->backend->getFileList( array( 'dir' => "$base/cont1/" ) );
774 foreach ( $iter as $file ) {
775 $list[] = $file;
776 }
777 sort( $list );
778
779 $this->assertEquals( $expected, $list, "Correct file listing ($backendName)." );
780
781 foreach ( $files as $file ) {
782 $this->backend->doOperation( array( 'op' => 'delete', 'src' => "$base/$file" ) );
783 }
784
785 $iter = $this->backend->getFileList( array( 'dir' => "$base/cont1/not/exists" ) );
786 foreach ( $iter as $iter ) {} // no errors
787 }
788
789 function tearDownFiles() {
790 foreach ( $this->filesToPrune as $file ) {
791 @unlink( $file );
792 }
793 foreach ( $this->pathsToPrune as $file ) {
794 $this->backend->doOperation( array( 'op' => 'delete', 'src' => $file ) );
795 }
796 }
797
798 function tearDown() {
799 parent::tearDown();
800 }
801 }