It takes about 20 minutes to run tests on testing.drupal.org.

I thought of an idea for SimpleTest itself that might help make it run faster: Install Drupal the first time and make copy of default database and files setup. Restore from it rather than re-install.

Thoughts?

CommentFileSizeAuthor
#116 drupal.simpletest-profile.116.patch2.34 KBsun
#112 323477-simpletest-performance.patch5.36 KBDamien Tournoud
#108 simpletest.speedup.patch69.04 KBAnonymous (not verified)
#106 simpletest.speedup.patch68.1 KBAnonymous (not verified)
#102 simpletest.speedup.patch72.61 KBAnonymous (not verified)
#94 simpletest.speedup_7.patch72.61 KBtstoeckler
#93 simpletest.speedup_6.patch71.17 KBtstoeckler
#92 simpletest.speedup_6.patch71.17 KBtstoeckler
#87 simpletest.speedup.patch72.6 KBAnonymous (not verified)
#85 simpletest.speedup.patch72.59 KBAnonymous (not verified)
#77 simpletest.speedup_3.patch70.39 KBAnonymous (not verified)
#75 simpletest.speedup_3.patch68.95 KBtstoeckler
#71 simpletest.speedup.patch70.39 KBAnonymous (not verified)
#67 simpletest.profile.patch68.7 KBAnonymous (not verified)
#65 simpletest.profile.patch70.36 KBAnonymous (not verified)
#62 simpletest.profile.patch64.59 KBAnonymous (not verified)
#55 testing.profile.patch2.99 KBAnonymous (not verified)
#51 simpletest.speedup.patch6.69 KBAnonymous (not verified)
#47 simpletest.speedup.patch6.21 KBAnonymous (not verified)
#44 323477-single-environment.patch6.47 KBDamien Tournoud
#32 simpletest_tune.patch.txt26.17 KBboombatower
#31 simpletest_tune.patch.txt18.13 KBboombatower
#30 simpletest_tune.patch.txt10.91 KBboombatower
#27 simpletest_tune.patch20.75 KBboombatower
#22 simpletest_tune.patch6.22 KBboombatower
#17 simpletest_tune.patch5.61 KBboombatower
#4 323477-simpletest-speedup.patch5.35 KBDamien Tournoud
#3 simpletest-benchmark.patch.txt3.78 KBboombatower
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

boombatower’s picture

Working on getting some numbers.

boombatower’s picture

After running first 10 test cases I get about 52% of the time spent installing Drupal. (54 seconds of 103 total)

boombatower’s picture

This is the very basic code I used to benchmark he testing suite. Using .txt extension as there is no need for t.d.o to test this patch.

You will need to create a table called 'benchmark' with fields: type (int), elapse (float).

The results will be displayed after tests finish.

Damien Tournoud’s picture

Status: Active » Needs review
FileSize
5.35 KB

I already investigated this a while back (patch attached). We already can get a significant performance improvement by doing intra-test-class caching (ie. we don't reinstall Drupal between test methods, simply copy back the clean environment).

Caching test environments *between* test-classes (ie. caching a clean installation of a given set of modules) would require locking somehow (because tests can be run concurrently), and I'm not sure how to do this now.

*But:* copying DB tables in a clean, portable manner is not easy. For MySQL, we need to add NO_AUTO_VALUE_ON_ZERO... but this seems to break some part of Drupal (especially where we do INSERT INTO table VALUES (DEFAULT)).

As a conclusion: Crell talked about implementing a clean interface for copying tables in our database layer. We should bother him :)

dlhubler’s picture

would using mysql transactions help?
begin transaction
run test
rollback transaction
its a strategy i used in a previous life w/postgres

boombatower’s picture

Possibly and then reseting the files directory, but that is easy and should remain the way it is.

Do we have proper access to transactions in Drupal 7 core?

Anonymous’s picture

Transactions can be installed anytime by converting tables to InnoDB. As for InnoDB in core see #301362: Default to InnoDB in MySQL. But shouldn't tests.drupal.org test installing Drupal core from scratch at least once a week?

catch’s picture

Status: Needs review » Needs work

#4 gives me: Notice: Undefined index: test_id in _simpletest_batch_finished() (line 403 of /home/catch/www/7/modules/simpletest/simpletest.module).

boombatower’s picture

#7: much more often than once a week. It will test it on every patch as they are posted and the whole set of active ones once daily or every other day...

That is why tuning is important.

Anonymous’s picture

And to really test the install process it needs to be done on all the supported DB; currently MySql and PostgreSQL. But MySQL has different engines and I would suggest testing on MyISAM and InnoDB as well.

Damien Tournoud’s picture

@catch#8: that's one of the issue with that patch, linked to the NO_AUTO_VALUE_ON_ZERO setting.

When assigning a new test_id, simpletest.module does:

  $test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute();

This translates to:

INSERT INTO simpletest_test_id VALUES(DEFAULT)

And that fails when NO_AUTO_VALUE_ON_ZERO is set (DEFAULT translates to 0 so test_id = 0 on the first run, and a duplicate error is generated on the second run).

I still need to study how to solve this issue in a cross-engine manner (inserting NULL would work on MySQL, but probably fail on PostgreSQL).

Anonymous’s picture

Another thought, in order to support #10 comments more than one DB server on different ports with different configurations could help in supporting the multiple MySQL engine testing.

Anonymous’s picture

If the DB has an auto index, the value shouldn't be specified at all to use the feature. Specifying the value for the index of course will use the value given regardless of the DB engine. I can't find a similar setting as NO_AUTO_VALUE_ON_ZERO for PostgreSQL.

Damien Tournoud’s picture

Specifying the value for the index of course will use the value given regardless of the DB engine.

Not at all :)

On MySQL, you are supposed to insert NULL (or omit) a column to have the autoincrement value:

NO_AUTO_VALUE_ON_ZERO affects handling of AUTO_INCREMENT columns. Normally, you generate the next sequence number for the column by inserting either NULL or 0 into it. NO_AUTO_VALUE_ON_ZERO suppresses this behavior for 0 so that only NULL generates the next sequence number.

But on PostgreSQL, serials are implemented by (1) sequences and (2) variable default values:

CREATE TABLE tablename (
colname SERIAL
);

is equivalent to specifying:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

So you are supposed to insert DEFAULT (or omit) to get the automatic value.

boombatower’s picture

Adding support for testing in separate environment is a totally different issue that I am looking into conquering later.

Anonymous’s picture

subscribe. very cool stuff.

boombatower’s picture

Assigned: Unassigned » boombatower
Status: Needs work » Needs review
FileSize
5.61 KB

Here is patch that caches install for entire test session. (base install without any non-default modules)

Then copies db over and installs test specific modules.

Note: I have not run entire suite, but initial results show 30+% speed increase.

This also needs cleanup as I do old style INSERT/UPDATE statements....

boombatower’s picture

There is an error when running aggregator tests...bed time.

boombatower’s picture

It needs to uninstall schema for custom (additional test specific modules) and leave all the default base tables.

webchick’s picture

I wish there was a way to quadruple-subscribe to an issue.

I want this in core so bad it hurts. ;) Will try and take a look tomorrow when I am more conscious.

cburschka’s picture

Subscribe. It takes more than half an hour to run through all tests on my server, unless the server gets a hiccup halfway in and stops the testing.

boombatower’s picture

Status: Needs review » Needs work
FileSize
6.22 KB

Fixed the main concern I had...aggregator tests now run, but get a page title fail on one of them...

babbage’s picture

Interesting. (Subscribe.)

boombatower’s picture

Coming back to this issue after a bit, I decided to write down the flow of the code so I could more easily visualize it.

First time:
setUp()
 * Create base database using default profile.
 * Create empty test database (schema only) using default profile.

Normal:
setUp()
 * Copy base database in test database.
 * Install additional modules.

tearDown()
 * Remove additional module tables.
 * Empty all default profile tables.

Last time:
tearDown()
 * Destroy base database.
 * Destory test database.

I noticed an issue....hook_schema_alter()...so i can either see if additional modules have that implemented and only drop the test database then...or always drop the test database to ensure fresh schema.

The main benefit of not dropping will be much larger performance gain and considering hook_schema_alter() is one of the less used hooks...might be worth tyring.

boombatower’s picture

sudo-code. Could move the create of base database to simpletest.module start of batch...but I'm think it will require code duplication...will look into.

/* drupal_web_test_case.php */

  protected function setUp() {
    if (!variable_get('simpletest_install_base', FALSE)) {
      // Create base database.
    }
    
    if (!variable_get('simpletest_install_test', FALSE)) {
      // Create test database.
    }
    
    // Install additional modules and detect hook_schema_alter() implementations.
    
    // Copy base tables to test tables.
    
    // Flush environment.
  }

  protected function tearDown() {
    // Uninstall additional modules.
    
    if ($this->destroyTestDatabase) {
      // Remove test database tables due to hook_schema_alter() implementation.
    }
    else {
      // Empty test database.
    }

    // Flush environment.
  }

/* simpletest.module */

  function _simpletest_batch_finished() {
    // Destroy test database.

    // Destroy base database.
  }
boombatower’s picture

In order to allow this to work will multi-process execution as provided by run-tests.sh I will need some sort of data structure to keep track of what test database are open for each base...

variable_get('simpletest_environment_prefixes');

DrupalWebTestCase
 * construct() - requests test database prefix
 * deconstruct() - releases test database prefix
boombatower’s picture

FileSize
20.75 KB

This is not functional...but represents where I got tonight.

The getInfo() function per test case should be static...and is part of what is breaking this.

Feel free to take a look...I haven't even gotten it all to run due to the getInfo() issue.

Otherwise all the code is complete...who knows what it will do.

boombatower’s picture

Status: Needs work » Postponed
boombatower’s picture

Status: Postponed » Active

After lots and lots of discussion #376129: Change getInfo() to a static method finally was decided on and made it in!

I'm am working on this.

boombatower’s picture

FileSize
10.91 KB

I have made great progress! I spend a fair amount of time drawing out what I was trying to do and came up with a much better approach with an added benefit. The code currently runs in index.php so I can easily debug it, but I have it to the point where it will consistently re-unse environments and such.

You can see here that it reuses an environment between two test methods.

Removed 0 of 2 tables...
init()...
new BlockTestCase()...
testBox()...
Array
(
)
Array
(
    [simpletest_base] => Array
        (
            [0] => simpletest625643
        )

)
testBlock()...
Array
(
    [simpletest_base] => Array
        (
        )

)
Array
(
    [simpletest_base] => Array
        (
            [0] => simpletest625643
        )

)
deinit()...
exit()...

I have attached a patch of the essentials to what I am working on. NOTE: some parts need a fair amount of cleanup. (this patch isn't ready for testing)

boombatower’s picture

FileSize
18.13 KB

Actually runs a test! Not how I want it to end up, but it works! (I might split off the second part into separate patch if it ends up being splittable)

Bed time now.

boombatower’s picture

Status: Active » Postponed
FileSize
26.17 KB

Needs #391340: Job queue API to work as I have planned and re-use prefixed test databases.

jhedstrom’s picture

Subscribing

Damien Tournoud’s picture

@boombatower: be careful, that's already a big patch, and it risks facing the same death as the previous attempt at refactoring Simpletest.

I suggest working on "baby"-steps:

  1. first, we should refactor database prefixes to make them per-connection. The patch for this is nearly ready in #195416: Table prefixes should be per database connection, but desperately crying for attention. This way, you could have a "child" connection separated from the "parent" connection.
  2. second, we should implement a DatabaseConnection::duplicate() method (or a similar name), that would copy all schema and data of an existing database. This needs to be done per database engine, because some engines might have nice shortcuts (for example on SQLite we could just copy the database file, etc.).
  3. third, we need to add .test files to the registry, in order to be able to easily get the filename in which a test class is defined.
  4. fourth, we need to implement a "test runner" that run an individual test. It would be perfect if this runner could avoid bootstrapping Drupal to BOOTSTRAP_FULL, in order to ensure that the environment is really clean for the ground up. For that we need at least 3 and probably 1.

There is really no need for a gigantic patch to do that ;)

boombatower’s picture

#2: created: #449186: Implement DatabaseConnection::duplicate()

#4: This patch does that, it loads the test class itself in an environment which bootstraps in the prefixed database instead of trying to change to it and clearing statics.

boombatower’s picture

Been meaning to work on #3 for a long time #449198: SimpleTest: Clean up test loading and related API.

Your right about splitting it up, much better approach...thx for bringing that up.

Note: the large patch you refer to that died...was very interdependent and required more work to split up then to just get on with life and commit...especially considering how much time I had spent on it...but oh well I let it die.

andypost’s picture

Step #0 - write instructions about writing a tests! Mostly concerned about optimizations to stop anarchy in test writing.

- Less test* methods
- Less drupalGet()
- commit #500866: [META] remove t() from assert message I think - t() eats a lot

rfay’s picture

I agree with andypost: We have to either massively optimize the creation of new test environments or we have to discourage people from creating a new test*() method for every test thought they have.

boombatower’s picture

If we do anything in 7.x cycle lets focus on optimizing tests themselves, I'm planning a rewrite for Drupal 8 that should drastically improve environment creation speed.

rfay’s picture

So let's agree on where the low-hanging fruit is. The first thing we can do is to set the standard and document it.

As far as I can tell in D7, the creation of a new db for every test* method trumps every other performance issue by thousands of times. So that argues for grouping functionality into less test methods.

However, that conflicts with the general functionality idea that you should keep test methods specific in their aim so that it's easy to understand what each one is about.

I'd hate to lose the forest for the trees. Changing from a better software approach to a faster one seems like giving up ground.

But we have to remember that our test suite is taking longer and longer to execute. Even DamZ's qa-1 now takes quite a lot longer than it used to. So our path is not sustainable (I don't think) and we really have to fix performance before it because a true thorn in our side.

We're still in the range of successful testing times, although they've grown quite a lot

boombatower’s picture

We add an API for this in 8.x and what not, but simple fix right now.

All the tests that can be grouped (or change them so they can) can be grouped using the following pattern.

testGroupSummary()
- checkX()
- checkY()
- checkZ()

etc.

rfay’s picture

That would be a BIG plus. The tests remain separate, but can be marked as not having dependency issues.

rfay’s picture

Title: Tune SimpleTest » Increase simpletest speed by limiting the number of DB reinstalls
Damien Tournoud’s picture

Category: feature » task
Status: Postponed » Needs review
FileSize
6.47 KB

Why not doing something like this?

Some tests will probably fail, because they are not designed to work in an unclean environment, but this should help a ton for the database tests.

Status: Needs review » Needs work

The last submitted patch, 323477-single-environment.patch, failed testing.

rfay’s picture

This looks pretty reasonable to me. I think we should give it a try.

+++ modules/simpletest/drupal_web_test_case.php
@@ -63,6 +63,15 @@ abstract class DrupalTestCase {
+  protected $singleEnvironmentMode = FALSE;

I think we could use a better name than $singleEnvironmentMode to drive it, as the word "environment" is so terribly overloaded already. How about $sharedInstallMode, or something like that

Powered by Dreditor.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
6.21 KB

here's another approach, probably not as fast as damien's, but one that keeps the environment for each test clean.

on my setup, i see the time to build the base environment drop from ~13s to ~8.5s, so it seems worth pursuing further.

i can take the patch to another issue if that's what people think is the way to go.

setting to "Needs Review" to see what the bot thinks of it. there are lots of hacks to clean up with this patch yet, but i'd like to get some feedback (bot and otherwise) now.

Anonymous’s picture

in #drupal, rfay just pointed out we can combine both DamZ's patch from #44 and mine from #47.

i'm not opposed to this idea, but i'd like to see how much faster we can go while sticking to "all tests run in a clean environment".

Status: Needs review » Needs work

The last submitted patch, simpletest.speedup.patch, failed testing.

Anonymous’s picture

ok, guess i can't wait to later to put locks around the building of the cache tables. will get to that next.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
6.69 KB

with some locking this time, still a hacky proof of concept, but hopefully this will pass all tests.

Status: Needs review » Needs work

The last submitted patch, simpletest.speedup.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review

i asked this of chx in #drupal, but i'll throw it in here as well - any reason we do the install profile module_enable after installing any module-specific tests?

if we can move this line from DWTC::setUp():

    // Run default profile tasks.
    module_enable(array('standard'), FALSE);

inside the cached part of the setup, we gain another couple of seconds per test.

Anonymous’s picture

post of conversation from #drupal between rfay and i:

beejeebus: rfay: i have another (possibly stupid) idea for speeding up testing
rfay: beejeebus, you haven't been stupid so far :-)(
beejeebus: rfay: :-) apart from caching the tables, i was wondering why we don't just make the install smaller when we can
beejeebus: many, many tests only require the minimal profile, yet we load the standard profile
rfay: beejeebus, that's not a bad idea. there's currently no control over that at all, but it would speed things up quite a lot.
beejeebus: rfay: this is much, much slower to install
beejeebus: rfay: right
rfay: beejeebus, actually, I wonder if we couldn't just switch to minimal and see how many tests break, then fix those.
beejeebus: just playing around with block tests, which nominally don't need standard, and there's plenty of breakage
beejeebus: but fixing for one set will probably fix for most
beejeebus: but yeah, default should probably be minimal, with more modules explicitly enabled by the test writer

looking into what this would take next...

Anonymous’s picture

FileSize
2.99 KB

attached is a patch that creates a minimal test profile, and makes it the default for all DrupalWebTestCase based tests.

the test results should illustrate just how bloated and dependency-ridden a lot of our current tests are.

i started looking at some of the fails in ActionLoopTestCase and ouch, bloat, bloat, bloat. (i'm only singling it out because it was at the top of the list...)

this test fails because it relies on hook watchdog and some custom GET requests to the front page. with the slimmed down profile, the GET requests fire access denied watchdog messages, and it all goes pear-shaped from there.

the simple way to fix this is just to turn on a bunch more modules on the tested-side until it works.

the *right* way to fix this is to make the module written for the test provide all that is needed to create an action-trigger combination that calls itself recursively.

i suspect that if "make your tests rely on as little of the rest of drupal as possible" was applied across the board, we'd be refactoring half of them. personally, i think its worth it, but if i'm the only one, then there's not much point pushing on it.

so, feedback please.

andypost’s picture

I think it's better to make a parameter that point which install profile should be used in test method

Status: Needs review » Needs work

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

chx’s picture

The reason we used standard profile because we wanted 'realistic' tests. A bit hard to explain at 2am :) anyways i am all for speeding up tests, i am totally against any major test refactoring in D7, i am all for major test refactoring in D8.

catch’s picture

@chx: I thought it was because simpletest went in before the minimal profile, and because we didn't have a way to specify which profile to use for tests, but 'free' code coverage may have been another reason.

"the simple way to fix this is just to turn on a bunch more modules on the tested-side until it work"
I think it'd be a good first run for a patch to default to the minimal profile then explicitly list dependencies (or specify the standard profile). Then followup patches can try to reduce the dependencies, doing it all in one mega-patch seems like it'll end up going into D8 whatever happens.

jhedstrom’s picture

The work for switching which profile to test is being pursued here: #279515: setting an installation profile for a test doesn't run hook_install_tasks().

Anonymous’s picture

jhedstrom: commented in #279515: setting an installation profile for a test doesn't run hook_install_tasks() . for this issue, we'd need per-test profile setting, not per-test class.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
64.59 KB

ok, lets see what the bot thinks of this.

Anonymous’s picture

while i'm waiting for the bot - running five tests that use the new slimmer framework and pass, ACTIONS CONFIGURATION, AJAX COMMANDS, AJAX COMMAND FORM VALUES, AJAX FRAMEWORK and BASIC SQL SYNTAX TESTS:

with the patch took 1 min 53 sec.

for HEAD, that was 4 min 3 sec.

Status: Needs review » Needs work

The last submitted patch, simpletest.profile.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
70.36 KB

alrighty, try this.

think there are a couple of fails still, but very close now. lets see what the bot says.

Status: Needs review » Needs work

The last submitted patch, simpletest.profile.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
68.7 KB

ok, this might actually pass.

Damien Tournoud’s picture

Title: Increase simpletest speed by limiting the number of DB reinstalls » Increase simpletest speed by running on a simplified profile

We need to be able to hide the new Testing profile, because we definitely don't want to put that in the face of newcomers on the first installation screen. I suggest we just add hidden = TRUE in the .info and make sure this is taken into account.

Other then that, this is a pretty harmless patch that increase the testing speed by as much as 30%!

982,879	 File	simpletest.profile_1.patch	 Result received from test client #253.	 07/11/2010 - 13:13:55
982,874	 File	simpletest.profile_1.patch	 Requested by test client #253.	 07/11/2010 - 12:51:00
982,824	 File	bartik-cleanup-general.patch	 Result received from test client #253.	 07/11/2010 - 12:13:15
982,764	 File	bartik-cleanup-general.patch	 Requested by test client #253.	 07/11/2010 - 11:41:00

(32 minutes vs. 23 minutes!)

Big +1 here.

Anonymous’s picture

Status: Needs review » Needs work

the profile doesn't show up on install (good) because i didn't create a .profile file (bad).

i can't see any support in the installer for hidden profiles, so that will need to be added. setting back to CNW for that.

glad to see Damien can replicate the speed-ups i see. just want to point out that there's still heeeeaaaaps of fat here. to avoid killing kittens, i just punted on pretty much everything that looked at all hard.

after this patch lands, we can pick webtestcase tests that have $profile = 'standard', take that out, then see what breaks. i suspect there are lot of tests that can easily be ported to the slim profile by adding a setUp() method with just parent::setUp('dependent_module', ...).

rfay’s picture

Yippee! I haven't tried it, but I can see this definitely being a +1.

Anonymous’s picture

FileSize
70.39 KB

ok, added a profile file, and made the installer respect hidden = TRUE in profile install files.

Anonymous’s picture

Status: Needs work » Needs review
Anonymous’s picture

CNR

tstoeckler’s picture

+++ modules/aggregator/aggregator.test	11 Jul 2010 14:41:06 -0000
@@ -292,6 +294,8 @@ class AddFeedTestCase extends Aggregator
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/aggregator/aggregator.test	11 Jul 2010 14:41:06 -0000
@@ -362,6 +368,8 @@ class RemoveFeedTestCase extends Aggrega
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/aggregator/aggregator.test	11 Jul 2010 14:41:06 -0000
@@ -642,6 +656,8 @@ class ImportOPMLTestCase extends Aggrega
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/locale/locale.test	11 Jul 2010 14:41:20 -0000
@@ -1215,6 +1220,8 @@ class LocaleLanguageSwitchingFunctionalT
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/poll/poll.test	11 Jul 2010 14:41:23 -0000
@@ -640,4 +642,4 @@ class PollExpirationTestCase extends Pol
\ No newline at end of file

Please add one.

+++ modules/simpletest/drupal_web_test_case.php	11 Jul 2010 14:41:27 -0000
@@ -1125,6 +1125,11 @@ class DrupalWebTestCase extends DrupalTe
+ ¶

Trailing whitespace

+++ modules/simpletest/tests/bootstrap.test	11 Jul 2010 14:41:28 -0000
@@ -224,6 +225,7 @@ class BootstrapPageCacheTestCase extends
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/simpletest/tests/path.test	11 Jul 2010 14:41:32 -0000
@@ -131,6 +131,8 @@ class DrupalMatchPathTestCase extends Dr
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/system/system.test	11 Jul 2010 14:41:34 -0000
@@ -1636,6 +1656,7 @@ array_space[a b] = Value';
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/trigger/trigger.test	11 Jul 2010 14:41:36 -0000
@@ -539,6 +550,7 @@ class TriggerUserActionTestCase extends 
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/trigger/trigger.test	11 Jul 2010 14:41:36 -0000
@@ -682,6 +694,7 @@ class TriggerOtherTestCase extends Trigg
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/update/update.test	11 Jul 2010 14:41:36 -0000
@@ -52,6 +52,7 @@ class UpdateTestHelper extends DrupalWeb
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -714,6 +716,7 @@ class UserCancelTestCase extends DrupalW
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -1029,6 +1032,8 @@ class UserPermissionsTestCase extends Dr
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -1085,6 +1090,8 @@ class UserAdminTestCase extends DrupalWe
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -1145,6 +1152,8 @@ class UserTimeZoneFunctionalTest extends
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -1185,6 +1194,8 @@ class UserAutocompleteTestCase extends D
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -1438,6 +1449,8 @@ class UserEditTestCase extends DrupalWeb
+  protected $profile = 'standard'; ¶

Trailing whitespace.

+++ modules/user/user.test	11 Jul 2010 14:41:37 -0000
@@ -1686,6 +1699,8 @@ class UserTokenReplaceTestCase extends D
+  protected $profile = 'standard'; ¶

Trailing whitespace.

Sorry for printing each one out individually, just makes it easier to reroll. Will post a new patch in a minute.

Powered by Dreditor.

tstoeckler’s picture

FileSize
68.95 KB

Here we go.

Status: Needs review » Needs work

The last submitted patch, simpletest.speedup_3.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
70.39 KB

tstoeckler, thanks, but you forgot the new files.

boombatower’s picture

Status: Needs review » Reviewed & tested by the community

Overall, looks good.

In general I think it would be best if we continue to convert most of the tests to the slim profile + dependencies for performance and consistency reasons, leaving only the tests that are attempting to check things setup based on the standard profile.

Good to see some performance work get done on the tests!

moshe weitzman’s picture

+1 from me too. If anyone is motivated, I think it makes sense to keep converting tests to slim while this sits in rtbc.

webchick’s picture

The performance benefits of this patch are very compelling, and I especially love this hunk:

+    // Allow tests to use a profile other than the testing one.
+    if (!isset($this->profile)) {
+      $this->profile = 'testing';
+    }

The changes are not nearly as invasive as I would've thought, too, which is nice. And I like this approach much better than previous recommendations, like shoving all of the tests for a module into a single testX() function.

However, as a release manager, I'm obviously incredibly nervous about this:

In general I think it would be best if we continue to convert most of the tests to the slim profile + dependencies for performance and consistency reasons

...when there are 50-something critical issues and growing every day, lately. We passed "polish" phase months and months ago, and distracting a bunch of the Really Smart People on the task of test polishing at this point, which is likely to grow the queue by another 50+ clean-up issues that will all need committer attention makes me go "margh". :\

However, since the testing bot now forms the backbone of our core development process, and since this performance increase will have massive implications going forward in the future, I think the benefits of this patch, despite its unfortunate timing, outweigh the possible detriments, so I'm willing to commit it.

I will leave this RTBC for 24 hours or so to give Dries a chance to chime in, though.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

Well, upon further review... a couple of things:

+++ modules/file/tests/file.test	11 Jul 2010 15:10:27 -0000
@@ -16,6 +16,7 @@ class FileFieldTestCase extends DrupalWe
+    $this->createDefaultContentTypes();

+++ modules/simpletest/drupal_web_test_case.php	11 Jul 2010 15:10:35 -0000
@@ -3065,6 +3075,37 @@ class DrupalWebTestCase extends DrupalTe
+  protected function createDefaultContentTypes() {

Let's put this function in one place and call it from both the tests and from standard.install. I can see these getting annoyingly out of sync going forward which is going to be terribly confusing for test debuggers.

+++ modules/trigger/trigger.test	11 Jul 2010 15:10:42 -0000
@@ -252,7 +253,15 @@ class TriggerCronTestCase extends Trigge
   function setUp() {
-    parent::setUp('trigger');
+    $args = func_get_args();
+    if (isset($args[0]) && is_array($args[0])) {
+      $modules = $args[0];
+      array_unshift($modules, 'trigger');
+      parent::setUp($modules);
+    }
+    else {
+      parent::setUp('trigger');
+    }
   }

Dear lord. What is all this belly-dancing? Please document it.

Powered by Dreditor.

Anonymous’s picture

Status: Needs work » Reviewed & tested by the community

webchick, thanks for the review, and i'm glad you're ok with the patch.

we can work on speeding up the remaining tests *after* the release.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

Presume this was a cross-post. And yes, good point. ;) Maybe. ;)

moshe weitzman’s picture

Speeding up tests increases our velocity when fixing criticals. Lets try not to see this as distracting core devs.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
72.59 KB

ok, reroll to address #81.

in the interests of kittens everywhere, i've taken out the TriggerActionTestCase belly-dancing and just set that test to use the standard profile. no point spending time on that right now, it'll still be there later.

i've pulled the content type creation out into a separate function in standard.install, and made the method in DrupalWebTestCase wrap that.

Status: Needs review » Needs work

The last submitted patch, simpletest.speedup.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
72.6 KB

fix typo in node edit test case.

Anonymous’s picture

just a note that once this lands, we can write tests that catch this sort of issue: #852394: minimal profile + seven leads to broken 'node/add' link.

Status: Needs review » Needs work

The last submitted patch, simpletest.speedup.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review

#87: simpletest.speedup.patch queued for re-testing.

Anonymous’s picture

i can't reproduce that fail locally, so i'm calling the bot a liar.

tstoeckler’s picture

FileSize
71.17 KB

The patch implemented the correct logic in install_select_profile_form(), but you forgot to put 'hidden = TRUE' in testing.info :)

This time I didn't forget the new files.

tstoeckler’s picture

FileSize
71.17 KB

Actually I did... (how embarassing...)

While I'm at it, removing the whitespace that crept in there again.

tstoeckler’s picture

FileSize
72.61 KB

Darn it!!! How DO you add new directories with a patch???

For now I just copied the stuff from your earlier patch into the bottom of my patch file...

moshe weitzman’s picture

You can add new files using fakeadd: http://wimleers.com/blog/cvs-diff-new-files-fakeadd. Otherwise, use bzr or git to generate the diff. There are well known core repositories for each.

chx’s picture

Where did we lose the notion of using 'minimal' and came up with a new profile? What's the point?

Anonymous’s picture

chx, speed, minimalism and separation.

i'd rather not have changes to the minimal profile effect testing.

having said that, we get 90% of the speed up using minimal profile, so i'm ok with doing that if that's what needed to get this in. its kinda dragging on now.

chx’s picture

90%...? Is minimal not minimal enough?? As far as I am aware the only thing it does is adding a few blocks, easy to be get rid of if you dont want. One insert query surely is not 10%?

Anonymous’s picture

justin@justinlappy:/var/www/drupal/core/7/clean$ grep required modules/*/*.info
modules/field/field.info:required = TRUE
modules/filter/filter.info:required = TRUE
modules/node/node.info:required = TRUE
modules/system/system.info:required = TRUE
modules/user/user.info:required = TRUE
justin@justinlappy:/var/www/drupal/core/7/clean$ grep dependencies profiles/minimal/minimal.info 
dependencies[] = block
dependencies[] = dblog

installing modules (registry rebuilds, cache clearing, etc) is one of the most expensive parts of the install process, and we go from 5 to 7 if we use minimal rather than the test profile. is that going to be 10%? don't know, haven't measured it, but i think its fair to say that the testing profile will be measurably quicker.

Damien Tournoud’s picture

I'm for using the testing profile, on the grounds of separation.

chx’s picture

Then we need a hidden profile feature?

Anonymous’s picture

FileSize
72.61 KB

blurgh, yes, we do, and this patch adds support for that. the patch at #94 was missing the "hidden = TRUE" line from testing.info.

chx’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

Anonymous’s picture

Issue tags: +Needs committer feedback

Tagging.

sun’s picture

Status: Reviewed & tested by the community » Needs work

This is badly needed, but only almost RTBC.

+++ modules/simpletest/drupal_web_test_case.php	16 Jul 2010 04:26:20 -0000
@@ -3065,6 +3075,17 @@ class DrupalWebTestCase extends DrupalTe
+   * Create default content types.
+   * ¶

(and elsewhere) Trailing white-space.

Please, if your IDE does not support auto-elimination of trailing white-space, and it also does not support to display/highlight EOL/CRLF markers, then please grep your patches for /\s$/ before submitting them. Not doing so wastes a lot of developer time.

+++ modules/simpletest/drupal_web_test_case.php	16 Jul 2010 04:26:20 -0000
@@ -3065,6 +3075,17 @@ class DrupalWebTestCase extends DrupalTe
+  protected function drupalCreateDefaultContentTypes() {
+    module_load_install('standard');
+    standard_create_default_content_types();

1) Replace 'standard' with $this->profile

2) Replace that other thing with

  $function = $this->profile . '_create_default_content_types';
  if (function_exists($function)) {
    $function();
  }

3) More on the actual function/hook name below.

+++ profiles/standard/standard.install	16 Jul 2010 04:26:28 -0000
@@ -427,3 +399,39 @@ function standard_install() {
+ * Create some default content types.
+ * ¶
+ * For a complete list of available node type attributes, refer to the node ¶
+ * type API documentation at: ¶
+ * http://api.drupal.org/api/HEAD/function/hook_node_info.
+ */
+function standard_create_default_content_types() {
...
+  foreach ($types as $type) {
+    $type = node_type_set_defaults($type);

1) "content type" is a Node module concept. First subject for this install profile hook therefore is "node".

2) Follow [subject]_[verb] pattern like modern code elsewhere in core; i.e. "content_types" before "create".

3) Singular, not plural, talking entity. Also, we already have a node type API containing a couple of node_type_* functions.

4) Not sure whether the foreach() shouldn't be part of the function that invokes this install profile hook.

5) Squeezing "install" into the hook name might make sense.

Effectively: hook_node_type_install() ?

Powered by Dreditor.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
68.1 KB

sun, thanks for the review, which has convinced me simplify this patch to avoid killing kittens. this patch just does:

- allow for a test to set the profile
- default to the slim profile with enabled dependencies where that is all that is needed to work with the slim profile
- all other tests use the fat profile

trying to do more than that has already slowed down getting this in, and i just don't want to see it fail because of that. so, i've ripped out the content type creation stuff and just set a couple of extra tests to use the fat profile.

next step after this lands is to find the remaining tests that will work with the slim profile plus some enabled dependencies, as that's the next lowest hanging, simplest to implement bit.

after that, we can look at any tests that actually require thought to port to the slimmer profile.

Status: Needs review » Needs work

The last submitted patch, simpletest.speedup.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
69.04 KB

when in doubt, throw code lard at the problem.

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community

The actual code changes in the patch are minimal and, now that the content type stuff is out have been reviewed numerous times.

Just a note that this patch adds two module dependencies for tests:
1. 'block' for one of the block tests
2. 'block', 'dashboard', 'comment' for the dashboard test.
I don't know whether this is intentional or not, but
1. since they are mostly obvious (I just don't get 'comment'...) and
2. the tests pass and
3. we want to revisit that in detail in a follow-up anyway
I think the patch is good to go still. Given that it increases test runs dramatically IMO it's not worth holding this up any longer on something that will be discussed (and changed, if needed) in a follow-up anyway.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

We (Dries, Damien, and I) talked about this at the Drupalcon CPH Core Developer Summit (tm). Both Dries and I are on board with committing this patch. One caveat: given where we are in the release cycle (and even where we were in the release cycle when this initiative picked up), it makes more sense for the testing profile to default to 'standard' in Drupal 7. Otherwise, every single person who's written a test for their contrib/custom modules in D7 (which is becoming more and more as time goes on) has to add this line to their tests, and as we can see from the 70K patch core needed, this is quite a lot of work. :P In Drupal 8, though, we should invert this and make 'testing' the default.

Patch needs a re-roll, both for this change, and also because testing.profile is missing. ;)

webchick’s picture

Issue tags: -Needs committer feedback

un-tagging.

Damien Tournoud’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
5.36 KB

This should work. Follow-up patches will use the testing profile in more places.

Dries’s picture

+++ modules/simpletest/drupal_web_test_case.php
@@ -1213,7 +1220,12 @@ class DrupalWebTestCase extends DrupalTestCase {
     // Run default profile tasks.
-    module_enable(array('standard'), FALSE);
+    $install_profile_module_exists = db_query("SELECT 1 FROM {system} WHERE type = 'module' AND name = :name", array(
+      ':name' => $this->profile))
+      ->fetchField();
+    if ($install_profile_module_exists) {
+      module_enable(array($this->profile), FALSE);
+    }

Looks like the comment needs to be updated? It is not necessarily the default profile.

anarcat’s picture

just a quick note there will be a conflict between this patch and #545452: Store install profile in the generated settings.php file which should be fairly easy to resolve, but that is to keep in mind anyways.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

sun’s picture

Status: Fixed » Needs review
FileSize
2.34 KB

Tiny follow-up. We should also fix that list of "absolutely required modules" in a separate issue, because we're treating many totally not required modules as absolutely required currently.

Damien Tournoud’s picture

Agreed with #116.

sun’s picture

Status: Needs review » Reviewed & tested by the community
webchick’s picture

Status: Reviewed & tested by the community » Fixed

Committed minor follow-up.

Status: Fixed » Closed (fixed)

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

sun’s picture