Skip to content

Commit 0aa6702

Browse files
author
epriestley
committedMay 16, 2013
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
1 parent 37e28f3 commit 0aa6702

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed
 

‎src/applications/base/PhabricatorApplication.php

+21-28
Original file line numberDiff line numberDiff line change
@@ -255,46 +255,39 @@ public static function getByClass($class_name) {
255255
}
256256

257257
public static function getAllApplications() {
258-
$classes = id(new PhutilSymbolLoader())
259-
->setAncestorClass(__CLASS__)
260-
->setConcreteOnly(true)
261-
->selectAndLoadSymbols();
258+
static $applications;
262259

263-
$apps = array();
260+
if ($applications === null) {
261+
$apps = id(new PhutilSymbolLoader())
262+
->setAncestorClass(__CLASS__)
263+
->loadObjects();
264264

265-
foreach ($classes as $class) {
266-
$app = newv($class['name'], array());
267-
$apps[] = $app;
265+
// Reorder the applications into "application order". Notably, this
266+
// ensures their event handlers register in application order.
267+
$apps = msort($apps, 'getApplicationOrder');
268+
$apps = mgroup($apps, 'getApplicationGroup');
269+
$apps = array_select_keys($apps, self::getApplicationGroups()) + $apps;
270+
$apps = array_mergev($apps);
271+
272+
$applications = $apps;
268273
}
269274

270-
// Reorder the applications into "application order". Notably, this ensures
271-
// their event handlers register in application order.
272-
$apps = msort($apps, 'getApplicationOrder');
273-
$apps = mgroup($apps, 'getApplicationGroup');
274-
$apps = array_select_keys($apps, self::getApplicationGroups()) + $apps;
275-
$apps = array_mergev($apps);
276275

277-
return $apps;
276+
return $applications;
278277
}
279278

280279
public static function getAllInstalledApplications() {
281-
static $applications;
282-
283-
if (empty($applications)) {
284-
$all_applications = self::getAllApplications();
285-
$apps = array();
286-
foreach ($all_applications as $app) {
287-
if (!$app->isInstalled()) {
288-
continue;
289-
}
290-
291-
$apps[] = $app;
280+
$all_applications = self::getAllApplications();
281+
$apps = array();
282+
foreach ($all_applications as $app) {
283+
if (!$app->isInstalled()) {
284+
continue;
292285
}
293286

294-
$applications = $apps;
287+
$apps[] = $app;
295288
}
296289

297-
return $applications;
290+
return $apps;
298291
}
299292

300293
}

‎src/infrastructure/__tests__/PhabricatorInfrastructureTestCase.php

+15-6
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,23 @@ final class PhabricatorInfrastructureTestCase
55

66
/**
77
* This is more of an acceptance test case instead of a unittest. It verifies
8-
* that all symbols can be loaded correctly. It can catch problem like missing
9-
* methods in descendants of abstract base classes.
8+
* that all symbols can be loaded correctly. It can catch problems like
9+
* missing methods in descendants of abstract base classes.
1010
*/
1111
public function testEverythingImplemented() {
12-
// Note that we don't have a try catch block around the following because,
13-
// when it fails, it will cause a HPHP or PHP fatal which won't be caught
14-
// by try catch.
15-
$every_class = id(new PhutilSymbolLoader())->selectAndLoadSymbols();
12+
id(new PhutilSymbolLoader())->selectAndLoadSymbols();
1613
}
14+
15+
public function testApplicationsInstalled() {
16+
$all = PhabricatorApplication::getAllApplications();
17+
$installed = PhabricatorApplication::getAllInstalledApplications();
18+
19+
$this->assertEqual(
20+
count($all),
21+
count($installed),
22+
'In test cases, all applications should default to installed.');
23+
}
24+
25+
1726
}
1827

‎src/infrastructure/testing/PhabricatorTestCase.php

+9
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ protected function willRunTests() {
8787
}
8888

8989
$this->env = PhabricatorEnv::beginScopedEnv();
90+
91+
// NOTE: While running unit tests, we act as though all applications are
92+
// installed, regardless of the install's configuration. Tests which need
93+
// to uninstall applications are responsible for adjusting state themselves
94+
// (such tests are exceedingly rare).
95+
96+
$this->env->overrideEnvConfig(
97+
'phabricator.uninstalled-applications',
98+
array());
9099
}
91100

92101
protected function didRunTests() {

0 commit comments

Comments
 (0)
Failed to load comments.