Mercurial > hg > isophonics-drupal-site
comparison core/modules/migrate/tests/src/Kernel/MigrateTestBase.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\migrate\Kernel; | |
4 | |
5 use Drupal\Core\Database\Database; | |
6 use Drupal\KernelTests\KernelTestBase; | |
7 use Drupal\migrate\MigrateExecutable; | |
8 use Drupal\migrate\MigrateMessageInterface; | |
9 use Drupal\migrate\Plugin\MigrateIdMapInterface; | |
10 use Drupal\migrate\Plugin\Migration; | |
11 use Drupal\migrate\Plugin\MigrationInterface; | |
12 use Drupal\migrate\Row; | |
13 | |
14 /** | |
15 * Creates abstract base class for migration tests. | |
16 */ | |
17 abstract class MigrateTestBase extends KernelTestBase implements MigrateMessageInterface { | |
18 | |
19 /** | |
20 * TRUE to collect messages instead of displaying them. | |
21 * | |
22 * @var bool | |
23 */ | |
24 protected $collectMessages = FALSE; | |
25 | |
26 /** | |
27 * A two dimensional array of messages. | |
28 * | |
29 * The first key is the type of message, the second is just numeric. Values | |
30 * are the messages. | |
31 * | |
32 * @var array | |
33 */ | |
34 protected $migrateMessages; | |
35 | |
36 /** | |
37 * The primary migration being tested. | |
38 * | |
39 * @var \Drupal\migrate\Plugin\MigrationInterface | |
40 */ | |
41 protected $migration; | |
42 | |
43 /** | |
44 * The source database connection. | |
45 * | |
46 * @var \Drupal\Core\Database\Connection | |
47 */ | |
48 protected $sourceDatabase; | |
49 | |
50 public static $modules = ['migrate']; | |
51 | |
52 /** | |
53 * {@inheritdoc} | |
54 */ | |
55 protected function setUp() { | |
56 parent::setUp(); | |
57 $this->createMigrationConnection(); | |
58 $this->sourceDatabase = Database::getConnection('default', 'migrate'); | |
59 } | |
60 | |
61 /** | |
62 * Changes the database connection to the prefixed one. | |
63 * | |
64 * @todo Remove when we don't use global. https://www.drupal.org/node/2552791 | |
65 */ | |
66 private function createMigrationConnection() { | |
67 // If the backup already exists, something went terribly wrong. | |
68 // This case is possible, because database connection info is a static | |
69 // global state construct on the Database class, which at least persists | |
70 // for all test methods executed in one PHP process. | |
71 if (Database::getConnectionInfo('simpletest_original_migrate')) { | |
72 throw new \RuntimeException("Bad Database connection state: 'simpletest_original_migrate' connection key already exists. Broken test?"); | |
73 } | |
74 | |
75 // Clone the current connection and replace the current prefix. | |
76 $connection_info = Database::getConnectionInfo('migrate'); | |
77 if ($connection_info) { | |
78 Database::renameConnection('migrate', 'simpletest_original_migrate'); | |
79 } | |
80 $connection_info = Database::getConnectionInfo('default'); | |
81 foreach ($connection_info as $target => $value) { | |
82 $prefix = is_array($value['prefix']) ? $value['prefix']['default'] : $value['prefix']; | |
83 // Simpletest uses 7 character prefixes at most so this can't cause | |
84 // collisions. | |
85 $connection_info[$target]['prefix']['default'] = $prefix . '0'; | |
86 | |
87 // Add the original simpletest prefix so SQLite can attach its database. | |
88 // @see \Drupal\Core\Database\Driver\sqlite\Connection::init() | |
89 $connection_info[$target]['prefix'][$value['prefix']['default']] = $value['prefix']['default']; | |
90 } | |
91 Database::addConnectionInfo('migrate', 'default', $connection_info['default']); | |
92 } | |
93 | |
94 /** | |
95 * {@inheritdoc} | |
96 */ | |
97 protected function tearDown() { | |
98 $this->cleanupMigrateConnection(); | |
99 parent::tearDown(); | |
100 $this->databaseDumpFiles = []; | |
101 $this->collectMessages = FALSE; | |
102 unset($this->migration, $this->migrateMessages); | |
103 } | |
104 | |
105 /** | |
106 * Cleans up the test migrate connection. | |
107 * | |
108 * @todo Remove when we don't use global. https://www.drupal.org/node/2552791 | |
109 */ | |
110 private function cleanupMigrateConnection() { | |
111 Database::removeConnection('migrate'); | |
112 $original_connection_info = Database::getConnectionInfo('simpletest_original_migrate'); | |
113 if ($original_connection_info) { | |
114 Database::renameConnection('simpletest_original_migrate', 'migrate'); | |
115 } | |
116 } | |
117 | |
118 /** | |
119 * Prepare any dependent migrations. | |
120 * | |
121 * @param array $id_mappings | |
122 * A list of ID mappings keyed by migration IDs. Each ID mapping is a list | |
123 * of two arrays, the first are source IDs and the second are destination | |
124 * IDs. | |
125 */ | |
126 protected function prepareMigrations(array $id_mappings) { | |
127 $manager = $this->container->get('plugin.manager.migration'); | |
128 foreach ($id_mappings as $migration_id => $data) { | |
129 foreach ($manager->createInstances($migration_id) as $migration) { | |
130 $id_map = $migration->getIdMap(); | |
131 $id_map->setMessage($this); | |
132 $source_ids = $migration->getSourcePlugin()->getIds(); | |
133 foreach ($data as $id_mapping) { | |
134 $row = new Row(array_combine(array_keys($source_ids), $id_mapping[0]), $source_ids); | |
135 $id_map->saveIdMapping($row, $id_mapping[1]); | |
136 } | |
137 } | |
138 } | |
139 } | |
140 | |
141 /** | |
142 * Modify a migration's configuration before executing it. | |
143 * | |
144 * @param \Drupal\migrate\Plugin\MigrationInterface $migration | |
145 * The migration to execute. | |
146 */ | |
147 protected function prepareMigration(MigrationInterface $migration) { | |
148 // Default implementation for test classes not requiring modification. | |
149 } | |
150 | |
151 /** | |
152 * Executes a single migration. | |
153 * | |
154 * @param string|\Drupal\migrate\Plugin\MigrationInterface $migration | |
155 * The migration to execute, or its ID. | |
156 */ | |
157 protected function executeMigration($migration) { | |
158 if (is_string($migration)) { | |
159 $this->migration = $this->getMigration($migration); | |
160 } | |
161 else { | |
162 $this->migration = $migration; | |
163 } | |
164 if ($this instanceof MigrateDumpAlterInterface) { | |
165 static::migrateDumpAlter($this); | |
166 } | |
167 | |
168 $this->prepareMigration($this->migration); | |
169 (new MigrateExecutable($this->migration, $this))->import(); | |
170 } | |
171 | |
172 /** | |
173 * Executes a set of migrations in dependency order. | |
174 * | |
175 * @param string[] $ids | |
176 * Array of migration IDs, in any order. | |
177 */ | |
178 protected function executeMigrations(array $ids) { | |
179 $manager = $this->container->get('plugin.manager.migration'); | |
180 array_walk($ids, function ($id) use ($manager) { | |
181 // This is possibly a base plugin ID and we want to run all derivatives. | |
182 $instances = $manager->createInstances($id); | |
183 array_walk($instances, [$this, 'executeMigration']); | |
184 }); | |
185 } | |
186 | |
187 /** | |
188 * {@inheritdoc} | |
189 */ | |
190 public function display($message, $type = 'status') { | |
191 if ($this->collectMessages) { | |
192 $this->migrateMessages[$type][] = $message; | |
193 } | |
194 else { | |
195 $this->assert($type == 'status', $message, 'migrate'); | |
196 } | |
197 } | |
198 | |
199 /** | |
200 * Start collecting messages and erase previous messages. | |
201 */ | |
202 public function startCollectingMessages() { | |
203 $this->collectMessages = TRUE; | |
204 $this->migrateMessages = []; | |
205 } | |
206 | |
207 /** | |
208 * Stop collecting messages. | |
209 */ | |
210 public function stopCollectingMessages() { | |
211 $this->collectMessages = FALSE; | |
212 } | |
213 | |
214 /** | |
215 * Records a failure in the map table of a specific migration. | |
216 * | |
217 * This is done in order to test scenarios which require a failed row. | |
218 * | |
219 * @param string|\Drupal\migrate\Plugin\MigrationInterface $migration | |
220 * The migration entity, or its ID. | |
221 * @param array $row | |
222 * The raw source row which "failed". | |
223 * @param int $status | |
224 * (optional) The failure status. Should be one of the | |
225 * MigrateIdMapInterface::STATUS_* constants. Defaults to | |
226 * MigrateIdMapInterface::STATUS_FAILED. | |
227 */ | |
228 protected function mockFailure($migration, array $row, $status = MigrateIdMapInterface::STATUS_FAILED) { | |
229 if (is_string($migration)) { | |
230 $migration = $this->getMigration($migration); | |
231 } | |
232 /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ | |
233 $destination = array_map(function () { | |
234 return NULL; | |
235 }, $migration->getDestinationPlugin()->getIds()); | |
236 $row = new Row($row, $migration->getSourcePlugin()->getIds()); | |
237 $migration->getIdMap()->saveIdMapping($row, $destination, $status); | |
238 } | |
239 | |
240 /** | |
241 * Gets the migration plugin. | |
242 * | |
243 * @param $plugin_id | |
244 * The plugin ID of the migration to get. | |
245 * | |
246 * @return \Drupal\migrate\Plugin\Migration | |
247 * The migration plugin. | |
248 */ | |
249 protected function getMigration($plugin_id) { | |
250 return $this->container->get('plugin.manager.migration')->createInstance($plugin_id); | |
251 } | |
252 | |
253 } |