Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Damien Tournoud’s picture

I don't get it. Why is "modules_installed" broken?

chx’s picture

Because at this point the module list and the implementation list and the router and the actions list is not yet rebuilt that happens inside module_enable. Which is quite OK when you install a module to an existing install but when you create a child Drupal which has a significantly list to the parent Drupal and one of the modules in the parent Drupal happens to fire a cache clear against a cache table which is not in the child Drupal then you are in trouble. (Check the fields-in-core bzr repo for fields.module. Hint, hint.)

moshe weitzman’s picture

$disable_modules_installed_hook = FALSE. This is ugly enough, without a double negative. Please use $modules_installed_hook = TRUE instead

Damien Tournoud’s picture

So the issue is that the module hook cache is not flushed after we call drupal_install_system(). Would the attached patch work?

Damien Tournoud’s picture

More precisely, the issue is we preload the registry of the child site with information from the parent registry, making module_implements() believe that it should run those hooks.

The solution is to preload the registry way later, just before rebuilding it, not before enabling modules.

Damien Tournoud’s picture

A static modifier was missing in currentlyRunning().

Anonymous’s picture

hmm, so webchick was right, this performance hack did break something after all. bummer, it was so quick!

given that the preload stuff is pure, kitten-killing performance hackery, i don't like either of these solutions. the initial version of the preloadRegistry patch was a kitten-killer, and it was rejected. the patch that got in didn't change anything on the non-test side, and i think we should stick to that.

@chx: your patch makes the module install process different when installing modules, which is bound to bite us somewhere.

@Damien: your patch avoids any problems during install, but not if a test enables a module post-install. in that case, we have the same problem, as we can get bogus calls to hook_modules_installed, which is bound to bite us somewhere.

here's a version of preloadRegistry that only preloads code from includes/*. this won't cause any of the issues with module implementations, and will save us about 700 queries for each setup, so still worth it i think.

Anonymous’s picture

note, i did think about preloading the registry for all modules returned by drupal_required_modules as well, as none of them implement hook_modules_installed, but this could produce subtle bugs later if this changes, and we don't remember this issue. thoughts?

Damien Tournoud’s picture

@Damien: your patch avoids any problems during install, but not if a test enables a module post-install. in that case, we have the same problem, as we can get bogus calls to hook_modules_installed, which is bound to bite us somewhere.

Oh, true, but that's easy to fix: simply $this->canPreloadRegistry = FALSE; after the registry is rebuilt.

I still like my approach better.

chx’s picture

Dont we know perfectly well which modules will be enabled? We do. There is modules information in both the registry_files and the registry table.

Anonymous’s picture

FileSize
2.29 KB

Dont we know perfectly well which modules will be enabled? We do. There is modules information in both the registry_files and the registry table.

yes, but this suffers from the same problem - to avoid the overhead of building a modules registry entries, we need to load them before its enabled. currently, there's no way to do this after the call to hook_modules_installed but before module_enable (without changing module install/enable code just for our testing performance hack).

attached patch only preloads a modules registry entries if the module doesn't implement hook_modules_installed. this keeps the hacks testing-side-only, and we get to keep most of the optimisation, as this hook is not implemented much.

Damien Tournoud’s picture

@justinrandell: I see no reason why an install function couldn't (at least indirectly) call a hook itself. So this is very fragile.

The way to go is what I implemented in #6, with the addition of a $this->canPreloadRegistry = FALSE; after module installation, so that we don't preload the registry at latter calls (it would be inefficient).

Note that you were wrong in #7:

@Damien: your patch avoids any problems during install, but not if a test enables a module post-install. in that case, we have the same problem, as we can get bogus calls to hook_modules_installed, which is bound to bite us somewhere.

FALSE: in my approach, we only preload the registry at the very last moment: just before rebuilding it. It's 100% safe, in all cases.

Here is a reroll.

Damien Tournoud’s picture

Should I add that my patch also has the added benefit of implementing DrupalWebTestCase::currentlyRunning() which will prove useful (in a later issue) to cleanup some of the the crappy "simpletest" regexps that pollute core.

Anonymous’s picture

Status: Needs review » Needs work

@Damien: i'm coming around to your way of thinking, though i still dislike changing registry code just to make things faster.

having said that, if we're going for a performance hack, lets get the best performance. we can still preload everything in includes/* unconditionally, and avoid 700-odd queries.

so, lets preload these files before the first registry rebuild, otherwise this patch will slow down simpletest building quite a lot.

webchick’s picture

subscribe. :)

Damien Tournoud’s picture

*sob* this is still an issue.

Damien Tournoud’s picture

Status: Needs work » Needs review
FileSize
4.34 KB

Rerolled.

Status: Needs review » Needs work

The last submitted patch failed testing.

Damien Tournoud’s picture

Status: Needs work » Needs review
FileSize
4.36 KB

The Field tests are already defining a $instance member variable. Moving to $this_instance.

Dries’s picture

I'd still like to see an answer to #14, and ideally a final review from @justinrandell.

Investigating the different approaches, I thought justin's approach was less of a hack.

Anonymous’s picture

Issue tags: +Registry

tagging with Registry

Anonymous’s picture

FileSize
4.37 KB

just refreshing patch for HEAD, no changes.

Anonymous’s picture

Status: Needs review » Needs work
+    // Refresh the module list and the implementation cache so that modules
+    // are installed in a clean environment and can safely fire hooks.
+    module_list(TRUE);
+    registry_rebuild();

on the child side, the registry isn't polluted by preloading from the parent at this point, so i don't understand the need for this first rebuild. DamZ, can you hit me with a cluebat?

if we can take this out, then my point at #14 is moot, because we'll get all of the includes resources pulled in from the parent.

also, can we can take out the $disable_modules_installed hack? i couldn't see anything else using that, so:

function drupal_install_modules($module_list = array(), $disable_modules_installed_hook = FALSE) {

can go back to:

function drupal_install_modules($module_list = array()) {

DrupalWebTestCase::setUp is still really fat. if this patch lands, we still run 4000+ queries in setup for each test. the low hanging fruit seems to be rebuilding the theme registry for each test (around 2228 queries).

i worked up a proof of concept patch to cache (keyed by theme name and test module list), but i'm not sure if thats just asking for more trouble.

moshe weitzman’s picture

I wonder if we truly need the theme registry. I'd love to rip it out and just do real time template discovery - then benchmark. Don't think I will get to that soon, but someone should.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
5.34 KB

patch attached does what i suggested in #23, lets see what the test bot thinks.

yched’s picture

Subscribe. I'm wondering if it's the same bug we're hitting in #372743-18: Body and teaser as fields (second paragraph) :

The fails are caused by the body_field instance being marked as widget_active = FALSE, because of module install workflow at setUp:
The 'book' content type (and thus the body instance for 'book') is created in book_install(). By this time text.module is installed, but not 'active', because drupal_install_modules($module_list) installs all modules, *then* marks them as active and refreshes module_list().
So $widget_active = module_exists($widget_module); in _field_write_instance() returns FALSE.
All tests pass if I replace this line with $widget_active = drupal_function_exists($widget_module . '_field_widget');

The 'body as field' patch is getting stale, so I'd need to reroll it first and test.

Dries’s picture

Status: Needs review » Needs work

1.

+  // When running in SimpleTest mode, we preload the child registry using what
+  // we already know from the parent registry.

I'd like to see us add a sentence that explains _why_ we do this.

2. The name "$this_instance" is rather poor. Can we think of a more descriptive name like $current_test or something?

3.

+    // It is now useful to preload the child registry site with information
+    // from the parent registry.

I'd like to see us add a sentence that explains _why_ it is now useful and/or why it wasn't useful before.

Damien Tournoud’s picture

Re: #23: we need to rebuild the registry as soon as possible, for two reasons: (1) static caches are full of information from the parent site and (2) the registry tables are empty, so hooks implemented by modules installed by drupal_install_system() will not be recognized.

This operation should be relatively cheap, especially if we decide to pre-copy include/* files.

JamesAn’s picture

Bump..

#515040: Simpletest throws exception on a fresh install that I filed a few days ago may stem from this problem. In short, simpletest doesn't work with a fresh install of head if the profile module is enabled.

A call to menu_rebuild() is made when simpletest is installing the toolbar module for the child site. Even though the profile module is not installed (and will not be installed), menu_rebuild() somehow knows that the profile module is enabled on the parent site, something that shouldn't happen.

scor’s picture

This patch does not apply. Some hunks have been applied to HEAD already. What's the status of this issue?

I've created #594234: hook_modules_installed() not invoked during tests which I believe is a related problem.

sun’s picture

Assigned: chx » Unassigned
Status: Needs work » Needs review
FileSize
6.2 KB

$disable_modules_installed_hook argument was introduced in the monster Field API patch, but the registry is gone now, and disabling this hook for modules that are installed in SimpleTest totally breaks my tests in a contributed module.

This is a straight re-roll against HEAD. If this passes, then we don't really need to preload the class registry, and only do it for performance reasons. Which in turn would mean that we can simply remove the argument.

sun’s picture

Continuing that conclusion, I can run tests just fine with a total revert of the $disable_modules_installed_hook argument.

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.32.patch, failed testing.

sun’s picture

Status: Needs work » Needs review

I have no idea.

This patch also breaks #569326: Add hook_taxonomy_vocabulary_info()

sun’s picture

still no luck

sun’s picture

Seems like http://api.drupal.org/api/function/rdf_install/7 had the same problem...

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.35.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
4.57 KB

More clean-ups, but Drupal render test is still failing for me (as for the bot).... chx mentions it passes for him... (?)

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.38.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
5.38 KB

I'm really running out of ideas now... additionally synced with install_finished() now.

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.40.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
4.56 KB

We're calling $this->refreshVariables(); too late?

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.42.patch, failed testing.

carlos8f’s picture

subscribing

sun’s picture

Status: Needs work » Needs review
FileSize
3.8 KB

Let's see whether #399642: Replace drupal_install_modules() with an improved module_enable() solved the problems.

Thus, re-rolled, no further changes. So this patch still updates setUp() to do exactly the same as http://api.drupal.org/api/function/install_finished/7

sun’s picture

Assigned: Unassigned » sun

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.45.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
4.47 KB
carlos8f’s picture

subscribing

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.48.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
Issue tags: +API change

.

sun.core’s picture

Issue tags: -Registry, -API change

#48: drupal.modules-installed.48.patch queued for re-testing.

Status: Needs review » Needs work
Issue tags: +Registry, +API change

The last submitted patch, drupal.modules-installed.48.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
3.76 KB

Re-rolled against HEAD and removed the change for unit tests (no modules installed here).

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.54.patch, failed testing.

sun’s picture

Obviously, the theme system information is not reset at all for any test that is run.

sun’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.56.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
4.75 KB

This works locally, let's see what the testbot has to say.

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.59.patch, failed testing.

Dries’s picture

The test bot doesn't like you anymore, sun. ;)

sun’s picture

Status: Needs work » Needs review
FileSize
8.58 KB

No surprise... who doesn't hate me?

Actually, those entire RDF tests contain plenty of workarounds for the bug that this issue is fixing. Removed all of those. After doing so, it seems that the RDF functionality seems to work properly, but the tests are trying to verify totally weird stuff, which was true with previous workarounds, but not with a proper module installation behavior.

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.62.patch, failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
8.55 KB

well, so why don't you eat this?

sun’s picture

or rather this? :P

sun’s picture

oh my, it's getting late here, sorry.

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.66.patch, failed testing.

scor’s picture

Status: Needs work » Needs review
FileSize
7.78 KB

@sun, yes, we really had a hard time getting the rdf tests to work and found out hook_modules_installed() was not invoked during testing (plus other caching issues). It obviously came form simpletest since everything worked when installing manually. These workarounds can be removed now the underlying issue is being fixed. The patch attached fixes the rdf test which failed in #66 (similar to patch in #65).

sun’s picture

+++ modules/rdf/rdf.test
@@ -196,13 +192,14 @@ class RdfCrudTestCase extends DrupalWebTestCase {
-    $this->assertTrue(rdf_mapping_save($mapping[1]) === SAVED_NEW, t('Second mapping was inserted.'));
+    rdf_mapping_save($mapping[1]);

#66 failed, because I thought I could remove this rdf_mapping_save().

Why is it needed? Shouldn't rdf_entity_info_alter() store the mapping already?

EDIT: The result of that save operation is 0 (zero), returned by db_merge(), which (I think) means that nothing was inserted and nothing was updated.

scor’s picture

The second mapping is for the blog bundle (see in rdf_test.module), and because the blog module is not enabled in this test there is no 'blog' bundle in the entity info cache to hold that mapping. That's why we need to have the explicit save operation (which is fine since that's the operation we're testing here).

EDIT: the above is not a good explanation since we're not using the entity info cache in this particular test. I'll rewrite the save operation test tomorrow morning.

Status: Needs review » Needs work

The last submitted patch, drupal.modules-installed.68.patch, failed testing.

scor’s picture

Status: Needs work » Needs review
FileSize
10.84 KB

the variable names in RdfCrudTestCase were confusing so I've refactored it. all rdf tests are now passing on my machine.

sun’s picture

Status: Needs review » Reviewed & tested by the community

Awesome! Thanks for helping out, scor!

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

Status: Fixed » Closed (fixed)
Issue tags: -Registry, -API change

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