Commit message: Migrate variables to config by bdone, chx, cosmicdreams, jacintocapote, jessehs, jibran, marvil07, mpgeek #2154955

This is the conversion of every upgrade_variable_to_config() call to migrations. They are tested. Yes, it's a big but it should be fairly easy to review as there is no architecture change here.

Comments

Status: Needs review » Needs work

The last submitted patch, migrate_variables_to_config.patch, failed testing.

chx’s picture

Status: Needs work » Needs review

Bot fluke.

chx’s picture

Issue summary: View changes
chx’s picture

Issue summary: View changes

I ran for i in core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6* ; do git log --follow --pretty=format:"%an" $i ; done|sort |uniq and created the commit message based on that.

jibran’s picture

+++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ActionSettings.php
@@ -0,0 +1,56 @@
+      'value' => 'i:35;',

IMO this should be serialize($var); This way it is more maintainable.
and here is a code review

$phpcs  --standard=Drupal --extensions=php,module,inc,install,test,profile,theme core/mod
ules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/

FILE: ...ate_drupal\lib\Drupal\migrate_drupal\Tests\Dump\Drupal6NodeSettings.php
--------------------------------------------------------------------------------
FOUND 4 ERROR(S) AFFECTING 3 LINE(S)
--------------------------------------------------------------------------------
  2 | ERROR | Missing file doc comment
 12 | ERROR | Missing short description in function doc comment
 13 | ERROR | There must be an empty line before the parameter block
 13 | ERROR | Missing comment for param "$database" at position 1
--------------------------------------------------------------------------------


FILE: ...rate_drupal\lib\Drupal\migrate_drupal\Tests\MigrateForumConfigsTest.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 1 WARNING(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
 44 | WARNING | Line exceeds 80 characters; contains 168 characters
 45 | ERROR   | No space before comment text; expected "//
    |         | $this->assertIdentical($config->get('forum_nav_vocabulary'),
    |         | '1');" but found
    |         | "//$this->assertIdentical($config->get('forum_nav_vocabulary'),
    |         | '1');"
--------------------------------------------------------------------------------


FILE: ...grate_drupal\lib\Drupal\migrate_drupal\Tests\MigrateNodeConfigsTest.php
--------------------------------------------------------------------------------
FOUND 3 ERROR(S) AFFECTING 2 LINE(S)
--------------------------------------------------------------------------------
 26 | ERROR | Missing function doc comment
 26 | ERROR | Visibility must be declared on method "testNodeSettings"
 32 | ERROR | Calling class constructors must always include parentheses
--------------------------------------------------------------------------------


FILE: ...ate_drupal\lib\Drupal\migrate_drupal\Tests\MigrateSystemConfigsTest.php
--------------------------------------------------------------------------------
FOUND 1 ERROR(S) AND 2 WARNING(S) AFFECTING 3 LINE(S)
--------------------------------------------------------------------------------
  58 | WARNING | Line exceeds 80 characters; contains 81 characters
  91 | WARNING | Line exceeds 80 characters; contains 81 characters
 139 | ERROR   | If the line declaring an array spans longer than 80
     |         | characters, each element should be broken into its own line
--------------------------------------------------------------------------------
jibran’s picture

StatusFileSize
new14.32 KB
new119.69 KB

Some doc fixes.

Status: Needs review » Needs work

The last submitted patch, 6: 2154955-6.patch, failed testing.

The last submitted patch, 6: 2154955-6.patch, failed testing.

jibran’s picture

Issue summary: View changes
StatusFileSize
new16.18 KB
new110.73 KB

Some more doc fixes.

chx’s picture

Status: Needs work » Needs review
StatusFileSize
new112.47 KB

That assert is right to fail; it was commented out in my patch; I have added a @TODO to explain what's up. I rolled #2130315: Variable to config: menu.settings into the issue as well.

jibran’s picture

StatusFileSize
new5.48 KB

Thanks for adding the @todo. Here is an interdiff :). It is a long patch needs interdiff to help reviewer.

jibran’s picture

For future reference.

  1. +++ b/core/modules/migrate_drupal/config/migrate.migration.d6_menu_settings.yml
    @@ -0,0 +1,14 @@
    \ No newline at end of file
    
    +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6MenuSettings.php
    @@ -0,0 +1,62 @@
    \ No newline at end of file
    

    EOL error.

  2. +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6MenuSettings.php
    @@ -0,0 +1,62 @@
    + * Contains \Drupal\migrate\Tests\Drupal6MenuSettings.
    
    +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/MigrateMenuConfigsTest.php
    @@ -0,0 +1,45 @@
    + * Contains \Drupal\system\Tests\Upgrade\MigrateMenuConfigsTest.
    

    Wrong namespace.

jibran’s picture

StatusFileSize
new1.9 KB
new115.15 KB

and fixes.

Status: Needs review » Needs work

The last submitted patch, 13: 2154955-12.patch, failed testing.

jibran’s picture

Status: Needs work » Needs review
StatusFileSize
new928 bytes
new115.15 KB

one more miner fix

chx’s picture

Status: Needs review » Needs work

Defaults need to be loaded. Stay tuned.

chx’s picture

Status: Needs work » Needs review

Let's keep that in a followup instead. Looks like this

  /**
   * {@inheritdoc}
   */
  public function import(Row $row) {
    $this->config
      ->setData(NestedArray::mergeDeep($this->getDefaultConfig(), $row->getDestination()))
      ->save();
  }

  /**
   * @return array
   */
  protected function getDefaultConfig() {
    if (isset($this->defaultConfig)) {
      return $this->defaultConfig;
    }
    list($name) = explode('.', $this->configuration['config_name']);
    $path = drupal_get_path('module', $name) ?: drupal_get_path('theme', $name);
    $file_storage = new FileStorage($path);
    return $file_storage->read($this->configuration['config_name']) ?: array();
  }

but then we get scope creep of architecture changes, unit tests for the new code etc. Let's stay on target.

The last submitted patch, 9: 2154955-9.patch, failed testing.

chx’s picture

StatusFileSize
new117.57 KB

The last stragglers slowly arrive (as the last subsystems get ported to CMI). Here's search.

chx’s picture

Issue summary: View changes
chx’s picture

StatusFileSize
new123.66 KB

dawehner questioned why the tests are not d6. they are now. I also applied the same changes to the sandbox. Here's how:

git diff --name-only HEAD |awk ' /Tests.Migrate/ { print "git mv " $1 " " gensub("/Migrate", "/d6/Migrate", 1)}' > /tmp/x.sh
sh /tmp/x.sh
cd core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6 
awk -i inplace 'BEGIN {FS=" "} BEGINFILE {changed=0} { print;if ($2 ~ "MigrateExecutable" && !changed) {print "use Drupal\\migrate_drupal\\Tests\\MigrateDrupalTestBase;";changed=1} }'  *
sed -i 's/namespace Drupal\\migrate_drupal\\Tests/namespace Drupal\\migrate_drupal\\Tests\\d6/' * 

I copied these commands just in case there's trouble.

Edit: I checked the test results and I see Drupal\migrate_drupal\Tests\d6\MigrateUserConfigsTest and all that. The move worked.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Thank you!

xjm’s picture

21: 2154955_21.patch queued for re-testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 21: 2154955_21.patch, failed testing.

chx’s picture

Status: Needs work » Needs review
StatusFileSize
new119.38 KB
jibran’s picture

Assigned: Unassigned » jibran
Status: Needs review » Needs work

@file doc is wrong in all files I'll fix it.

jibran’s picture

Assigned: jibran » Unassigned
Status: Needs work » Reviewed & tested by the community
StatusFileSize
new122.88 KB
new12.63 KB

It is a simple reroll so back to RTBC.

The last submitted patch, 25: 2154955_25.patch, failed testing.

The last submitted patch, 27: d8-migrate-variables-2154955-27.patch, failed testing.

chx’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new7.78 KB
new119.59 KB

mmm config is not type casting now. Except when it does.

Status: Needs review » Needs work

The last submitted patch, 30: 2154955_30.patch, failed testing.

benjy’s picture

Status: Needs work » Needs review
StatusFileSize
new3.83 KB
new123.42 KB

Reroll as requested.

benjy’s picture

StatusFileSize
new6.03 KB
new123.35 KB

Fixed other assertions.

The last submitted patch, 32: 2154955_32.patch, failed testing.

chx’s picture

Status: Needs review » Reviewed & tested by the community

Finally back to green. No changes since RTBC just config threw us by being strongly typed now.

webchick’s picture

Status: Reviewed & tested by the community » Needs review

Spent some time reviewing this today with xjm, moshe, and eff.

Over-arching concern is:

- How do we a) know that, and b) continue to know that ;) the dump PHP files are accurate as compared to the source schemas? In the past, we used actual database dumps to test the upgrade path; this moves it to code-generated database dumps, which is better for modularity, but presumes that we've caught everything accurate and transcribed it into PHP. So, is this coming from a script? If so, where is this script? I didn't find it on looking in /scripts.

- The second unknown (without lengthy manual verification) is whether or not all of the values in the dumps are reflected in the assertions in the tests, along with the correct default values. Can we automate this somewhow so that if these two ever were to fall out of sync, we would know?

A few comments about the specific elements of the patch:

  1. +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6ContactSettings.php
    @@ -0,0 +1,59 @@
    +    $database->schema()->createTable('variable', array(
    +      'fields' => array(
    +        'name' => array(
    +          'type' => 'varchar',
    +          'length' => 128,
    +          'not null' => TRUE,
    +          'default' => '',
    +        ),
    +        'value' => array(
    +          'type' => 'blob',
    +          'not null' => TRUE,
    +          'size' => 'big',
    +          'translatable' => TRUE,
    +        ),
    +      ),
    +      'primary key' => array(
    +        'name',
    +      ),
    +      'module' => 'contact',
    +      'name' => 'variable',
    +    ));
    
    

    This hunk ends up getting copy/pasted like 600 times in this patch. It'd be far preferable, I think, it to be in the code only once and then called into the various tests that need it. While the risk of that schema changing in D6 is pretty low, that's not necessarily the case for D7 which still has another N years go to until 9.x LTS comes out.

  2. +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSyslogConfigsTest.php
    @@ -0,0 +1,47 @@
    +    // @TODO: remove this typecast once there's schema of rhtis config.
    

    Just a silly typo.

  3. +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/d6/MigrateSystemConfigsTest.php
    @@ -0,0 +1,191 @@
    +    config_context_leave();
    ...
    +    config_context_enter('config.context.free');
    

    Can we add some comments to explain why this was done? No other tests had to do this.

  4. +++ b/core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Tests/Dump/Drupal6SystemSite.php
    @@ -40,35 +48,31 @@ public static function load(Connection $database) {
    -      'value' => 's:6:"drupal";',
    +      'value' => serialize('Drupal'),
    

    This whole section changes from serialized string values to serialize('Foo'). The rest of them don't. What's up with that? We should be consistent.

chx’s picture

> In the past, we used actual database dumps to test the upgrade path

And these are copypasted from the those dumps because we are way too lazy to write our own :D perhaps the values have been changed but the very reason the dumps have not been removed because we intend to use them for the d7-d8 migration.

> Can we automate this somehow

The assertions are only same-looking for this particular batch of migrations. They are very different for, say, entity migrations. So while we could automate -- we could run the migration, and write an assert for every piece of config data migrated -- it's pointless as it'd only do these tests which are written.

> Can we add some comments to explain why this was done? No other tests had to do this.

That's because simpletest overrides the file path config and that was the value we got instead of ours. Other tests need it theoretically to test correctly but they work without because simpletest doesn't override them.

> This whole section changes from serialized string values to serialize('Foo'). The rest of them don't. What's up with that? We should be consistent.

Busted! The serialized parts are typically the copypaste from the D6 dumpfiles and the serialize(foo) is what we manually added.

chx’s picture

StatusFileSize
new8.26 KB
new114.23 KB

The interdiff is partial to make it easier to review -- pointless to bloat the interdiff with the variable table creation moved into Drupal6DumpCommon for every dump. Note that a number of variables are not found in the D6 dumps (heh, actually a few are not found in D6 either, I removed those). A note on testing: our tests are by necessity much more through than the D6-D7 path -- the D6-D7 upgrade path tests could focus on changes but migrate copies over everything so we truly test whether everything migrates as we describe. This doesn't mean the descriptions are correct. if there would an API returning the site slogan we could test with that , short of that we hope that everything wanting the slogan runs \Drupal::config('system.site')->get('slogan').

webchick’s picture

Cool, class Drupal6DumpCommon addresses point 1. The other points are addressed, too.

The test coverage is extremely thorough, so I'm not criticising it, but I'm a bit concerned about ongoing maintenance/upkeep.

Right now, each Dump file adds 1-N lines like this:

+    ->values(array(
+      'name' => 'actions_max_stack',
+      'value' => 'i:35;',
+    ))

Then, later, there's a test that pulls in that database dump and makes 1-N test assertions like so:

+    $this->assertIdentical($config->get('recursion_limit'), 35);

So my questions are:

a) Where did 'i:35' come from in the first place, and how can we verify that it's correct against a valid D6 schema?

b) How do we know, other than rigorous manual cross-referencing of Dumps to Tests, whether or not we indeed have assertions for all values inserted?

c) Is there a way we can automate the generation of these dumps/assertions to catch changes that may have happened in the upstream schema (both schema and default values)? While this is unlikely to happen in Drupal 6, it could definitely still happen in Drupal 7 sometime in the next 4+ years until it's EOLed.

Does that make sense?

These questions aren't commit-blockers btw, but I would love to have them answered before we go too far down the road of mass-copying this pattern to other migrations.

webchick’s picture

Also, this is totally unrelated but just a question I had when reviewing the patch:

+id: d6_action_settings
+source:
+  plugin: drupal6_variable
+  variables:
+    - actions_max_stack
+process:
+  recursion_limit: actions_max_stack
+destination:
+  plugin: d8_config
+  config_name: action.settings

For "source," I can grep for drupal6_variable, and that gets me to core/modules/migrate_drupal/lib/Drupal/migrate_drupal/Plugin/migrate/source/d6/Variable.php.

For "destination," I can grep for d8_config (side-note: could we please make a minor follow-up to make those plugin IDs consistently spell out the word "drupal"? :D) and that gets me to core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/destination/Config.php

However, I'm not sure how to see what "process" class is being used to convert the values. It took us a few minutes to realize that it was doing "new name : old name." Maybe something for a follow-up issue to discuss DX-wise, not sure.

chx’s picture

> a) Where did 'i:35' come from in the first place, and how can we verify that it's correct against a valid D6 schema?

/home/chx/www/d6/includes/actions.inc
64:  if ($stack > variable_get('actions_max_stack', 35)) {

> How do we know, other than rigorous manual cross-referencing of Dumps to Tests, whether or not we indeed have assertions for all values inserted?

You trust the migration team it did the cross referencing.

> Is there a way we can automate the generation of these dumps/assertions

I recommend developing a strong AI :) Even for variables to config you need to find the default value in the code -- and if it's meaningless (say, empty string) create a testable version yourself. For generic case, it's truly hopeless.

> mass-copying this pattern to other migrations.

We aren't. We do create dumps for other migrations and we assert them but those are different dumps and different asserts.

> However, I'm not sure how to see what "process" class is being used to convert the values

You read the process handbook page to realize it's get. https://drupal.org/node/2129651
The get plugin is used to copy a value from a source property.

webchick’s picture

Ok, so in a nutshell (summarizing from IRC): those default values are manually entered through inspecting the D6 code, and then they're manually copy/pasted to assertion messages. There's no real way of automating this... default variables don't get into the database unless you somehow loop through and save the config form for every module, and even then it doesn't cover variables like actions_max_stack which only appears in variable_get().

So this is a bit unfortunate, because the tests basically only test the D6 schema at some point in time, and assume that whoever wrote that part of the tests did so correctly and was meticulous about finding all of the variables and transcribing their values properly in two different places. It also means that we will only catch holes and bugs in these default values/tests as people report bugs with the migration path.

However, what's here now is definitely far more complete than the current upgrade path tests, so I think in the end we come out ahead here.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

These changes looks pretty good. I am not sure whether it is a good idea to move the custom homepage and site name to pretty much the default one.
This removes the certainty that the patch really works, but I don't block based upon that.

In general I wonder whether migrate in core would migrate the views settings as well

webchick’s picture

Status: Reviewed & tested by the community » Fixed

Ok, awesome!

Committed and pushed to 8.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.