2011-04-30 19:11:41 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
abstract class PhabricatorTestCase extends ArcanistPhutilTestCase {
|
|
|
|
|
2012-11-01 02:36:38 +01:00
|
|
|
const NAMESPACE_PREFIX = 'phabricator_unittest_';
|
2011-04-30 19:11:59 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* If true, put Lisk in process-isolated mode for the duration of the tests so
|
|
|
|
* that it will establish only isolated, side-effect-free database
|
|
|
|
* connections. Defaults to true.
|
|
|
|
*
|
|
|
|
* NOTE: You should disable this only in rare circumstances. Unit tests should
|
|
|
|
* not rely on external resources like databases, and should not produce
|
|
|
|
* side effects.
|
|
|
|
*/
|
2012-05-02 21:42:23 +02:00
|
|
|
const PHABRICATOR_TESTCONFIG_ISOLATE_LISK = 'isolate-lisk';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If true, build storage fixtures before running tests, and connect to them
|
|
|
|
* during test execution. This will impose a performance penalty on test
|
|
|
|
* execution (currently, it takes roughly one second to build the fixture)
|
|
|
|
* but allows you to perform tests which require data to be read from storage
|
|
|
|
* after writes. The fixture is shared across all test cases in this process.
|
|
|
|
* Defaults to false.
|
|
|
|
*
|
|
|
|
* NOTE: All connections to fixture storage open transactions when established
|
|
|
|
* and roll them back when tests complete. Each test must independently
|
|
|
|
* write data it relies on; data will not persist across tests.
|
|
|
|
*
|
|
|
|
* NOTE: Enabling this implies disabling process isolation.
|
|
|
|
*/
|
|
|
|
const PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES = 'storage-fixtures';
|
2011-04-30 19:11:59 +02:00
|
|
|
|
|
|
|
private $configuration;
|
2012-04-17 16:52:01 +02:00
|
|
|
private $env;
|
2011-04-30 19:11:59 +02:00
|
|
|
|
2012-05-02 21:42:23 +02:00
|
|
|
private static $storageFixtureReferences = 0;
|
|
|
|
private static $storageFixture;
|
2012-10-23 01:25:00 +02:00
|
|
|
private static $storageFixtureObjectSeed = 0;
|
2012-05-02 21:42:23 +02:00
|
|
|
|
2011-04-30 19:11:59 +02:00
|
|
|
protected function getPhabricatorTestCaseConfiguration() {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
|
|
|
|
private function getComputedConfiguration() {
|
2012-05-02 21:42:23 +02:00
|
|
|
$config = $this->getPhabricatorTestCaseConfiguration() + array(
|
|
|
|
self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => true,
|
|
|
|
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => false,
|
2011-04-30 19:11:59 +02:00
|
|
|
);
|
2012-05-02 21:42:23 +02:00
|
|
|
|
|
|
|
if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) {
|
|
|
|
// Fixtures don't make sense with process isolation.
|
|
|
|
$config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $config;
|
2011-04-30 19:11:59 +02:00
|
|
|
}
|
|
|
|
|
2011-04-30 19:11:41 +02:00
|
|
|
protected function willRunTests() {
|
|
|
|
$root = dirname(phutil_get_library_root('phabricator'));
|
2011-10-01 17:59:42 +02:00
|
|
|
require_once $root.'/scripts/__init_script__.php';
|
2011-04-30 19:11:59 +02:00
|
|
|
|
|
|
|
$config = $this->getComputedConfiguration();
|
|
|
|
|
|
|
|
if ($config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK]) {
|
|
|
|
LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess();
|
|
|
|
}
|
2012-04-17 16:52:01 +02:00
|
|
|
|
2012-05-02 21:42:23 +02:00
|
|
|
if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) {
|
|
|
|
++self::$storageFixtureReferences;
|
|
|
|
if (!self::$storageFixture) {
|
|
|
|
self::$storageFixture = $this->newStorageFixture();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-17 16:52:01 +02:00
|
|
|
$this->env = PhabricatorEnv::beginScopedEnv();
|
2011-04-30 19:11:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function didRunTests() {
|
|
|
|
$config = $this->getComputedConfiguration();
|
|
|
|
|
|
|
|
if ($config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK]) {
|
|
|
|
LiskDAO::endIsolateAllLiskEffectsToCurrentProcess();
|
|
|
|
}
|
2012-04-17 16:52:01 +02:00
|
|
|
|
2012-05-02 21:42:23 +02:00
|
|
|
if (self::$storageFixture) {
|
|
|
|
self::$storageFixtureReferences--;
|
|
|
|
if (!self::$storageFixtureReferences) {
|
|
|
|
self::$storageFixture = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-17 16:52:01 +02:00
|
|
|
try {
|
|
|
|
unset($this->env);
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
throw new Exception(
|
|
|
|
"Some test called PhabricatorEnv::beginScopedEnv(), but is still ".
|
|
|
|
"holding a reference to the scoped environment!");
|
|
|
|
}
|
2011-04-30 19:11:41 +02:00
|
|
|
}
|
|
|
|
|
2012-05-02 21:42:23 +02:00
|
|
|
protected function willRunOneTest($test) {
|
|
|
|
$config = $this->getComputedConfiguration();
|
|
|
|
|
|
|
|
if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) {
|
|
|
|
LiskDAO::beginIsolateAllLiskEffectsToTransactions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function didRunOneTest($test) {
|
|
|
|
$config = $this->getComputedConfiguration();
|
|
|
|
|
|
|
|
if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) {
|
|
|
|
LiskDAO::endIsolateAllLiskEffectsToTransactions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function newStorageFixture() {
|
|
|
|
$bytes = Filesystem::readRandomCharacters(24);
|
2012-11-01 02:36:38 +01:00
|
|
|
$name = self::NAMESPACE_PREFIX.$bytes;
|
2012-05-02 21:42:23 +02:00
|
|
|
|
|
|
|
return new PhabricatorStorageFixtureScopeGuard($name);
|
|
|
|
}
|
|
|
|
|
2012-09-07 23:21:51 +02:00
|
|
|
protected function getLink($method) {
|
|
|
|
$phabricator_project = 'PHID-APRJ-3f1fc779edeab89b2171';
|
|
|
|
return
|
|
|
|
'https://secure.phabricator.com/diffusion/symbol/'.$method.
|
|
|
|
'/?lang=php&projects='.$phabricator_project.
|
|
|
|
'&jump=true&context='.get_class($this);
|
|
|
|
}
|
|
|
|
|
2012-10-23 01:25:00 +02:00
|
|
|
/**
|
|
|
|
* Returns an integer seed to use when building unique identifiers (e.g.,
|
|
|
|
* non-colliding usernames). The seed is unstable and its value will change
|
|
|
|
* between test runs, so your tests must not rely on it.
|
|
|
|
*
|
|
|
|
* @return int A unique integer.
|
|
|
|
*/
|
|
|
|
protected function getNextObjectSeed() {
|
|
|
|
self::$storageFixtureObjectSeed += mt_rand(1, 100);
|
|
|
|
return self::$storageFixtureObjectSeed;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function generateNewTestUser() {
|
|
|
|
$seed = $this->getNextObjectSeed();
|
|
|
|
|
|
|
|
$user = id(new PhabricatorUser())
|
|
|
|
->setRealName("Test User {$seed}}")
|
|
|
|
->setUserName("test{$seed}");
|
|
|
|
|
|
|
|
$email = id(new PhabricatorUserEmail())
|
|
|
|
->setAddress("testuser{$seed}@example.com")
|
|
|
|
->setIsVerified(1);
|
|
|
|
|
|
|
|
$editor = new PhabricatorUserEditor();
|
|
|
|
$editor->setActor($user);
|
|
|
|
$editor->createNewUser($user, $email);
|
|
|
|
|
|
|
|
return $user;
|
|
|
|
}
|
|
|
|
|
2011-04-30 19:11:41 +02:00
|
|
|
}
|