Simpletest builds a new table prefix that it uses for its tables. It builds this using the global $db_prefix. However this isn't always a string. Common scenarios include multisite installs and when using CiviCRM. This patch fixes this.

Comments

dalin’s picture

Title: $db_prefix is assumed to be an array » $db_prefix is assumed to be a string

:P

dave reid’s picture

Status: Needs review » Postponed (maintainer needs more info)

SimpleTest should be run all on the same database. It takes special care to save your current db_prefix settings, changes them for testing, and then changes them back after the tests have finished? I'm not sure exactly why this is a problem?

dalin’s picture

Status: Postponed (maintainer needs more info) » Needs review

Currently simpletest does this to create its table names:

global $db_prefix;
$db_prefix_new = $db_prefix . 'simpletest' . mt_rand(1000, 1000000);

However global $db_prefix is not always a string. In fact I would guess that if it's not empty then more often than not it's an array.

$db_prefix = 'my_prefix_string';

OR something like:

$db_prefix = array(
  'default' => 'foo.'
  'users' => '',
  'civicrm_contacts' => 'civicrm.',
);
dave reid’s picture

Again, this is in the context of testing, not normal website operation. Are you testing CiviCRM?

dalin’s picture

Yes I'm testing CiviCRM but I think that's irrelevant. The point is that you can't concatenate an array with a string:

$foo = array('bar') . '_baz';

does not make $foo == 'bar_baz'

dave reid’s picture

Ah, I see what's going on. Seems like it might be valid.

agentrickard’s picture

Safer perhaps to check if $db_prefix is an array and use $db_prefix['default'] in that case?

Domain Prefix has this issue, and this fix:

/**
 * Check for existing table prefixing.
 */
function domain_prefix_get_prefix() {
  global $db_prefix;
  // Check for existing table prefixing.
  $prefix = NULL;
  if (!empty($db_prefix)) {
    if (is_array($db_prefix)) {
      $prefix = $db_prefix['default'];
    }
    else {
      $prefix = $db_prefix;
    }
  }
  return $prefix;
}
dalin’s picture

@agentrickard the problem being that the 'default' key, while recommended, is not required. So in my patch I did:

if (is_array($db_prefix)) {
  return (isset($db_prefix['default']) ? $db_prefix['default'] : array_shift($db_prefix)) .'simpletest';
}
else {
  return $db_prefix .'simpletest';
}
dalin’s picture

But perhaps to better mimick what core does, we should just use '' if 'default' is missing:


if (is_array($db_prefix)) {
  return (isset($db_prefix['default']) ? $db_prefix['default'] : '') .'simpletest';
}
else {
  return $db_prefix .'simpletest';
}
dalin’s picture

StatusFileSize
new2.39 KB

New patch using '' if 'default' is absent.

agentrickard’s picture

Now I wonder if I have to change my code, too. ;-p

moshe weitzman’s picture

This is a bug in core simpletest for d7. $this->originalPrefix can be an array.


protected function preloadRegistry() {
    db_query('INSERT INTO {registry} SELECT * FROM ' . $this->originalPrefix . 'registry');
    db_query('INSERT INTO {registry_file} SELECT * FROM ' . $this->originalPrefix . 'registry_file');
  }

boombatower’s picture

mysterlune’s picture

StatusFileSize
new520 bytes

Following up on #13, there are a couple of critical lines in the "716394-db-prefix-force.patch" (for D7) file that are not in the "D6-core-simpletest.patch" file distributed with SimpleTest (6.x-2.10 nor 6.x-2.x-dev). Banged my head on the wall for quite a bit on this one, so hopefully will save a lot of trouble for some D6'ers out there who are (like me) new to SimpleTest and use an array for $db_prefix.

Summary of the change: Out of the gate, we are asked to apply the D6-core-simpletest.patch to core. In doing so, bootstrap.inc's receives updates including (~ line 1029) the following:


        $db_prefix .= $matches[1];

that, on concatenation, resolves as something like "Arraysimpletest709493". As in the D7 patch 716394-db-prefix-force.patch we need the above line to actually be the following:


        $db_prefix_string = is_array($db_prefix) ? $db_prefix['default'] : $db_prefix;
        $db_prefix = $db_prefix_string . $matches[1];

The attached patch applies only this change.

The underlying assumption in rolling this patch against the (patched with D6-core-simpletest.patch) bootstrap.inc file is that folks are already running on the patched file per the distribution's INSTALL.txt

Please verify the fix does what it should.

(Brilliant module boombatower, btw. Many thanks!)

webchick’s picture

I'm getting a bunch of these in my php_error.log:

[30-Jun-2010 16:51:20] PHP Warning:  Table 'g365.simpletest475964simpletest475964semaphore' doesn't exist
query: SELECT expire, value FROM simpletest475964simpletest475964semaphore WHERE name = 'variable_cache_regenerate' in /Users/webchick/Sites/xxx.com/trunk/public_html/includes/database.mysql.inc on line 141

Presumably it's a result of this same thing because I'm connecting to both Drupal and CiviCRM databases in settings.php.

However, none of the patches here works for me. :(

I noticed #710978: Domain causes major testing errors as well, and we are using Domain Access, so I'll check that one before setting this to "needs work."

webchick’s picture

Ok. My problem was Domain Access-related. Ignore me! :D

moshe weitzman’s picture

good gosh, woman. you are using writing tests for simpletest d6 and domain access and Civicrm? And that 'variable_cache_regenerate' in the error msg looks ominous. You are a glutton for punishment.

webchick’s picture

Yes, my life has been a happy, happy place, let me tell you. ;)

sylvain lecoy’s picture

The bug is in drupal7 as well ?

I am getting this Arraysimpletest as well because of this:

<?php $db_prefix = $db_prefix . 'simpletest' . mt_rand(1000, 1000000); ?>

What is the status of this bug ? Should I apply the patch submitted ? Do we need to submit a patch for d7 or only for this back ported version ?

boombatower’s picture

Status: Needs review » Fixed

Should be fixed.

Status: Fixed » Closed (fixed)

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

dgtlmoon’s picture

Status: Closed (fixed) » Active

I just lost a lot of time tracing this bug down, only that it is still part of the current stable AND current dev release. It does not look like this patch to fix the issue was applied

    $db_prefix = $db_prefix . 'simpletest' . mt_rand(1000, 1000000);
dgtlmoon’s picture

Priority: Normal » Major

Marking as major because no one who uses anything than a trivial database setup can use simpletest

sylvain lecoy’s picture

I agree

dave reid’s picture

Priority: Major » Normal

Needs to be re-confirmed using the lastest code.

dave reid’s picture

Status: Active » Postponed (maintainer needs more info)
jonathan_hunt’s picture

I applied the patch in #10 to 6.x-2.11 and $db_prefix as an array now works for me. The release notes in 6.x-2.11 (http://drupal.org/node/935344 ) imply this issue is fixed but the patch in #10 wasn't applied.

bartoll’s picture

Status: Postponed (maintainer needs more info) » Needs review

#10: simpletest_db_prefix.diff queued for re-testing.

lendude’s picture

Issue summary: View changes
Status: Needs review » Fixed

Since this was originally marked fixed, setting it back to that, since nobody complained in the intervening 8 years :)

Status: Fixed » Closed (fixed)

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