Skip to content

Commit 934df0e

Browse files
author
epriestley
committedJan 20, 2015
Add bin/trigger, for testing event triggers
Summary: Ref T6881. This makes it easier to fire a trigger and make sure it works properly. You can use the `--now` flag to travel through time, and test scheduling conditions with `--last` and `--next`. It will tell you when the trigger would reschedule. Better than waiting 24 hours to see if things work. Test Plan: Fired some backups, got useful output which made me think my code probably works correctly. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6881 Differential Revision: https://secure.phabricator.com/D11438
1 parent e6d6d8e commit 934df0e

File tree

5 files changed

+219
-0
lines changed

5 files changed

+219
-0
lines changed
 

‎bin/trigger

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../scripts/setup/manage_trigger.php

‎scripts/setup/manage_trigger.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
$root = dirname(dirname(dirname(__FILE__)));
5+
require_once $root.'/scripts/__init_script__.php';
6+
7+
$args = new PhutilArgumentParser($argv);
8+
$args->setTagline('manage triggers');
9+
$args->setSynopsis(<<<EOSYNOPSIS
10+
**trigger** __command__ [__options__]
11+
Manage event triggers.
12+
13+
EOSYNOPSIS
14+
);
15+
$args->parseStandardArguments();
16+
17+
$workflows = id(new PhutilSymbolLoader())
18+
->setAncestorClass('PhabricatorWorkerTriggerManagementWorkflow')
19+
->loadObjects();
20+
$workflows[] = new PhutilHelpArgumentWorkflow();
21+
$args->parseWorkflows($workflows);

‎src/__phutil_library_map__.php

+4
Original file line numberDiff line numberDiff line change
@@ -2603,6 +2603,8 @@
26032603
'PhabricatorWorkerTestCase' => 'infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php',
26042604
'PhabricatorWorkerTrigger' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTrigger.php',
26052605
'PhabricatorWorkerTriggerEvent' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTriggerEvent.php',
2606+
'PhabricatorWorkerTriggerManagementFireWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementFireWorkflow.php',
2607+
'PhabricatorWorkerTriggerManagementWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementWorkflow.php',
26062608
'PhabricatorWorkerTriggerPHIDType' => 'infrastructure/daemon/workers/phid/PhabricatorWorkerTriggerPHIDType.php',
26072609
'PhabricatorWorkerTriggerQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php',
26082610
'PhabricatorWorkerYieldException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerYieldException.php',
@@ -5889,6 +5891,8 @@
58895891
'PhabricatorDestructibleInterface',
58905892
),
58915893
'PhabricatorWorkerTriggerEvent' => 'PhabricatorWorkerDAO',
5894+
'PhabricatorWorkerTriggerManagementFireWorkflow' => 'PhabricatorWorkerTriggerManagementWorkflow',
5895+
'PhabricatorWorkerTriggerManagementWorkflow' => 'PhabricatorManagementWorkflow',
58925896
'PhabricatorWorkerTriggerPHIDType' => 'PhabricatorPHIDType',
58935897
'PhabricatorWorkerTriggerQuery' => 'PhabricatorOffsetPagedQuery',
58945898
'PhabricatorWorkerYieldException' => 'Exception',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
final class PhabricatorWorkerTriggerManagementFireWorkflow
4+
extends PhabricatorWorkerTriggerManagementWorkflow {
5+
6+
protected function didConstruct() {
7+
$this
8+
->setName('fire')
9+
->setExamples('**fire** --id __id__')
10+
->setSynopsis(
11+
pht(
12+
'Activates selected triggers, firing them immediately.'))
13+
->setArguments(
14+
array_merge(
15+
array(
16+
array(
17+
'name' => 'now',
18+
'param' => 'time',
19+
'help' => pht(
20+
'Fire the trigger as though the current time is a given '.
21+
'time. This allows you to test how a trigger would behave '.
22+
'if activated in the past or future. Defaults to the actual '.
23+
'current time.'),
24+
),
25+
array(
26+
'name' => 'last',
27+
'param' => 'time',
28+
'help' => pht(
29+
'Fire the trigger as though the last event occurred at a '.
30+
'given time. Defaults to the actual last event time.'),
31+
),
32+
array(
33+
'name' => 'next',
34+
'param' => 'time',
35+
'help' => pht(
36+
'Fire the trigger as though the next event was scheduled '.
37+
'at a given time. Defaults to the actual time when the '.
38+
'event is next scheduled to fire.'),
39+
),
40+
),
41+
$this->getTriggerSelectionArguments()));
42+
}
43+
44+
public function execute(PhutilArgumentParser $args) {
45+
$console = PhutilConsole::getConsole();
46+
$viewer = $this->getViewer();
47+
$triggers = $this->loadTriggers($args);
48+
49+
$now = $args->getArg('now');
50+
$now = $this->parseTime($now);
51+
if (!$now) {
52+
$now = PhabricatorTime::getNow();
53+
}
54+
55+
PhabricatorTime::pushTime($now, date_default_timezone_get());
56+
57+
$console->writeOut(
58+
"%s\n",
59+
pht(
60+
'Set current time to %s.',
61+
phabricator_datetime(PhabricatorTime::getNow(), $viewer)));
62+
63+
$last_time = $this->parseTime($args->getArg('last'));
64+
$next_time = $this->parseTime($args->getArg('next'));
65+
66+
PhabricatorWorker::setRunAllTasksInProcess(true);
67+
68+
foreach ($triggers as $trigger) {
69+
$console->writeOut(
70+
"%s\n",
71+
pht('Executing trigger %s.', $this->describeTrigger($trigger)));
72+
73+
$event = $trigger->getEvent();
74+
if ($event) {
75+
if (!$last_time) {
76+
$last_time = $event->getLastEventEpoch();
77+
}
78+
if (!$next_time) {
79+
$next_time = $event->getNextEventEpoch();
80+
}
81+
}
82+
83+
if (!$next_time) {
84+
$console->writeOut(
85+
"%s\n",
86+
pht(
87+
'Trigger is not scheduled to execute. Use --at to simluate '.
88+
'a scheduled event.'));
89+
continue;
90+
} else {
91+
$console->writeOut(
92+
"%s\n",
93+
pht(
94+
'Executing event as though it was scheduled to execute at %s.',
95+
phabricator_datetime($next_time, $viewer)));
96+
}
97+
98+
if (!$last_time) {
99+
$console->writeOut(
100+
"%s\n",
101+
pht(
102+
'Executing event as though it never previously executed.'));
103+
} else {
104+
$console->writeOut(
105+
"%s\n",
106+
pht(
107+
'Executing event as though it previously executed at %s.',
108+
phabricator_datetime($last_time, $viewer)));
109+
}
110+
111+
$trigger->executeTrigger($last_time, $next_time);
112+
113+
$reschedule_time = $trigger->getNextEventEpoch(
114+
$next_time,
115+
$is_reschedule = true);
116+
117+
if (!$reschedule_time) {
118+
$console->writeOut(
119+
"%s\n",
120+
pht(
121+
'After executing under these conditions, this event would never '.
122+
'execute again.'));
123+
} else {
124+
$console->writeOut(
125+
"%s\n",
126+
pht(
127+
'After executing under these conditions, this event would '.
128+
'next execute at %s.',
129+
phabricator_datetime($reschedule_time, $viewer)));
130+
}
131+
}
132+
133+
return 0;
134+
}
135+
136+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
abstract class PhabricatorWorkerTriggerManagementWorkflow
4+
extends PhabricatorManagementWorkflow {
5+
6+
protected function getTriggerSelectionArguments() {
7+
return array(
8+
array(
9+
'name' => 'id',
10+
'param' => 'id',
11+
'repeat' => true,
12+
'help' => pht('Select one or more triggers by ID.'),
13+
),
14+
);
15+
}
16+
17+
protected function loadTriggers(PhutilArgumentParser $args) {
18+
$ids = $args->getArg('id');
19+
if (!$ids) {
20+
throw new PhutilArgumentUsageException(
21+
pht('Use --id to select triggers by ID.'));
22+
}
23+
24+
$triggers = id(new PhabricatorWorkerTriggerQuery())
25+
->withIDs($ids)
26+
->needEvents(true)
27+
->execute();
28+
$triggers = mpull($triggers, null, 'getID');
29+
30+
foreach ($ids as $id) {
31+
if (empty($triggers[$id])) {
32+
throw new PhutilArgumentUsageException(
33+
pht('No trigger exists with id "%s"!', $id));
34+
}
35+
}
36+
37+
return $triggers;
38+
}
39+
40+
protected function describeTrigger(PhabricatorWorkerTrigger $trigger) {
41+
return pht('Trigger %d', $trigger->getID());
42+
}
43+
44+
protected function parseTime($time) {
45+
if (!strlen($time)) {
46+
return null;
47+
}
48+
49+
$epoch = strtotime($time);
50+
if ($epoch <= 0) {
51+
throw new PhutilArgumentUsageException(
52+
pht('Unable to parse time "%s".', $time));
53+
}
54+
return $epoch;
55+
}
56+
57+
}

0 commit comments

Comments
 (0)
Failed to load comments.