Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(REF) CiviUnitTestCase - Cleanup and simplify the DB-reset mechanism #25178

Merged
merged 10 commits into from
Dec 19, 2022
127 changes: 19 additions & 108 deletions tests/phpunit/CiviTest/CiviUnitTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,6 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase {
*/
private static $dbInit = FALSE;

/**
* Database connection.
*
* @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
*/
protected $_dbconn;

/**
* The database name.
*
* @var string
*/
static protected $_dbName;

/**
* API version in use.
*
Expand All @@ -117,20 +103,6 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase {
*/
protected $tempDirs;

/**
* @var bool
* populateOnce allows to skip db resets in setUp
*
* WARNING! USE WITH CAUTION - IT'LL RENDER DATA DEPENDENCIES
* BETWEEN TESTS WHEN RUN IN SUITE. SUITABLE FOR LOCAL, LIMITED
* "CHECK RUNS" ONLY!
*
* IF POSSIBLE, USE $this->DBResetRequired = FALSE IN YOUR TEST CASE!
*
* @see http://forum.civicrm.org/index.php/topic,18065.0.html
*/
public static $populateOnce = FALSE;

/**
* DBResetRequired allows skipping DB reset
* in specific test case. If you still need
Expand Down Expand Up @@ -241,8 +213,6 @@ public function __construct($name = NULL, array $data = [], $dataName = '') {
// we need full error reporting
error_reporting(E_ALL & ~E_NOTICE);

self::$_dbName = self::getDBName();

// also load the class loader
require_once 'CRM/Core/ClassLoader.php';
CRM_Core_ClassLoader::singleton()->register();
Expand Down Expand Up @@ -271,87 +241,28 @@ protected function runTest() {
}

/**
* @return bool
*/
public function requireDBReset() {
return $this->DBResetRequired;
}

/**
* @return string
*/
public static function getDBName() {
static $dbName = NULL;
if ($dbName === NULL) {
require_once "DB.php";
$dsn = CRM_Utils_SQL::autoSwitchDSN(CIVICRM_DSN);
$dsninfo = DB::parseDSN($dsn);
$dbName = $dsninfo['database'];
}
return $dbName;
}

/**
* Create database connection for this instance.
* Declare the environment that we wish to run in.
*
* Initialize the test database if it hasn't been initialized
* TODO: The hope is to get this to align with `Civi\Test::headless()` and perhaps
* assimilate other steps from 'setUp()'. The method is reserved while we look
* for the right split. However, when we're a little further along on that, this
* should be made overrideable.
*
* @return \Civi\Test\CiviEnvBuilder
*/
protected function getConnection() {
if (!self::$dbInit) {
$dbName = self::getDBName();

// install test database
echo PHP_EOL . "Installing {$dbName} database" . PHP_EOL;

static::_populateDB(FALSE, $this);

self::$dbInit = TRUE;
}

}

/**
* Required implementation of abstract method.
*/
protected function getDataSet() {
final public static function buildEnvironment(): \Civi\Test\CiviEnvBuilder {
// Ideally: return Civi\Test::headless();
$b = new \Civi\Test\CiviEnvBuilder();
$b->callback([\Civi\Test::data(), 'populate']);
return $b;
}

/**
* @param bool $perClass
* @param null $object
*
* @return bool
* TRUE if the populate logic runs; FALSE if it is skipped
*/
protected static function _populateDB($perClass = FALSE, &$object = NULL) {
public static function setUpBeforeClass(): void {
if (CIVICRM_UF !== 'UnitTests') {
throw new \RuntimeException("_populateDB requires CIVICRM_UF=UnitTests");
throw new \RuntimeException("CiviUnitTestCase requires CIVICRM_UF=UnitTests");
}

if ($perClass || $object == NULL) {
$dbreset = TRUE;
}
else {
$dbreset = $object->requireDBReset();
}

if (self::$populateOnce || !$dbreset) {
return FALSE;
}
self::$populateOnce = NULL;

Civi\Test::data()->populate();

// `CiviUnitTestCase` has replaced the baseline DB configuration. To coexist with other
// tests based on `CiviEnvBuilder`, we need to store a signature marking the current DB configuration.
(new \Civi\Test\CiviEnvBuilder())->callback(function(){}, 'CiviUnitTestCase')->apply(TRUE);

return TRUE;
}

public static function setUpBeforeClass(): void {
static::_populateDB(TRUE);
\Civi\Test::asPreInstall([static::CLASS, 'buildEnvironment'])->apply(TRUE);

// also set this global hack
$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = [];
Expand All @@ -375,11 +286,11 @@ protected function setUp(): void {
exit(1);
}

// Get and save a connection to the database
$this->_dbconn = $this->getConnection();

// reload database before each test
// $this->_populateDB();
if (!self::$dbInit) {
fprintf(STDERR, "\nInstalling %s database\n", \Civi\Test::dsn('database'));
\Civi\Test::asPreInstall([static::CLASS, 'buildEnvironment'])->apply(TRUE);
self::$dbInit = TRUE;
}

// "initialize" CiviCRM to avoid problems when running single tests
// FIXME: look at it closer in second stage
Expand Down