diff --git a/core/modules/migrate/src/Plugin/MigrateDestinationAuditInterface.php b/core/modules/migrate/src/Plugin/MigrateDestinationAuditInterface.php index 9592679..df92efb 100644 --- a/core/modules/migrate/src/Plugin/MigrateDestinationAuditInterface.php +++ b/core/modules/migrate/src/Plugin/MigrateDestinationAuditInterface.php @@ -11,6 +11,11 @@ /** * Checks whether ID conflicts exist. * + * ID conflicts exist if new content has been created without the migration + * system knowing about it. To find out if there is ID conflicts, this method + * should compare the highest destination ID to the highest migrated ID. If + * the former is greater than the later, there is ID conflicts. + * * @param MigrateIdMapInterface $id_map * The ID map for this migration. * diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php index 854bb1a..00ffb8d 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6AuditIdsTest.php @@ -2,8 +2,16 @@ namespace Drupal\Tests\migrate_drupal\Kernel\d6; +use Drupal\aggregator\Entity\Feed; +use Drupal\aggregator\Entity\Item; +use Drupal\block_content\Entity\BlockContent; +use Drupal\comment\Entity\Comment; +use Drupal\file\Entity\File; +use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\KernelTests\FileSystemModuleDiscoveryDataProviderTrait; use Drupal\node\Entity\Node; +use Drupal\taxonomy\Entity\Term; +use Drupal\user\Entity\User; /** * Tests the migration auditor for ID conflicts. @@ -31,46 +39,15 @@ protected function setUp() { $this->installEntitySchema('menu_link_content'); $this->installEntitySchema('node'); $this->installEntitySchema('taxonomy_term'); + $this->installSchema('book', ['book']); $this->installSchema('dblog', ['watchdog']); + $this->installSchema('forum', ['forum_index']); + $this->installSchema('search', ['search_dataset']); + $this->installSchema('system', ['sequences']); $this->installSchema('tracker', ['tracker_node', 'tracker_user']); } /** - * Tests all migrations with no ID conflicts. - */ - public function testAllMigrationsWithNoConflicts() { - $plugin_manager = $this->container->get('plugin.manager.migration'); - - // Get all migration definitions. - $migrations = []; - foreach ($plugin_manager->getDefinitions() as $migration_id => $migration) { - $migrations[$migration_id] = $this->getMigration($migration_id); - } - - // Audit the IDs of all migrations. There should be no conflicts since no - // content has been created. - $conflicts = $this->container->get('migrate.id_auditor')->auditIds($migrations); - $this->assertTrue(empty($conflicts)); - } - - /** - * Tests the node migration with ID conflicts. - */ - public function testMigrationWithIdConflicts() { - // Create a node of type page. - Node::create(['type' => 'page', 'title' => 'foo'])->save(); - - // Audit the IDs of the d6_node migrations for the page & article node type. - // There should be a conflict since there's a new node that wasn't created - // from a previous migration. - $conflicts = $this->container->get('migrate.id_auditor')->auditIds([ - $this->getMigration('d6_node:article'), - $this->getMigration('d6_node:page'), - ]); - $this->assertSame(['node'], array_keys($conflicts)); - } - - /** * Tests multiple migrations to the same destination with no ID conflicts. */ public function testMultipleMigrationWithoutIdConflicts() { @@ -99,4 +76,126 @@ public function testMultipleMigrationWithoutIdConflicts() { $this->assertTrue(empty($conflicts)); } + /** + * Tests all migrations with no ID conflicts. + */ + public function testAllMigrationsWithNoIdConflicts() { + $plugin_manager = $this->container->get('plugin.manager.migration'); + + // Get all migration definitions. + $migrations = []; + foreach ($plugin_manager->getDefinitions() as $migration_id => $migration) { + $migrations[$migration_id] = $this->getMigration($migration_id); + } + + // Audit the IDs of all migrations. There should be no conflicts since no + // content has been created. + $conflicts = $this->container->get('migrate.id_auditor')->auditIds($migrations); + $this->assertTrue(empty($conflicts)); + } + + /** + * Tests all migrations with ID conflicts. + */ + public function testAllMigrationsWithIdConflicts() { + $plugin_manager = $this->container->get('plugin.manager.migration'); + + // Get all migration definitions. + $migrations = []; + foreach ($plugin_manager->getDefinitions() as $migration_id => $migration) { + $migrations[$migration_id] = $this->getMigration($migration_id); + } + + // Create content. + $this->createContent(); + + // Audit the IDs of all migrations. There should be no conflicts since no + // content has been created. + $conflicts = $this->container->get('migrate.id_auditor')->auditIds($migrations); + ksort($conflicts); + + $expected = [ + 'aggregator_feed', + 'aggregator_item', + 'block_content', + 'comment', + 'file', + 'menu_link_content', + 'node', + 'taxonomy_term', + 'user', + ]; + + $this->assertSame($expected, array_keys($conflicts)); + } + + protected function createContent() { + // Create an aggregator feed. + $feed = Feed::create([ + 'title' => 'feed', + 'url' => 'http://www.example.com', + ]); + $feed->save(); + + // Create an aggregator feed item. + $item = Item::create([ + 'title' => 'feed item', + 'fid' => $feed->id(), + 'link' => 'http://www.example.com', + ]); + $item->save(); + + // Create a block content. + $block = BlockContent::create([ + 'info' => 'block', + 'type' => 'block', + ]); + $block->save(); + + // Create a node. + $node = Node::create([ + 'type' => 'page', + 'title' => 'page', + ]); + $node->save(); + + // Create a comment. + $comment = Comment::create([ + 'comment_type' => 'comment', + 'field_name' => 'comment', + 'entity_type' => 'node', + 'entity_id' => $node->id(), + ]); + $comment->save(); + + // Create a file. + $file = File::create([ + 'uri' => 'public://example.txt', + ]); + $file->save(); + + // Create a menu link. + $menu_link = MenuLinkContent::create([ + 'title' => 'menu link', + 'link' => ['uri' => 'http://www.example.com'], + 'menu_name' => 'tools', + ]); + $menu_link->save(); + + // Create a taxonomy term. + $term = Term::create([ + 'name' => 'term', + 'vid' => 'term', + ]); + $term->save(); + + // Create a user. + $user = User::create([ + 'uid' => 2, + 'name' => 'user', + 'mail' => 'user@example.com', + ]); + $user->save(); + } + } diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php b/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php new file mode 100644 index 0000000..720dccc --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Kernel/d7/MigrateDrupal7AuditIdsTest.php @@ -0,0 +1,201 @@ +coreModuleListDataProvider()); + parent::setUp(); + + // Install required schemas. + $this->installEntitySchema('aggregator_item'); + $this->installEntitySchema('aggregator_feed'); + $this->installEntitySchema('block_content'); + $this->installEntitySchema('comment'); + $this->installEntitySchema('file'); + $this->installEntitySchema('menu_link_content'); + $this->installEntitySchema('node'); + $this->installEntitySchema('taxonomy_term'); + $this->installSchema('book', ['book']); + $this->installSchema('dblog', ['watchdog']); + $this->installSchema('forum', ['forum_index']); + $this->installSchema('search', ['search_dataset']); + $this->installSchema('system', ['sequences']); + $this->installSchema('tracker', ['tracker_node', 'tracker_user']); + } + + /** + * Tests multiple migrations to the same destination with no ID conflicts. + */ + public function testMultipleMigrationWithoutIdConflicts() { + // Create a node of type page. + Node::create(['type' => 'page', 'title' => 'foo'])->save(); + + // Insert data in the d7_node:page migration mappping table to simulate a + // previously migrated node. + $table_name = $this->getMigration('d7_node:page')->getIdMap()->mapTableName(); + $this->container->get('database')->insert($table_name) + ->fields([ + 'source_ids_hash' => 1, + 'sourceid1' => 1, + 'destid1' => 1, + ]) + ->execute(); + + // Audit the IDs of the d7_node migrations for the page & article node type. + // There should be no conflicts since the highest destination ID should be + // equal to the highest migrated ID, as found in the aggregated mapping + // tables of the two node migrations. + $conflicts = $this->container->get('migrate.id_auditor')->auditIds([ + $this->getMigration('d7_node:page'), + $this->getMigration('d7_node:article'), + ]); + $this->assertTrue(empty($conflicts)); + } + + /** + * Tests all migrations with no ID conflicts. + */ + public function testAllMigrationsWithNoIdConflicts() { + $plugin_manager = $this->container->get('plugin.manager.migration'); + + // Get all migration definitions. + $migrations = []; + foreach ($plugin_manager->getDefinitions() as $migration_id => $migration) { + $migrations[$migration_id] = $this->getMigration($migration_id); + } + + // Audit the IDs of all migrations. There should be no conflicts since no + // content has been created. + $conflicts = $this->container->get('migrate.id_auditor')->auditIds($migrations); + $this->assertTrue(empty($conflicts)); + } + + /** + * Tests all migrations with ID conflicts. + */ + public function testAllMigrationsWithIdConflicts() { + $plugin_manager = $this->container->get('plugin.manager.migration'); + + // Get all migration definitions. + $migrations = []; + foreach ($plugin_manager->getDefinitions() as $migration_id => $migration) { + $migrations[$migration_id] = $this->getMigration($migration_id); + } + + // Create content. + $this->createContent(); + + // Audit the IDs of all migrations. There should be no conflicts since no + // content has been created. + $conflicts = $this->container->get('migrate.id_auditor')->auditIds($migrations); + ksort($conflicts); + + $expected = [ + 'aggregator_feed', + 'aggregator_item', + 'block_content', + 'comment', + 'file', + 'menu_link_content', + 'node', + 'taxonomy_term', + 'user', + ]; + + $this->assertSame($expected, array_keys($conflicts)); + } + + protected function createContent() { + // Create an aggregator feed. + $feed = Feed::create([ + 'title' => 'feed', + 'url' => 'http://www.example.com', + ]); + $feed->save(); + + // Create an aggregator feed item. + $item = Item::create([ + 'title' => 'feed item', + 'fid' => $feed->id(), + 'link' => 'http://www.example.com', + ]); + $item->save(); + + // Create a block content. + $block = BlockContent::create([ + 'info' => 'block', + 'type' => 'block', + ]); + $block->save(); + + // Create a node. + $node = Node::create([ + 'type' => 'page', + 'title' => 'page', + ]); + $node->save(); + + // Create a comment. + $comment = Comment::create([ + 'comment_type' => 'comment', + 'field_name' => 'comment', + 'entity_type' => 'node', + 'entity_id' => $node->id(), + ]); + $comment->save(); + + // Create a file. + $file = File::create([ + 'uri' => 'public://example.txt', + ]); + $file->save(); + + // Create a menu link. + $menu_link = MenuLinkContent::create([ + 'title' => 'menu link', + 'link' => ['uri' => 'http://www.example.com'], + 'menu_name' => 'tools', + ]); + $menu_link->save(); + + // Create a taxonomy term. + $term = Term::create([ + 'name' => 'term', + 'vid' => 'term', + ]); + $term->save(); + + // Create a user. + $user = User::create([ + 'uid' => 2, + 'name' => 'user', + 'mail' => 'user@example.com', + ]); + $user->save(); + } + +}