-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SimpleParsoidOutputStash: add serialization test cases
The '1.44' test data is the current serialization output. The '1.44_native' test data is the output after I9e6b924d62ccc3312f5c70989477da1e2f21c86b which uses native PageBundle serialization. This is to establish forward-compatibility using the procedure described at https://www.mediawiki.org/wiki/Manual:Parser_cache/Serialization_compatibility Change-Id: I8d53ff3e9c600cce16a0fc07f3665a91e5d8036b
- Loading branch information
Showing
8 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1 @@ | ||
{"revId":5678,"pb":{"_type_":"Wikimedia\\Parsoid\\Core\\PageBundle","html":"<b>html<\/b>","parsoid":{"counter":1234,"offsetType":"byte","ids":{"mwAA":{"parsoid":true}}},"mw":{"ids":{"mwAA":{"mw":true}}},"version":"1.2.3.4","headers":{"X-Header-Test":"header test"},"contentmodel":"wikitext"},"content":{"model":"wikitext","data":"wiki wiki wiki"}} |
1 change: 1 addition & 0 deletions
1
tests/phpunit/data/SelserContext/1.44-SelserContext-basic.serialized
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1 @@ | ||
a:3:{s:5:"revId";i:5678;s:2:"pb";a:7:{s:6:"_type_";s:33:"Wikimedia\Parsoid\Core\PageBundle";s:4:"html";s:11:"<b>html</b>";s:7:"parsoid";a:3:{s:7:"counter";i:1234;s:10:"offsetType";s:4:"byte";s:3:"ids";a:1:{s:4:"mwAA";a:1:{s:7:"parsoid";b:1;}}}s:2:"mw";a:1:{s:3:"ids";a:1:{s:4:"mwAA";a:1:{s:2:"mw";b:1;}}}s:7:"version";s:7:"1.2.3.4";s:7:"headers";a:1:{s:13:"X-Header-Test";s:11:"header test";}s:12:"contentmodel";s:8:"wikitext";}s:7:"content";a:2:{s:5:"model";s:8:"wikitext";s:4:"data";s:14:"wiki wiki wiki";}} |
1 change: 1 addition & 0 deletions
1
tests/phpunit/data/SelserContext/1.44_native-SelserContext-basic.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1 @@ | ||
{"revId":5678,"pb":{"html":"<b>html<\/b>","parsoid":{"counter":1234,"offsetType":"byte","ids":{"mwAA":{"parsoid":true}}},"mw":{"ids":{"mwAA":{"mw":true}}},"version":"1.2.3.4","headers":{"X-Header-Test":"header test"},"contentmodel":"wikitext"},"content":{"model":"wikitext","data":"wiki wiki wiki"}} |
1 change: 1 addition & 0 deletions
1
tests/phpunit/data/SelserContext/1.44_native-SelserContext-basic.serialized
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1 @@ | ||
a:3:{s:5:"revId";i:5678;s:2:"pb";a:6:{s:4:"html";s:11:"<b>html</b>";s:7:"parsoid";a:3:{s:7:"counter";i:1234;s:10:"offsetType";s:4:"byte";s:3:"ids";a:1:{s:4:"mwAA";a:1:{s:7:"parsoid";b:1;}}}s:2:"mw";a:1:{s:3:"ids";a:1:{s:4:"mwAA";a:1:{s:2:"mw";b:1;}}}s:7:"version";s:7:"1.2.3.4";s:7:"headers";a:1:{s:13:"X-Header-Test";s:11:"header test";}s:12:"contentmodel";s:8:"wikitext";}s:7:"content";a:2:{s:5:"model";s:8:"wikitext";s:4:"data";s:14:"wiki wiki wiki";}} |
163 changes: 163 additions & 0 deletions
163
tests/phpunit/integration/includes/edit/SimpleParsoidOutputStashSerializationTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,163 @@ | ||
<?php | ||
|
||
namespace MediaWiki\Tests\Integration\Edit; | ||
|
||
use MediaWiki\Content\Content; | ||
use MediaWiki\Content\ContentHandler; | ||
use MediaWiki\Content\IContentHandlerFactory; | ||
use MediaWiki\Content\WikitextContent; | ||
use MediaWiki\Edit\SelserContext; | ||
use MediaWiki\Edit\SimpleParsoidOutputStash; | ||
use MediaWikiIntegrationTestCase; | ||
use Wikimedia\ObjectCache\HashBagOStuff; | ||
use Wikimedia\Parsoid\Core\PageBundle; | ||
use Wikimedia\TestingAccessWrapper; | ||
use Wikimedia\Tests\SerializationTestTrait; | ||
|
||
/** | ||
* @covers \MediaWiki\Edit\SimpleParsoidOutputStash | ||
* @covers \MediaWiki\Edit\SelserContext | ||
*/ | ||
class SimpleParsoidOutputStashSerializationTest extends MediaWikiIntegrationTestCase { | ||
use SerializationTestTrait; | ||
|
||
/** | ||
* Overrides SerializationTestTrait::getClassToTest | ||
* @return string | ||
*/ | ||
public static function getClassToTest(): string { | ||
return SelserContext::class; | ||
} | ||
|
||
/** | ||
* Overrides SerializationTestTrait::getSerializedDataPath | ||
* @return string | ||
*/ | ||
public static function getSerializedDataPath(): string { | ||
return __DIR__ . '/../../../data/SelserContext'; | ||
} | ||
|
||
/** | ||
* Overrides SerializationTestTrait::getTestInstancesAndAssertions | ||
* @return array | ||
*/ | ||
public static function getTestInstancesAndAssertions(): array { | ||
return [ | ||
'basic' => [ | ||
'instance' => new SelserContext( | ||
new PageBundle( | ||
'<b>html</b>', | ||
[ | ||
'counter' => 1234, | ||
'offsetType' => 'byte', | ||
'ids' => [ | ||
'mwAA' => [ 'parsoid' => true ], | ||
], | ||
], | ||
[ | ||
'ids' => [ | ||
'mwAA' => [ 'mw' => true ], | ||
], | ||
], | ||
'1.2.3.4', | ||
[ | ||
'X-Header-Test' => 'header test', | ||
], | ||
CONTENT_MODEL_WIKITEXT, | ||
), | ||
5678, /* revision */ | ||
new WikitextContent( 'wiki wiki wiki' ) | ||
), | ||
'assertions' => static function ( MediaWikiIntegrationTestCase $testCase, SelserContext $ss ) { | ||
$pb = $ss->getPageBundle(); | ||
$testCase->assertSame( '<b>html</b>', $pb->html ); | ||
$testCase->assertSame( [ | ||
'counter' => 1234, | ||
'offsetType' => 'byte', | ||
'ids' => [ | ||
'mwAA' => [ 'parsoid' => true ], | ||
], | ||
], $pb->parsoid ); | ||
$testCase->assertSame( [ | ||
'ids' => [ | ||
'mwAA' => [ 'mw' => true ], | ||
], | ||
], $pb->mw ); | ||
$testCase->assertSame( '1.2.3.4', $pb->version ); | ||
$testCase->assertSame( [ | ||
'X-Header-Test' => 'header test', | ||
], $pb->headers ); | ||
$testCase->assertSame( CONTENT_MODEL_WIKITEXT, $pb->contentmodel ); | ||
|
||
$testCase->assertSame( 5678, $ss->getRevisionID() ); | ||
|
||
$content = $ss->getContent(); | ||
$testCase->assertSame( CONTENT_MODEL_WIKITEXT, $content->getModel() ); | ||
$testCase->assertSame( 'wiki wiki wiki', $content->getText() ); | ||
}, | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Overrides SerializationTestTrait::getSupportedSerializationFormats | ||
* @return array | ||
*/ | ||
public static function getSupportedSerializationFormats(): array { | ||
$stash = new SimpleParsoidOutputStash( | ||
new class implements IContentHandlerFactory { | ||
public function getContentHandler( string $modelID ): ContentHandler { | ||
return new class( CONTENT_MODEL_WIKITEXT, [ CONTENT_FORMAT_WIKITEXT ] ) extends ContentHandler { | ||
public function serializeContent( Content $content, $format = null ) { | ||
return $content->getText(); | ||
} | ||
|
||
public function unserializeContent( $blob, $format = null ) { | ||
return new WikitextContent( $blob ); | ||
} | ||
|
||
public function makeEmptyContent() { | ||
throw new \Error( "unimplemented" ); | ||
} | ||
}; | ||
} | ||
|
||
public function getContentModels(): array { | ||
return [ CONTENT_MODEL_WIKITEXT ]; | ||
} | ||
|
||
public function getAllContentFormats(): array { | ||
return [ CONTENT_FORMAT_WIKITEXT ]; | ||
} | ||
|
||
public function isDefinedModel( string $modelId ): bool { | ||
return $modelId === CONTENT_MODEL_WIKITEXT; | ||
} | ||
}, | ||
new HashBagOStuff(), | ||
10000 | ||
); | ||
$wrapper = TestingAccessWrapper::newFromObject( $stash ); | ||
return [ | ||
[ | ||
'ext' => 'serialized', | ||
'serializer' => static function ( $obj ) use ( $wrapper ) { | ||
return serialize( $wrapper->selserContextToJsonArray( $obj ) ); | ||
}, | ||
'deserializer' => static function ( $data ) use ( $wrapper ) { | ||
return $wrapper->newSelserContextFromJson( unserialize( $data ) ); | ||
}, | ||
], | ||
[ | ||
'ext' => 'json', | ||
'serializer' => static function ( $obj ) use ( $wrapper ) { | ||
return json_encode( $wrapper->selserContextToJsonArray( $obj ) ); | ||
}, | ||
'deserializer' => static function ( $data ) use ( $wrapper ) { | ||
return $wrapper->newSelserContextFromJson( json_decode( $data, true ) ); | ||
}, | ||
], | ||
]; | ||
} | ||
|
||
} |
121 changes: 121 additions & 0 deletions
121
tests/phpunit/integration/includes/edit/validateSelserContextTestData.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,121 @@ | ||
<?php | ||
|
||
namespace Wikimedia\Tests\Message; | ||
|
||
use MediaWiki\Logger\ConsoleLogger; | ||
use MediaWiki\Maintenance\Maintenance; | ||
use MediaWiki\Tests\Integration\Edit\SimpleParsoidOutputStashSerializationTest; | ||
use Wikimedia\Tests\SerializationTestUtils; | ||
|
||
define( 'MW_AUTOLOAD_TEST_CLASSES', true ); | ||
define( 'MW_PHPUNIT_TEST', true ); | ||
|
||
require_once __DIR__ . '/../../../../../maintenance/Maintenance.php'; | ||
|
||
// phpcs:disable MediaWiki.Files.ClassMatchesFilename.WrongCase | ||
class ValidateSelserContextTestData extends Maintenance { | ||
|
||
public function __construct() { | ||
parent::__construct(); | ||
|
||
$this->addArg( | ||
'path', | ||
'Path of serialization files.', | ||
false | ||
); | ||
$this->addOption( 'create', 'Create missing serialization' ); | ||
$this->addOption( 'update', 'Update mismatching serialization files' ); | ||
$this->addOption( 'version', 'Specify version for which to check serialization. ' | ||
. 'Also determines which files may be created or updated if ' | ||
. 'the respective options are set.' | ||
. 'Unserialization is always checked against all versions. ', false, true ); | ||
} | ||
|
||
public function execute() { | ||
$tests = [ | ||
SimpleParsoidOutputStashSerializationTest::class, | ||
]; | ||
foreach ( $tests as $testClass ) { | ||
$objClass = $testClass::getClassToTest(); | ||
$this->validateSerialization( | ||
$objClass, | ||
$testClass::getSerializedDataPath(), | ||
$testClass::getSupportedSerializationFormats(), | ||
array_map( static function ( $testCase ) use ( $objClass ) { | ||
return $testCase['instance']; | ||
}, $testClass::getTestInstancesAndAssertions() ) | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Ensures that objects will serialize into the form expected for the given version. | ||
* If the respective options are set in the constructor, this will create missing files or | ||
* update mismatching files. | ||
* | ||
* @param string $className | ||
* @param string $defaultDirectory | ||
* @param array $supportedFormats | ||
* @param array $testInstances | ||
*/ | ||
public function validateSerialization( | ||
string $className, | ||
string $defaultDirectory, | ||
array $supportedFormats, | ||
array $testInstances | ||
) { | ||
$ok = true; | ||
foreach ( $supportedFormats as $serializationFormat ) { | ||
$serializationUtils = new SerializationTestUtils( | ||
$this->getArg( 1 ) ?: $defaultDirectory, | ||
$testInstances, | ||
$serializationFormat['ext'], | ||
$serializationFormat['serializer'], | ||
$serializationFormat['deserializer'] | ||
); | ||
$serializationUtils->setLogger( new ConsoleLogger( 'validator' ) ); | ||
foreach ( $serializationUtils->getSerializedInstances() as $testCaseName => $currentSerialized ) { | ||
$expected = $serializationUtils | ||
->getStoredSerializedInstance( $className, $testCaseName, $this->getOption( 'version' ) ); | ||
$ok = $this->validateSerializationData( $currentSerialized, $expected ) && $ok; | ||
} | ||
} | ||
if ( !$ok ) { | ||
$this->output( "\n\n" ); | ||
$this->fatalError( "Serialization data mismatch! " | ||
. "If this was expected, rerun the script with the --update option " | ||
. "to update the expected serialization. WARNING: make sure " | ||
. "a forward compatible version of the code is live before deploying a " | ||
. "serialization change!\n" | ||
); | ||
} | ||
} | ||
|
||
private function validateSerializationData( $data, $fileInfo ): bool { | ||
if ( !$fileInfo->data ) { | ||
if ( $this->hasOption( 'create' ) ) { | ||
$this->output( 'Creating file: ' . $fileInfo->path . "\n" ); | ||
file_put_contents( $fileInfo->path, $data ); | ||
} else { | ||
$this->fatalError( "File not found: {$fileInfo->path}. " | ||
. "Rerun the script with the --create option set to create it." | ||
); | ||
} | ||
} else { | ||
if ( $data !== $fileInfo->data ) { | ||
if ( $this->hasOption( 'update' ) ) { | ||
$this->output( 'Data mismatch, updating file: ' . $fileInfo->currentVersionPath . "\n" ); | ||
file_put_contents( $fileInfo->currentVersionPath, $data ); | ||
} else { | ||
$this->output( 'Serialization MISMATCH: ' . $fileInfo->path . "\n" ); | ||
return false; | ||
} | ||
} else { | ||
$this->output( "Serialization OK: " . $fileInfo->path . "\n" ); | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
|
||
return ValidateSelserContextTestData::class; |