Index: branches/FileBackend/phase3/tests/phpunit/includes/filerepo/FileBackendTest.php |
— | — | @@ -1,5 +1,6 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +// @TODO: fix empty dir leakage |
4 | 5 | class FileBackendTest extends MediaWikiTestCase { |
5 | 6 | private $backend, $multiBackend; |
6 | 7 | private $filesToPrune, $pathsToPrune; |
— | — | @@ -254,35 +255,35 @@ |
255 | 256 | /** |
256 | 257 | * @dataProvider provider_testCreate |
257 | 258 | */ |
258 | | - public function testCreate( $op, $source, $alreadyExists, $okStatus, $newSize ) { |
259 | | - $this->pathsToPrune[] = $source; |
| 259 | + public function testCreate( $op, $dest, $alreadyExists, $okStatus, $newSize ) { |
| 260 | + $this->pathsToPrune[] = $dest; |
260 | 261 | |
261 | 262 | $oldText = 'blah...blah...waahwaah'; |
262 | 263 | if ( $alreadyExists ) { |
263 | 264 | $status = $this->backend->doOperation( |
264 | | - array( 'op' => 'create', 'content' => $oldText, 'dst' => $source ) ); |
265 | | - $this->assertEquals( true, $status->isOK(), "Creation of file at $source succeeded." ); |
| 265 | + array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) ); |
| 266 | + $this->assertEquals( true, $status->isOK(), "Creation of file at $dest succeeded." ); |
266 | 267 | } |
267 | 268 | |
268 | 269 | $status = $this->backend->doOperation( $op ); |
269 | 270 | if ( $okStatus ) { |
270 | | - $this->assertEquals( true, $status->isOK(), "Creation of file at $source succeeded." ); |
| 271 | + $this->assertEquals( true, $status->isOK(), "Creation of file at $dest succeeded." ); |
271 | 272 | } else { |
272 | | - $this->assertEquals( false, $status->isOK(), "Creation of file at $source failed." ); |
| 273 | + $this->assertEquals( false, $status->isOK(), "Creation of file at $dest failed." ); |
273 | 274 | } |
274 | 275 | |
275 | | - $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $source ) ), |
276 | | - "Source file $source exists after creation." ); |
| 276 | + $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), |
| 277 | + "Dest file $dest exists after creation." ); |
277 | 278 | |
278 | | - $props1 = $this->backend->getFileProps( array( 'src' => $source ) ); |
| 279 | + $props1 = $this->backend->getFileProps( array( 'src' => $dest ) ); |
279 | 280 | $this->assertEquals( true, $props1['fileExists'], |
280 | | - "Source file $source exists according to props." ); |
| 281 | + "Dest file $dest exists according to props." ); |
281 | 282 | if ( $okStatus ) { // file content is what we saved |
282 | 283 | $this->assertEquals( $newSize, $props1['size'], |
283 | | - "Source file $source has expected size according to props." ); |
| 284 | + "Dest file $dest has expected size according to props." ); |
284 | 285 | } else { // file content is some other previous text |
285 | 286 | $this->assertEquals( strlen( $oldText ), $props1['size'], |
286 | | - "Source file $source has different size that given text according to props." ); |
| 287 | + "Dest file $dest has different size that given text according to props." ); |
287 | 288 | } |
288 | 289 | } |
289 | 290 | |
— | — | @@ -324,16 +325,183 @@ |
325 | 326 | return $cases; |
326 | 327 | } |
327 | 328 | |
328 | | - // @TODO: testConcatenate |
| 329 | + /** |
| 330 | + * @dataProvider provider_testConcatenate |
| 331 | + */ |
| 332 | + public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) { |
| 333 | + $this->pathsToPrune = array_merge( $this->pathsToPrune, $srcs ); |
| 334 | + $this->pathsToPrune[] = $op['dst']; |
329 | 335 | |
| 336 | + $expContent = ''; |
| 337 | + // Create sources |
| 338 | + $ops = array(); |
| 339 | + foreach ( $srcs as $i => $source ) { |
| 340 | + $ops[] = array( |
| 341 | + 'op' => 'create', // operation |
| 342 | + 'dst' => $source, // source |
| 343 | + 'content' => $srcsContent[$i] |
| 344 | + ); |
| 345 | + $expContent .= $srcsContent[$i]; |
| 346 | + } |
| 347 | + $dest = $op['dst']; |
| 348 | + $status = $this->backend->doOperations( $ops ); |
| 349 | + |
| 350 | + $this->assertEquals( true, $status->isOK(), "Creation of concat file at $dest succeeded." ); |
| 351 | + |
| 352 | + if ( $alreadyExists ) { |
| 353 | + $oldText = 'blah...blah...waahwaah'; |
| 354 | + $status = $this->backend->doOperation( |
| 355 | + array( 'op' => 'create', 'content' => $oldText, 'dst' => $dest ) ); |
| 356 | + $this->assertEquals( true, $status->isOK(), "Creation of file at $dest succeeded." ); |
| 357 | + } |
| 358 | + |
| 359 | + // Combine them |
| 360 | + $status = $this->backend->doOperation( $op ); |
| 361 | + if ( $okStatus ) { |
| 362 | + $this->assertEquals( true, $status->isOK(), "Creation of concat file at $dest succeeded." ); |
| 363 | + } else { |
| 364 | + $this->assertEquals( false, $status->isOK(), "Creation of concat file at $dest failed." ); |
| 365 | + } |
| 366 | + |
| 367 | + if ( $okStatus ) { |
| 368 | + $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), |
| 369 | + "Dest concat file $dest exists after creation." ); |
| 370 | + } else { |
| 371 | + $this->assertEquals( true, $this->backend->fileExists( array( 'src' => $dest ) ), |
| 372 | + "Dest concat file $dest exists after failed creation." ); |
| 373 | + } |
| 374 | + |
| 375 | + $tmpFile = $this->backend->getLocalCopy( array( 'src' => $dest ) ); |
| 376 | + $this->assertNotNull( $tmpFile, "Creation of local copy of $dest succeeded." ); |
| 377 | + |
| 378 | + $contents = file_get_contents( $tmpFile->getPath() ); |
| 379 | + $this->assertNotEquals( false, $contents, "Local copy of $dest exists." ); |
| 380 | + |
| 381 | + if ( $okStatus ) { |
| 382 | + $this->assertEquals( $expContent, $contents, "Concat file at $dest has correct contents." ); |
| 383 | + } else { |
| 384 | + $this->assertNotEquals( $expContent, $contents, "Concat file at $dest has correct contents." ); |
| 385 | + } |
| 386 | + } |
| 387 | + |
| 388 | + function provider_testConcatenate() { |
| 389 | + $cases = array(); |
| 390 | + |
| 391 | + $dest = $this->singleBasePath() . '/cont1/full_file.txt'; |
| 392 | + $srcs = array( |
| 393 | + $this->singleBasePath() . '/cont1/file1.txt', |
| 394 | + $this->singleBasePath() . '/cont1/file2.txt', |
| 395 | + $this->singleBasePath() . '/cont1/file3.txt', |
| 396 | + $this->singleBasePath() . '/cont1/file4.txt', |
| 397 | + $this->singleBasePath() . '/cont1/file5.txt', |
| 398 | + $this->singleBasePath() . '/cont1/file6.txt', |
| 399 | + $this->singleBasePath() . '/cont1/file7.txt', |
| 400 | + $this->singleBasePath() . '/cont1/file8.txt', |
| 401 | + $this->singleBasePath() . '/cont1/file9.txt', |
| 402 | + $this->singleBasePath() . '/cont1/file10.txt' |
| 403 | + ); |
| 404 | + $content = array( |
| 405 | + 'egfage', |
| 406 | + 'ageageag', |
| 407 | + 'rhokohlr', |
| 408 | + 'shgmslkg', |
| 409 | + 'kenga', |
| 410 | + 'owagmal', |
| 411 | + 'kgmae', |
| 412 | + 'g eak;g', |
| 413 | + 'lkaem;a', |
| 414 | + 'legma' |
| 415 | + ); |
| 416 | + $op = array( 'op' => 'concatenate', 'srcs' => $srcs, 'dst' => $dest ); |
| 417 | + |
| 418 | + $cases[] = array( |
| 419 | + $op, // operation |
| 420 | + $srcs, // sources |
| 421 | + $content, // content for each source |
| 422 | + false, // no dest already exists |
| 423 | + true, // succeeds |
| 424 | + ); |
| 425 | + |
| 426 | + $cases[] = array( |
| 427 | + $op, // operation |
| 428 | + $srcs, // sources |
| 429 | + $content, // content for each source |
| 430 | + true, // no dest already exists |
| 431 | + false, // succeeds |
| 432 | + ); |
| 433 | + |
| 434 | + $op['overwriteDest'] = true; |
| 435 | + $cases[] = array( |
| 436 | + $op, // operation |
| 437 | + $srcs, // sources |
| 438 | + $content, // content for each source |
| 439 | + true, // no dest already exists |
| 440 | + true, // succeeds |
| 441 | + ); |
| 442 | + |
| 443 | + return $cases; |
| 444 | + } |
| 445 | + |
| 446 | + /** |
| 447 | + * @dataProvider provider_testGetLocalCopy |
| 448 | + */ |
| 449 | + public function testGetLocalCopy( $src, $content ) { |
| 450 | + $this->pathsToPrune[] = $src; |
| 451 | + |
| 452 | + $status = $this->backend->doOperation( |
| 453 | + array( 'op' => 'create', 'content' => $content, 'dst' => $src ) ); |
| 454 | + $this->assertEquals( true, $status->isOK(), "Creation of file at $src succeeded." ); |
| 455 | + |
| 456 | + $tmpFile = $this->backend->getLocalCopy( array( 'src' => $src ) ); |
| 457 | + $this->assertNotNull( $tmpFile, "Creation of local copy of $src succeeded." ); |
| 458 | + |
| 459 | + $contents = file_get_contents( $tmpFile->getPath() ); |
| 460 | + $this->assertNotEquals( false, $contents, "Local copy of $src exists." ); |
| 461 | + } |
| 462 | + |
| 463 | + function provider_testGetLocalCopy() { |
| 464 | + $cases = array(); |
| 465 | + |
| 466 | + $base = $this->singleBasePath(); |
| 467 | + $cases[] = array( "$base/cont1/a/z/some_file.txt", "some file contents" ); |
| 468 | + $cases[] = array( "$base/cont1/a/some-other_file.txt", "more file contents" ); |
| 469 | + |
| 470 | + return $cases; |
| 471 | + } |
| 472 | + |
| 473 | + /** |
| 474 | + * @dataProvider provider_testGetReference |
| 475 | + */ |
| 476 | + public function testGetLocalReference( $src, $content ) { |
| 477 | + $this->pathsToPrune[] = $src; |
| 478 | + |
| 479 | + $status = $this->backend->doOperation( |
| 480 | + array( 'op' => 'create', 'content' => $content, 'dst' => $src ) ); |
| 481 | + $this->assertEquals( true, $status->isOK(), "Creation of file at $src succeeded." ); |
| 482 | + |
| 483 | + $tmpFile = $this->backend->getLocalReference( array( 'src' => $src ) ); |
| 484 | + $this->assertNotNull( $tmpFile, "Creation of local copy of $src succeeded." ); |
| 485 | + |
| 486 | + $contents = file_get_contents( $tmpFile->getPath() ); |
| 487 | + $this->assertNotEquals( false, $contents, "Local copy of $src exists." ); |
| 488 | + } |
| 489 | + |
| 490 | + function provider_testGetReference() { |
| 491 | + $cases = array(); |
| 492 | + |
| 493 | + $base = $this->singleBasePath(); |
| 494 | + $cases[] = array( "$base/cont1/a/z/some_file.txt", "some file contents" ); |
| 495 | + $cases[] = array( "$base/cont1/a/some-other_file.txt", "more file contents" ); |
| 496 | + |
| 497 | + return $cases; |
| 498 | + } |
| 499 | + |
330 | 500 | // @TODO: testPrepare |
331 | 501 | |
332 | 502 | // @TODO: testSecure |
333 | 503 | |
334 | 504 | // @TODO: testClean |
335 | 505 | |
336 | | - // @TODO: testGetLocalCopy |
337 | | - |
338 | 506 | // @TODO: testDoOperations |
339 | 507 | |
340 | 508 | public function testGetFileList() { |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackendMultiWrite.php |
— | — | @@ -180,11 +180,11 @@ |
181 | 181 | return $this->backends[$this->masterIndex]->getFileTimestamp( $realParams ); |
182 | 182 | } |
183 | 183 | |
184 | | - function getSha1Base36(array $params) { |
| 184 | + function getFileSha1Base36(array $params) { |
185 | 185 | # Hit all backends in case of failed operations (out of sync) |
186 | 186 | foreach ( $this->backends as $backend ) { |
187 | 187 | $realParams = $this->substOpPaths( $params, $backend ); |
188 | | - $hash = $backend->getSha1Base36( $realParams ); |
| 188 | + $hash = $backend->getFileSha1Base36( $realParams ); |
189 | 189 | if ( $hash !== false ) { |
190 | 190 | return $hash; |
191 | 191 | } |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileOp.php |
— | — | @@ -400,7 +400,7 @@ |
401 | 401 | if ( FileBackend::isStoragePath( $path ) ) { |
402 | 402 | // For some backends (e.g. Swift, Azure) we can get |
403 | 403 | // standard hashes to use for this types of comparisons. |
404 | | - $hash = $this->backend->getSha1Base36( array( 'src' => $path ) ); |
| 404 | + $hash = $this->backend->getFileSha1Base36( array( 'src' => $path ) ); |
405 | 405 | // Source file is on file system |
406 | 406 | } else { |
407 | 407 | wfSuppressWarnings(); |
Index: branches/FileBackend/phase3/includes/filerepo/backend/FileBackend.php |
— | — | @@ -213,7 +213,7 @@ |
214 | 214 | * @param $params Array |
215 | 215 | * @return string|false Hash string or false on failure |
216 | 216 | */ |
217 | | - abstract public function getSha1Base36( array $params ); |
| 217 | + abstract public function getFileSha1Base36( array $params ); |
218 | 218 | |
219 | 219 | /** |
220 | 220 | * Get the last-modified timestamp of the file at a storage path. |
— | — | @@ -457,7 +457,7 @@ |
458 | 458 | return false; // not implemented |
459 | 459 | } |
460 | 460 | |
461 | | - public function getSha1Base36( array $params ) { |
| 461 | + public function getFileSha1Base36( array $params ) { |
462 | 462 | $fsFile = $this->getLocalReference( array( 'src' => $params['src'] ) ); |
463 | 463 | if ( !$fsFile ) { |
464 | 464 | return false; |