r107361 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r107360‎ | r107361 | r107362 >
Date:05:06, 27 December 2011
Author:j
Status:ok
Tags:
Comment:
Add phpunit tests for chunk upload api.
Follow up r104687
Modified paths:
  • /trunk/phase3/tests/phpunit/includes/api/ApiTestCaseUpload.php (modified) (history)
  • /trunk/phase3/tests/phpunit/includes/api/ApiUploadTest.php (modified) (history)

Diff [purge]

Index: trunk/phase3/tests/phpunit/includes/api/ApiTestCaseUpload.php
@@ -104,6 +104,27 @@
105105 return true;
106106
107107 }
 108+ function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ){
 109+ $tmpName = tempnam( wfTempDir(), "" );
 110+ // copy the chunk data to temp location:
 111+ if ( !file_put_contents( $tmpName, $chunkData ) ) {
 112+ throw new Exception( "couldn't copy chunk data to $tmpName" );
 113+ }
 114+
 115+ clearstatcache();
 116+ $size = filesize( $tmpName );
 117+ if ( $size === false ) {
 118+ throw new Exception( "couldn't stat $tmpName" );
 119+ }
 120+
 121+ $_FILES[ $fieldName ] = array(
 122+ 'name' => $fileName,
 123+ 'type' => $type,
 124+ 'tmp_name' => $tmpName,
 125+ 'size' => $size,
 126+ 'error' => null
 127+ );
 128+ }
108129
109130 function clearTempUpload() {
110131 if( isset( $_FILES['file']['tmp_name'] ) ) {
Index: trunk/phase3/tests/phpunit/includes/api/ApiUploadTest.php
@@ -423,5 +423,143 @@
424424 $this->deleteFileByFilename( $fileName );
425425 unlink( $filePath );
426426 }
 427+
 428+
 429+ /**
 430+ * @depends testLogin
 431+ */
 432+ public function testUploadChunks( $session ) {
 433+ global $wgUser;
 434+ $wgUser = self::$users['uploader']->user; // @todo FIXME: still used somewhere
 435+
 436+ $chunkSize = 1048576;
 437+ // Download a large image file
 438+ // ( using RandomImageGenerator for large files is not stable )
 439+ $mimeType = 'image/jpeg';
 440+ $url = 'http://upload.wikimedia.org/wikipedia/commons/e/ed/Oberaargletscher_from_Oberaar%2C_2010_07.JPG';
 441+ $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg';
 442+ try {
 443+ // Only download if the file is not avaliable in the temp location:
 444+ if( !is_file( $filePath ) ){
 445+ copy($url, $filePath);
 446+ }
 447+ }
 448+ catch ( Exception $e ) {
 449+ $this->markTestIncomplete( $e->getMessage() );
 450+ }
 451+
 452+ $fileSize = filesize( $filePath );
 453+ $fileName = basename( $filePath );
 454+
 455+ $this->deleteFileByFileName( $fileName );
 456+ $this->deleteFileByContent( $filePath );
 457+
 458+ // Base upload params:
 459+ $params = array(
 460+ 'action' => 'upload',
 461+ 'stash' => 1,
 462+ 'filename' => $fileName,
 463+ 'filesize' => $fileSize,
 464+ 'offset' => 0,
 465+ );
 466+
 467+ // Upload chunks
 468+ $chunkSessionKey = false;
 469+ $resultOffset = 0;
 470+ // Open the file:
 471+ $handle = @fopen ($filePath, "r");
 472+ if( $handle === false ){
 473+ $this->markTestIncomplete( "could not open file: $filePath" );
 474+ }
 475+ while (!feof ($handle)) {
 476+ // Get the current chunk
 477+ $chunkData = @fread( $handle, $chunkSize );
 478+
 479+ // Upload the current chunk into the $_FILE object:
 480+ $this->fakeUploadChunk( 'chunk', 'blob', $mimeType, $chunkData );
 481+
 482+ // Check for chunkSessionKey
 483+ if( !$chunkSessionKey ){
 484+ // Upload fist chunk ( and get the session key )
 485+ try {
 486+ list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session,
 487+ self::$users['uploader']->user );
 488+ } catch ( UsageException $e ) {
 489+ $this->markTestIncomplete( $e->getMessage() );
 490+ }
 491+ // Make sure we got a valid chunk continue:
 492+ $this->assertTrue( isset( $result['upload'] ) );
 493+ $this->assertTrue( isset( $result['upload']['filekey'] ) );
 494+ // If we don't get a session key mark test incomplete.
 495+ if( ! isset( $result['upload']['filekey'] ) ){
 496+ $this->markTestIncomplete( "no filekey provided" );
 497+ }
 498+ $chunkSessionKey = $result['upload']['filekey'];
 499+ $this->assertEquals( 'Continue', $result['upload']['result'] );
 500+ // First chunk should have chunkSize == offset
 501+ $this->assertEquals( $chunkSize, $result['upload']['offset'] );
 502+ $resultOffset = $result['upload']['offset'];
 503+ continue;
 504+ }
 505+ // Filekey set to chunk session
 506+ $params['filekey'] = $chunkSessionKey;
 507+ // Update the offset ( always add chunkSize for subquent chunks should be in-sync with $result['upload']['offset'] )
 508+ $params['offset'] += $chunkSize;
 509+ // Make sure param offset is insync with resultOffset:
 510+ $this->assertEquals( $resultOffset, $params['offset'] );
 511+ // Upload current chunk
 512+ try {
 513+ list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session,
 514+ self::$users['uploader']->user );
 515+ } catch ( UsageException $e ) {
 516+ $this->markTestIncomplete( $e->getMessage() );
 517+ }
 518+ // Make sure we got a valid chunk continue:
 519+ $this->assertTrue( isset( $result['upload'] ) );
 520+ $this->assertTrue( isset( $result['upload']['filekey'] ) );
 521+
 522+ // Check if we were on the last chunk:
 523+ if( $params['offset'] + $chunkSize >= $fileSize ){
 524+ $this->assertEquals( 'Success', $result['upload']['result'] );
 525+ break;
 526+ } else {
 527+ $this->assertEquals( 'Continue', $result['upload']['result'] );
 528+ // update $resultOffset
 529+ $resultOffset = $result['upload']['offset'];
 530+ }
 531+ }
 532+ fclose ($handle);
 533+
 534+ // Check that we got a valid file result:
 535+ wfDebug( __METHOD__ . " hohoh filesize {$fileSize} info {$result['upload']['imageinfo']['size']}\n\n");
 536+ $this->assertEquals( $fileSize, $result['upload']['imageinfo']['size'] );
 537+ $this->assertEquals( $mimeType, $result['upload']['imageinfo']['mime'] );
 538+ $this->assertTrue( isset( $result['upload']['filekey'] ) );
 539+ $filekey = $result['upload']['filekey'];
 540+
 541+ // Now we should try to release the file from stash
 542+ $params = array(
 543+ 'action' => 'upload',
 544+ 'filekey' => $filekey,
 545+ 'filename' => $fileName,
 546+ 'comment' => 'dummy comment',
 547+ 'text' => "This is the page text for $fileName, altered",
 548+ );
 549+ $this->clearFakeUploads();
 550+ $exception = false;
 551+ try {
 552+ list( $result, $request, $session ) = $this->doApiRequestWithToken( $params, $session,
 553+ self::$users['uploader']->user );
 554+ } catch ( UsageException $e ) {
 555+ $exception = true;
 556+ }
 557+ $this->assertTrue( isset( $result['upload'] ) );
 558+ $this->assertEquals( 'Success', $result['upload']['result'] );
 559+ $this->assertFalse( $exception );
 560+
 561+ // clean up
 562+ $this->deleteFileByFilename( $fileName );
 563+ // don't remove downloaded temporary file for fast subquent tests.
 564+ //unlink( $filePath );
 565+ }
427566 }
428 -

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r104687Use database to track uploaded chunks and concatenate at the end....j14:56, 30 November 2011

Status & tagging log