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() { $this->validateSerialization( CacheTime::class, array_map( static function ( $testCase ) { return $testCase['instance']; }, ParserCacheSerializationTestCases::getCacheTimeTestCases() ) ); $this->validateSerialization( ParserOutput::class, array_map( static function ( $testCase ) { return $testCase['instance']; }, ParserCacheSerializationTestCases::getParserOutputTestCases() ) ); } /** * 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 array $testInstances */ public function validateSerialization( string $className, array $testInstances ) { $supportedFormats = ParserCacheSerializationTestCases::getSupportedSerializationFormats( $className ); foreach ( $supportedFormats as $serializationFormat ) { $serializationUtils = new \Wikimedia\Tests\SerializationTestUtils( $this->getArg( 1 ) ?: __DIR__ . '/../../data/ParserCache', $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' ) ); $this->validateSerializationData( $currentSerialized, $expected ); } } } private function validateSerializationData( $data, $fileInfo ) { 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->path . "\n" ); file_put_contents( $fileInfo->path, $data ); } else { $this->fatalError( "Serialization data mismatch: {$fileInfo->path}. " . "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!" ); } } else { $this->output( "Serialization OK: " . $fileInfo->path . "\n" ); } } } } $maintClass = ValidateParserCacheSerializationTestData::class; require_once RUN_MAINTENANCE_IF_MAIN;