1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 11:30:55 +01:00

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
This commit is contained in:
epriestley 2015-01-20 11:31:32 -08:00
parent e6d6d8e961
commit 934df0e735
5 changed files with 219 additions and 0 deletions

1
bin/trigger Symbolic link
View file

@ -0,0 +1 @@
../scripts/setup/manage_trigger.php

View file

@ -0,0 +1,21 @@
#!/usr/bin/env php
<?php
$root = dirname(dirname(dirname(__FILE__)));
require_once $root.'/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline('manage triggers');
$args->setSynopsis(<<<EOSYNOPSIS
**trigger** __command__ [__options__]
Manage event triggers.
EOSYNOPSIS
);
$args->parseStandardArguments();
$workflows = id(new PhutilSymbolLoader())
->setAncestorClass('PhabricatorWorkerTriggerManagementWorkflow')
->loadObjects();
$workflows[] = new PhutilHelpArgumentWorkflow();
$args->parseWorkflows($workflows);

View file

@ -2603,6 +2603,8 @@ phutil_register_library_map(array(
'PhabricatorWorkerTestCase' => 'infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php',
'PhabricatorWorkerTrigger' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTrigger.php',
'PhabricatorWorkerTriggerEvent' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTriggerEvent.php',
'PhabricatorWorkerTriggerManagementFireWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementFireWorkflow.php',
'PhabricatorWorkerTriggerManagementWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerTriggerManagementWorkflow.php',
'PhabricatorWorkerTriggerPHIDType' => 'infrastructure/daemon/workers/phid/PhabricatorWorkerTriggerPHIDType.php',
'PhabricatorWorkerTriggerQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerTriggerQuery.php',
'PhabricatorWorkerYieldException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerYieldException.php',
@ -5889,6 +5891,8 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface',
),
'PhabricatorWorkerTriggerEvent' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerTriggerManagementFireWorkflow' => 'PhabricatorWorkerTriggerManagementWorkflow',
'PhabricatorWorkerTriggerManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorWorkerTriggerPHIDType' => 'PhabricatorPHIDType',
'PhabricatorWorkerTriggerQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorWorkerYieldException' => 'Exception',

View file

@ -0,0 +1,136 @@
<?php
final class PhabricatorWorkerTriggerManagementFireWorkflow
extends PhabricatorWorkerTriggerManagementWorkflow {
protected function didConstruct() {
$this
->setName('fire')
->setExamples('**fire** --id __id__')
->setSynopsis(
pht(
'Activates selected triggers, firing them immediately.'))
->setArguments(
array_merge(
array(
array(
'name' => 'now',
'param' => 'time',
'help' => pht(
'Fire the trigger as though the current time is a given '.
'time. This allows you to test how a trigger would behave '.
'if activated in the past or future. Defaults to the actual '.
'current time.'),
),
array(
'name' => 'last',
'param' => 'time',
'help' => pht(
'Fire the trigger as though the last event occurred at a '.
'given time. Defaults to the actual last event time.'),
),
array(
'name' => 'next',
'param' => 'time',
'help' => pht(
'Fire the trigger as though the next event was scheduled '.
'at a given time. Defaults to the actual time when the '.
'event is next scheduled to fire.'),
),
),
$this->getTriggerSelectionArguments()));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$viewer = $this->getViewer();
$triggers = $this->loadTriggers($args);
$now = $args->getArg('now');
$now = $this->parseTime($now);
if (!$now) {
$now = PhabricatorTime::getNow();
}
PhabricatorTime::pushTime($now, date_default_timezone_get());
$console->writeOut(
"%s\n",
pht(
'Set current time to %s.',
phabricator_datetime(PhabricatorTime::getNow(), $viewer)));
$last_time = $this->parseTime($args->getArg('last'));
$next_time = $this->parseTime($args->getArg('next'));
PhabricatorWorker::setRunAllTasksInProcess(true);
foreach ($triggers as $trigger) {
$console->writeOut(
"%s\n",
pht('Executing trigger %s.', $this->describeTrigger($trigger)));
$event = $trigger->getEvent();
if ($event) {
if (!$last_time) {
$last_time = $event->getLastEventEpoch();
}
if (!$next_time) {
$next_time = $event->getNextEventEpoch();
}
}
if (!$next_time) {
$console->writeOut(
"%s\n",
pht(
'Trigger is not scheduled to execute. Use --at to simluate '.
'a scheduled event.'));
continue;
} else {
$console->writeOut(
"%s\n",
pht(
'Executing event as though it was scheduled to execute at %s.',
phabricator_datetime($next_time, $viewer)));
}
if (!$last_time) {
$console->writeOut(
"%s\n",
pht(
'Executing event as though it never previously executed.'));
} else {
$console->writeOut(
"%s\n",
pht(
'Executing event as though it previously executed at %s.',
phabricator_datetime($last_time, $viewer)));
}
$trigger->executeTrigger($last_time, $next_time);
$reschedule_time = $trigger->getNextEventEpoch(
$next_time,
$is_reschedule = true);
if (!$reschedule_time) {
$console->writeOut(
"%s\n",
pht(
'After executing under these conditions, this event would never '.
'execute again.'));
} else {
$console->writeOut(
"%s\n",
pht(
'After executing under these conditions, this event would '.
'next execute at %s.',
phabricator_datetime($reschedule_time, $viewer)));
}
}
return 0;
}
}

View file

@ -0,0 +1,57 @@
<?php
abstract class PhabricatorWorkerTriggerManagementWorkflow
extends PhabricatorManagementWorkflow {
protected function getTriggerSelectionArguments() {
return array(
array(
'name' => 'id',
'param' => 'id',
'repeat' => true,
'help' => pht('Select one or more triggers by ID.'),
),
);
}
protected function loadTriggers(PhutilArgumentParser $args) {
$ids = $args->getArg('id');
if (!$ids) {
throw new PhutilArgumentUsageException(
pht('Use --id to select triggers by ID.'));
}
$triggers = id(new PhabricatorWorkerTriggerQuery())
->withIDs($ids)
->needEvents(true)
->execute();
$triggers = mpull($triggers, null, 'getID');
foreach ($ids as $id) {
if (empty($triggers[$id])) {
throw new PhutilArgumentUsageException(
pht('No trigger exists with id "%s"!', $id));
}
}
return $triggers;
}
protected function describeTrigger(PhabricatorWorkerTrigger $trigger) {
return pht('Trigger %d', $trigger->getID());
}
protected function parseTime($time) {
if (!strlen($time)) {
return null;
}
$epoch = strtotime($time);
if ($epoch <= 0) {
throw new PhutilArgumentUsageException(
pht('Unable to parse time "%s".', $time));
}
return $epoch;
}
}