search_update_totals() should be more robust
andypost - June 29, 2009 - 20:22
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | search.module |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | duplicate |
Jump to:
Description
Here is a host with replicatable errors
console 2 run http://drupalbin.com/10206
http://drupalbin.com/10203 on mine server
http://drupalbin.com/10204 on AWS

#1
On the same site, I ran simpletest from the UI.
http://drupalbin.com/10207
SSH keys and logins are available. Just ask in #drupal-infrastructure.
#2
Care to identify the test cases that are failing?
#3
I have stable fault on test system->Cron Run
http://php.net/manual/en/function.set-exception-handler.php
In comments I found mostly happens when exception raised inside exception handler
#4
So when I run from console scrups/run-tests.sh
Trigger cron (system) actions 30 passes, 0 fails, and 0 exceptions
Fatal error: Exception thrown without a stack frame in Unknown on line 0
Upload functionality 113 passes, 28 fails, and 4 exceptions
Suppose, exception just breaks batch, because result - tests passed
#5
I'm really not sure what the issue is, can someone provide a bit more detail...seems like it changed from the original thought.
#6
Test “System -> Cron run” fails with an exception; the message returned is:
Message: {"status":true,"percentage":"100","message":"Processed test 1 of 1 - \x3cem\x3eCron run\x3c\/em\x3e.\x3cdiv class=\"simpletest-pass\"\x3eOverall results: 18 passes, 0 fails, and 0 exceptions\x3c\/div\x3e\x3cdiv class=\"item-list\"\x3e\x3cul\x3e\x3cli class=\"first last\"\x3e\x3cdiv class=\"simpletest-pass\"\x3eCron run: 18 passes, 0 fails, and 0 exceptions\x3c\/div\x3e\x3c\/li\x3e\n\x3c\/ul\x3e\x3c\/div\x3e"}Fatal error: Exception thrown without a stack frame in Unknown on line 0
Test “System -> Trigger cron (system) actions” fails with an exception; the message returned is:
Message: {"status":true,"percentage":"100","message":"Processed test 1 of 1 - \x3cem\x3eTrigger cron (system) actions\x3c\/em\x3e.\x3cdiv class=\"simpletest-pass\"\x3eOverall results: 30 passes, 0 fails, and 0 exceptions\x3c\/div\x3e\x3cdiv class=\"item-list\"\x3e\x3cul\x3e\x3cli class=\"first last\"\x3e\x3cdiv class=\"simpletest-pass\"\x3eTrigger cron (system) actions: 30 passes, 0 fails, and 0 exceptions\x3c\/div\x3e\x3c\/li\x3e\n\x3c\/ul\x3e\x3c\/div\x3e"}Fatal error: Exception thrown without a stack frame in Unknown on line 0
Both tests call drupal_cron_run at least once; this instigates the Exception thrown later on in the DBTNG environment, see below for how I arrived at this.
For both of these, the function calling hierarchy is: drupal_cron_run -> module_invoke_all('cron') -> call_user_func_array -> search_cron -> register_shutdown_function('search_update_totals');
search_update_totals -> db_query("... {search_total} ...");
Cron is calling the module's _cron functions, but is falling over on the Search module as that module hasn't been enabled.
I'm looking in function module_implements(); plugging the SQL into mysql via the CLI:
SELECT * FROM registry WHERE type = 'function' AND suffix = "cron";
+-------------+----------+------------------------------+--------+--------+--------+| name | type | filename | module | suffix | weight |
+-------------+----------+------------------------------+--------+--------+--------+
| dblog_cron | function | modules/dblog/dblog.module | dblog | cron | 0 |
| filter_cron | function | modules/filter/filter.module | filter | cron | 0 |
| node_cron | function | modules/node/node.module | node | cron | 0 |
| system_cron | function | modules/system/system.module | system | cron | 0 |
| update_cron | function | modules/update/update.module | update | cron | 0 |
+-------------+----------+------------------------------+--------+--------+--------+
5 rows in set (0.00 sec)
If I put:
if ($hook=='cron') { var_dump($implementations[$hook]); }in modules.inc at line 387, it prints:
array(5) {
[0]=>
string(5) "dblog"
[1]=>
string(6) "filter"
[2]=>
string(4) "node"
[3]=>
string(6) "search"
[4]=>
string(6) "system"
}
I don't understand why 'search' is returned and 'update' isn't.
At least
db_query ("SELECT * FROM {does_not_exist}");throws an exception with helpful text and file names with line numbers.
Can anyone replicate what I've produced above and help clear the fog my brain as to why it's happening?
#7
I can replicate it, though I can't shed any further light.
Bizarrely, the same query, when run directly before module_implements() is called, returns:
array(5) {[0]=>
string(5) "dblog"
[1]=>
string(6) "filter"
[2]=>
string(4) "node"
[3]=>
string(6) "system"
[4]=>
string(6) "update"
}
but within module_implements() it returns the result philipnet mentioned above. I don't believe caching is a factor as I've got module_implements() purging its cache to automatically. It's as if the registry table is changed 'magically' each time the function module_implements() is invoked with the 'cron' hook.
#8
I've done some more fossicking. In modules/simpletest/drupal_web_test_case.php DrupalWebTestCase::setUp() installs modules from the default profile, including search. I had Drupal installed using the expert ('Drupal (minimal)') profile and I found when reinstalling with the default profile I no longer got the error.
I understand that testing against the default profile makes sense (you have to test against some sort of defined environment) but this testing doesn't seem to be working when the underlying platform has been installed with a different profile.
My colleague Josh Waihi suggests there might be DrupalWebTestCase::preloadRegistry() might be part of the problem.
#9
To extend what @stuzza is saying, this problem only occurs when testing in Expert mode, because, as it would seem, simpletests assumes the parent database is in a state that reflects the default install profile and tries to cut performance corners by copying the registry from from the parent database (I think with ->preloadRegisty). If this is the case, then when need to either make the default profile modules dependencies of the simpletest module or not steal the registry state from the parent database, which seems like a better idea to me.
Thinking about it a bit more, why not create a drupal install with a prefix like 'st_model' and steal the registry from that rather than the parent - It could also be useful for stealing other bits and pieces.
#10
In that case, this need re-assigning.
#11
This has nothing to do with the registry or simpletest. It's just that the search module is registering a shutdown function when run into the child site, but this function fails because at the time when it is executed, the child site has already been destroyed.
Let's just add a try / catch in search_update_totals().
#12
Is this error showing on servers with php5-suhosin installed? Seems like that was the cause for me. Haven't been able to reproduce this on MySQL 5.0 MyISAM and InnoDB or MySQL 5.1 MyISAM, so I'm removing the blocker tag.
#13
It showed up on my test server which /didn't have/ suhosin installed.
But I doubt it's a PIFR 2 blocker as it only manifests if the user invokes the tests from an existing Drupal 7 installation where the Search module is not enabled (AIUI).
#14
#602958: Running cron does not end well