Skip to content

Commit adfe84f

Browse files
author
epriestley
committedDec 17, 2012
Add HarbormasterRunnerWorker, for running CI tests
Summary: This is very preliminary and doesn't actually do anything useful. In theory, it uses Drydock to check out a working copy and run tests. In practice, it's not actually capable of running any of our tests (because of complicated interdependency stuff), but does check out a working copy and //try// to run tests there. Adds various sorts of utility methods to various things as well. Test Plan: Ran `reparse.php --harbormaster --trace <commit>`, observed attempt to run tests via Drydock. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2015, T1049 Differential Revision: https://secure.phabricator.com/D4215
1 parent 5cd39b3 commit adfe84f

9 files changed

+142
-5
lines changed
 

‎scripts/repository/reparse.php

+12-3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
'delete existing relationship entries between your '.
5656
'package and some old commits!)',
5757
),
58+
array(
59+
'name' => 'harbormaster',
60+
'help' => 'EXPERIMENTAL. Execute Harbormaster.',
61+
),
5862
// misc options
5963
array(
6064
'name' => 'force',
@@ -73,6 +77,7 @@
7377
$reparse_change = $args->getArg('change');
7478
$reparse_herald = $args->getArg('herald');
7579
$reparse_owners = $args->getArg('owners');
80+
$reparse_harbormaster = $args->getArg('harbormaster');
7681
$reparse_what = $args->getArg('revision');
7782
$force = $args->getArg('force');
7883
$force_local = $args->getArg('force-local');
@@ -83,9 +88,9 @@
8388
}
8489

8590
if (!$reparse_message && !$reparse_change && !$reparse_herald &&
86-
!$reparse_owners) {
91+
!$reparse_owners && !$reparse_harbormaster) {
8792
usage("Specify what information to reparse with --message, --change, ".
88-
"--herald, and/or --owners");
93+
"--herald, --harbormaster, and/or --owners");
8994
}
9095
if ($reparse_owners && !$force) {
9196
echo phutil_console_wrap(
@@ -202,6 +207,10 @@
202207
$classes[] = 'PhabricatorRepositoryCommitOwnersWorker';
203208
}
204209

210+
if ($reparse_harbormaster) {
211+
$classes[] = 'HarbormasterRunnerWorker';
212+
}
213+
205214
$spec = array(
206215
'commitID' => $commit->getID(),
207216
'only' => true,
@@ -218,7 +227,7 @@
218227
foreach ($classes as $class) {
219228
$worker = newv($class, array($spec));
220229
echo "Running '{$class}'...\n";
221-
$worker->doWork();
230+
$worker->executeTask();
222231
}
223232
}
224233
}

‎src/__phutil_library_map__.php

+2
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@
456456
'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php',
457457
'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
458458
'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
459+
'HarbormasterRunnerWorker' => 'applications/harbormaster/worker/HarbormasterRunnerWorker.php',
459460
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
460461
'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
461462
'HeraldActionConfig' => 'applications/herald/config/HeraldActionConfig.php',
@@ -1744,6 +1745,7 @@
17441745
'FeedPublisherWorker' => 'PhabricatorWorker',
17451746
'HarbormasterDAO' => 'PhabricatorLiskDAO',
17461747
'HarbormasterObject' => 'HarbormasterDAO',
1748+
'HarbormasterRunnerWorker' => 'PhabricatorWorker',
17471749
'HarbormasterScratchTable' => 'HarbormasterDAO',
17481750
'HeraldAction' => 'HeraldDAO',
17491751
'HeraldApplyTranscript' => 'HeraldDAO',

‎src/applications/drydock/blueprint/DrydockBlueprint.php

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ public function getBlueprintClass() {
2222
return get_class($this);
2323
}
2424

25+
protected function loadLease($lease_id) {
26+
$lease = id(new DrydockLease())->load($lease_id);
27+
if (!$lease) {
28+
throw new Exception("No such lease '{$lease_id}'!");
29+
}
30+
31+
$resource = $lease->loadResource();
32+
$lease->attachResource($resource);
33+
return $lease;
34+
}
35+
2536

2637
/* -( Lease Acquisition )-------------------------------------------------- */
2738

‎src/applications/drydock/blueprint/DrydockWorkingCopyBlueprint.php

+7
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ public function getInterface(
8686
DrydockLease $lease,
8787
$type) {
8888

89+
switch ($type) {
90+
case 'command':
91+
return $this
92+
->loadLease($resource->getAttribute('lease.host'))
93+
->getInterface($type);
94+
}
95+
8996
throw new Exception("No interface of type '{$type}'.");
9097
}
9198

‎src/applications/drydock/interface/command/DrydockCommandInterface.php

+24
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
abstract class DrydockCommandInterface extends DrydockInterface {
44

5+
private $workingDirectory;
6+
7+
public function setWorkingDirectory($working_directory) {
8+
$this->workingDirectory = $working_directory;
9+
return $this;
10+
}
11+
12+
public function getWorkingDirectory() {
13+
return $this->workingDirectory;
14+
}
15+
516
final public function getInterfaceType() {
617
return 'command';
718
}
@@ -24,4 +35,17 @@ final public function execx($command) {
2435

2536
abstract public function getExecFuture($command);
2637

38+
protected function applyWorkingDirectoryToArgv(array $argv) {
39+
if ($this->getWorkingDirectory() !== null) {
40+
$cmd = $argv[0];
41+
$cmd = "(cd %s; {$cmd})";
42+
$argv = array_merge(
43+
array($cmd),
44+
array($this->getWorkingDirectory()),
45+
array_slice($argv, 1));
46+
}
47+
48+
return $argv;
49+
}
50+
2751
}

‎src/applications/drydock/interface/command/DrydockLocalCommandInterface.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ final class DrydockLocalCommandInterface extends DrydockCommandInterface {
44

55
public function getExecFuture($command) {
66
$argv = func_get_args();
7+
$argv = $this->applyWorkingDirectoryToArgv($argv);
8+
79
return newv('ExecFuture', $argv);
810
}
911

‎src/applications/drydock/interface/command/DrydockSSHCommandInterface.php

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ final class DrydockSSHCommandInterface extends DrydockCommandInterface {
44

55
public function getExecFuture($command) {
66
$argv = func_get_args();
7+
$argv = $this->applyWorkingDirectoryToArgv($argv);
8+
79
$full_command = call_user_func_array('csprintf', $argv);
810

911
// NOTE: The "-t -t" is for psuedo-tty allocation so we can "sudo" on some

‎src/applications/drydock/storage/DrydockLease.php

+30-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,26 @@ final class DrydockLease extends DrydockDAO {
1111
protected $taskID;
1212

1313
private $resource;
14+
private $releaseOnDestruction;
15+
16+
/**
17+
* Flag this lease to be released when its destructor is called. This is
18+
* mostly useful if you have a script which acquires, uses, and then releases
19+
* a lease, as you don't need to explicitly handle exceptions to properly
20+
* release the lease.
21+
*/
22+
public function releaseOnDestruction() {
23+
$this->releaseOnDestruction = true;
24+
return $this;
25+
}
26+
27+
public function __destruct() {
28+
if ($this->releaseOnDestruction) {
29+
if ($this->isActive()) {
30+
$this->release();
31+
}
32+
}
33+
}
1434

1535
public function getLeaseName() {
1636
return pht('Lease %d', $this->getID());
@@ -103,9 +123,17 @@ public function release() {
103123
return $this;
104124
}
105125

126+
private function isActive() {
127+
switch ($this->status) {
128+
case DrydockLeaseStatus::STATUS_ACTIVE:
129+
case DrydockLeaseStatus::STATUS_ACQUIRING:
130+
return true;
131+
}
132+
return false;
133+
}
134+
106135
private function assertActive() {
107-
if (($this->status != DrydockLeaseStatus::STATUS_ACTIVE) &&
108-
($this->status != DrydockLeaseStatus::STATUS_ACQUIRING)) {
136+
if (!$this->isActive()) {
109137
throw new Exception(
110138
"Lease is not active! You can not interact with resources through ".
111139
"an inactive lease.");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
final class HarbormasterRunnerWorker extends PhabricatorWorker {
4+
5+
public function getRequiredLeaseTime() {
6+
return 60 * 60 * 24;
7+
}
8+
9+
protected function doWork() {
10+
$data = $this->getTaskData();
11+
$id = idx($data, 'commitID');
12+
13+
$commit = id(new PhabricatorRepositoryCommit())->loadOneWhere(
14+
'id = %d',
15+
$id);
16+
17+
if (!$commit) {
18+
throw new PhabricatorWorkerPermanentFailureException(
19+
"Commit '{$id}' does not exist!");
20+
}
21+
22+
$repository = id(new PhabricatorRepository())->loadOneWhere(
23+
'id = %d',
24+
$commit->getRepositoryID());
25+
26+
if (!$repository) {
27+
throw new PhabricatorWorkerPermanentFailureException(
28+
"Unable to load repository for commit '{$id}'!");
29+
}
30+
31+
$lease = id(new DrydockLease())
32+
->setResourceType('working-copy')
33+
->setAttributes(
34+
array(
35+
'repositoryID' => $repository->getID(),
36+
'commit' => $commit->getCommitIdentifier(),
37+
))
38+
->releaseOnDestruction()
39+
->waitUntilActive();
40+
41+
$cmd = $lease->getInterface('command');
42+
list($json) = $cmd
43+
->setWorkingDirectory($lease->getResource()->getAttribute('path'))
44+
->execx('arc unit --everything --json');
45+
$lease->release();
46+
47+
// TODO: Do something actually useful with this. Requires Harbormaster
48+
// buildout.
49+
echo $json;
50+
}
51+
52+
}

0 commit comments

Comments
 (0)
Failed to load comments.