1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-20 02:38:39 +01:00
phorge-phorge/src/infrastructure/testing/PhabricatorTestCase.php

185 lines
5.8 KiB
PHP
Raw Normal View History

<?php
abstract class PhabricatorTestCase extends ArcanistPhutilTestCase {
const NAMESPACE_PREFIX = 'phabricator_unittest_';
/**
* 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.
*/
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';
private $configuration;
private $env;
private static $storageFixtureReferences = 0;
private static $storageFixture;
private static $storageFixtureObjectSeed = 0;
protected function getPhabricatorTestCaseConfiguration() {
return array();
}
private function getComputedConfiguration() {
$config = $this->getPhabricatorTestCaseConfiguration() + array(
self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => true,
self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => false,
);
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;
}
public function willRunTestCases(array $test_cases) {
$root = dirname(phutil_get_library_root('phabricator'));
require_once $root.'/scripts/__init_script__.php';
$config = $this->getComputedConfiguration();
if ($config[self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES]) {
++self::$storageFixtureReferences;
if (!self::$storageFixture) {
self::$storageFixture = $this->newStorageFixture();
}
}
}
public function didRunTestCases(array $test_cases) {
if (self::$storageFixture) {
self::$storageFixtureReferences--;
if (!self::$storageFixtureReferences) {
self::$storageFixture = null;
}
}
}
protected function willRunTests() {
$config = $this->getComputedConfiguration();
if ($config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK]) {
LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess();
}
$this->env = PhabricatorEnv::beginScopedEnv();
In unit test environments, install all applications Summary: Normalize the unit test environment by installing all applications. The immediate issue this fixes is that `testDropUnknownSenderMail` depends on Maniphest being installed. Some possible fixes are: # Don't rely on the Maniphest mail receiver for the test (e.g., write a stub/dummy/mock receiver). # Explicitly make sure Maniphest is installed before running the test. # Normalize the test environment to install all applications. I don't like (1) much because it turns a pretty good 10 line test into a bunch of stub classes or mock junk. I'll do it if we have more uses after a few more diffs, but so far running these tests against real code hasn't created a dependency mess and we get more coverage. I don't like (2) much because I think requiring tests to do this will do more harm than good. The number of issues we'll hypothetically uncover by exposing unrealized application interdependencies is probably very small or maybe zero, and they're probably all trivial. But tests with an undeclared but implicit dependency on an application (e.g., Differential tests depend on Differential) are common. So here's (3), which I think is reasonable. I also simplified some of this code a little bit, and moved the Application object cache one level down (this was sort of a bug -- installation status is variant across requests). Test Plan: Added unit test. Reviewers: wez, btrahan Reviewed By: wez CC: aran Differential Revision: https://secure.phabricator.com/D5938
2013-05-16 12:25:26 -07:00
// NOTE: While running unit tests, we act as though all applications are
// installed, regardless of the install's configuration. Tests which need
// to uninstall applications are responsible for adjusting state themselves
// (such tests are exceedingly rare).
$this->env->overrideEnvConfig(
'phabricator.uninstalled-applications',
array());
// TODO: Remove this when we remove "releeph.installed".
$this->env->overrideEnvConfig('releeph.installed', true);
}
protected function didRunTests() {
$config = $this->getComputedConfiguration();
if ($config[self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK]) {
LiskDAO::endIsolateAllLiskEffectsToCurrentProcess();
}
try {
if (phutil_is_hiphop_runtime()) {
$this->env->__destruct();
}
unset($this->env);
} catch (Exception $ex) {
throw new Exception(
"Some test called PhabricatorEnv::beginScopedEnv(), but is still ".
"holding a reference to the scoped environment!");
}
}
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);
$name = self::NAMESPACE_PREFIX.$bytes;
return new PhabricatorStorageFixtureScopeGuard($name);
}
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);
}
/**
* 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;
}
}