PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/core/modules/migrate_drupal/tests/src/Traits/ValidateMigrationStateTestTrait.php

http://github.com/drupal/drupal
PHP | 154 lines | 91 code | 19 blank | 44 comment | 9 complexity | 47eb6818ede0bec5624c754ce5686f7e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. namespace Drupal\Tests\migrate_drupal\Traits;
  3. use Drupal\Component\Discovery\YamlDiscovery;
  4. use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait;
  5. use Drupal\migrate_drupal\MigrationConfigurationTrait;
  6. use Drupal\migrate_drupal\MigrationState;
  7. /**
  8. * Tests the migration state information in module.migrate_drupal.yml.
  9. *
  10. * This test checks that the discovered upgrade paths, which are based on the
  11. * source_module and destination_module definition matches the declared
  12. * upgrade paths in all the migrate_drupal.yml files.
  13. *
  14. * @group migrate_drupal
  15. */
  16. trait ValidateMigrationStateTestTrait {
  17. use FileSystemModuleDiscoveryDataProviderTrait;
  18. use MigrationConfigurationTrait;
  19. /**
  20. * Tests the migration information in .migrate_drupal.yml.
  21. *
  22. * Checks that every discovered pair has a corresponding declaration in the
  23. * declared pairs. The alternate check, that each declared pair has a
  24. * corresponding discovered pair is not possible because declarations can be
  25. * made for the two cases where migrations are yet to be written and where
  26. * migrations are not needed.
  27. */
  28. public function testMigrationState() {
  29. // Level separator of destination and source properties.
  30. $separator = ',';
  31. $this->enableAllModules();
  32. $version = (string) $this->getLegacyDrupalVersion($this->sourceDatabase);
  33. // Build an array for each migration keyed by provider. The value is a
  34. // string consisting of the version number, the provider, the source_module
  35. // and the destination module.
  36. $discovered = [];
  37. /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
  38. $plugin_manager = $this->container->get('plugin.manager.migration');
  39. $migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version);
  40. /** @var \Drupal\migrate\Plugin\Migration $migration */
  41. foreach ($migrations as $migration) {
  42. $definition = $migration->getPluginDefinition();
  43. if (is_array($definition['provider'])) {
  44. $provider = reset($definition['provider']);
  45. }
  46. else {
  47. $provider = $definition['provider'];
  48. }
  49. $source_module = $migration->getSourcePlugin()->getSourceModule();
  50. $destination_module = $migration->getDestinationPlugin()
  51. ->getDestinationModule();
  52. $discovered[] = implode($separator, [
  53. $provider,
  54. $source_module,
  55. $destination_module,
  56. ]);
  57. }
  58. // Add the field migrations.
  59. /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
  60. $definitions = $this->container->get('plugin.manager.migrate.field')
  61. ->getDefinitions();
  62. foreach ($definitions as $key => $definition) {
  63. if (isset($definition['core'][$version])) {
  64. $discovered[] = implode($separator, [
  65. $definition['provider'],
  66. $definition['source_module'],
  67. $definition['destination_module'],
  68. ]);
  69. }
  70. }
  71. // Get the declared migration state information from .migrate_drupal.yml
  72. // and build an array of source modules and there migration state. The
  73. // destination is not used yet but can be later for validating the
  74. // source/destination pairs with the actual source/destination pairs in the
  75. // migrate plugins.
  76. $system_info = (new YamlDiscovery('migrate_drupal', array_map(function (&$value) {
  77. return $value . '/migrations/state/';
  78. }, \Drupal::moduleHandler()->getModuleDirectories())))->findAll();
  79. $declared = [];
  80. $states = [MigrationState::FINISHED, MigrationState::NOT_FINISHED];
  81. foreach ($system_info as $module => $info) {
  82. foreach ($states as $state) {
  83. if (isset($info[$state][$version])) {
  84. foreach ($info[$state][$version] as $source => $destination) {
  85. // Do not add the source module i18nstrings or i18_string. The
  86. // 18n migrations can have up to three source modules but only one
  87. // can be handled in the migration.
  88. if (($source !== 'i18nstrings') && ($source !== 'i18n_string')) {
  89. foreach ((array) $destination as $dest) {
  90. $key = [$module, $source, trim($dest)];
  91. $declared[$state][] = implode($separator, $key);
  92. }
  93. }
  94. }
  95. }
  96. }
  97. }
  98. // Sort and make the array values unique.
  99. sort($declared[MigrationState::FINISHED]);
  100. sort($declared[MigrationState::NOT_FINISHED]);
  101. $declared_unique[MigrationState::FINISHED] = array_unique($declared[MigrationState::FINISHED]);
  102. $declared_unique[MigrationState::NOT_FINISHED] = array_unique($declared[MigrationState::NOT_FINISHED]);
  103. sort($discovered);
  104. $discovered_unique = array_unique($discovered);
  105. // Assert that each discovered migration has a corresponding declaration
  106. // in a migrate_drupal.yml.
  107. foreach ($discovered_unique as $datum) {
  108. $data = str_getcsv($datum);
  109. $in_finished = in_array($datum, $declared_unique[MigrationState::FINISHED]);
  110. $in_not_finished = in_array($datum, $declared_unique[MigrationState::NOT_FINISHED]);
  111. $found = $in_finished || $in_not_finished;
  112. $this->assertTrue($found, sprintf("No migration state found for version '%s' with source_module '%s' and destination_module '%s' declared in module '%s'", $version, $data[1], $data[2], $data[0]));
  113. }
  114. // Remove the declared finished from the discovered, leaving just the not
  115. // finished, if there are any. These should have an entry in the declared
  116. // not finished.
  117. $discovered_not_finished = array_diff($discovered_unique, $declared_unique[MigrationState::FINISHED]);
  118. foreach ($discovered_not_finished as $datum) {
  119. $data = str_getcsv($datum);
  120. $this->assertContains($datum, $declared_unique[MigrationState::NOT_FINISHED], sprintf("No migration found for version '%s' with source_module '%s' and destination_module '%s' declared in module '%s'", $version, $data[1], $data[2], $data[0]));
  121. }
  122. }
  123. /**
  124. * Enable all available modules.
  125. */
  126. protected function enableAllModules() {
  127. // Install all available modules.
  128. $module_handler = $this->container->get('module_handler');
  129. $modules = $this->coreModuleListDataProvider();
  130. $modules_enabled = $module_handler->getModuleList();
  131. $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
  132. $this->enableModules($modules_to_enable);
  133. return $modules;
  134. }
  135. }