diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index 89cfd7c..4fcdd1b 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -1,4 +1,3 @@
tools:
external_code_coverage:
- timeout: 300
- runs: 6
+ timeout: 1200
diff --git a/.travis.yml b/.travis.yml
index 21dd9cb..a2a68c5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,19 +1,31 @@
language: php
-php:
- - 5.5
- - 5.6
- - 7.0
- - hhvm
-
-env:
- - STORAGE=array
- - STORAGE=doctrine
+matrix:
+ fast_finish: true
+ include:
+ - php: 5.6
+ env:
+ - STORAGE=doctrine
+ - CODE_COVERAGE=true
+ - php: 5.6
+ env:
+ - STORAGE=array
+ - php: 7.0
+ env:
+ - STORAGE=doctrine
+ - php: 7.0
+ env:
+ - STORAGE=array
+ - php: hhvm
+ env:
+ - STORAGE=doctrine
+ - php: hhvm
+ env:
+ - STORAGE=array
install:
- composer self-update
- composer update
- - wget https://scrutinizer-ci.com/ocular.phar
before_script:
- STORAGE=doctrine tests/app/console doctrine:database:create
@@ -23,4 +35,10 @@ script:
- phpunit -c phpunit.xml.dist --coverage-clover=coverage.clover
after_script:
- - php ocular.phar code-coverage:upload --access-token="230ec5e01daf5bb3e46ea304fb20348b52d80de73463ec08ee9c96fcd1349e35" --format=php-clover coverage.clover
+ - if [[ $CODE_COVERAGE == 'true' ]]; then wget https://scrutinizer-ci.com/ocular.phar ; fi
+ - if [[ $CODE_COVERAGE == 'true' ]]; then php ocular.phar code-coverage:upload --access-token="230ec5e01daf5bb3e46ea304fb20348b52d80de73463ec08ee9c96fcd1349e35" --format=php-clover coverage.clover ; fi
+
+cache:
+ directories:
+ - "$HOME/.composer/cache"
+ - vendor
diff --git a/composer.json b/composer.json
index 932f04c..32424f4 100644
--- a/composer.json
+++ b/composer.json
@@ -10,7 +10,7 @@
}
],
"require": {
- "php": "~5.5 || ~7.0",
+ "php": "~5.6 || ~7.0",
"php-task/php-task": "dev-master",
"symfony/http-kernel": "^2.6",
"symfony/dependency-injection": "^2.6",
@@ -22,13 +22,19 @@
"phpunit/phpunit": "^4.8",
"symfony/framework-bundle": "^2.6",
"symfony/finder": "^2.6",
- "doctrine/doctrine-bundle": "^1.5"
+ "doctrine/doctrine-bundle": "^1.5",
+ "doctrine/data-fixtures": "^1.2"
},
"autoload": {
"psr-4": {
"Task\\TaskBundle\\": "src"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "Task\\TaskBundle\\Tests\\": "tests"
+ }
+ },
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
diff --git a/src/Command/DebugTasksCommand.php b/src/Command/DebugTasksCommand.php
index f3f22f6..5dfbe52 100644
--- a/src/Command/DebugTasksCommand.php
+++ b/src/Command/DebugTasksCommand.php
@@ -16,7 +16,7 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use Task\Execution\TaskExecutionRepositoryInterface;
+use Task\Storage\TaskExecutionRepositoryInterface;
/**
* Run pending tasks.
@@ -26,17 +26,17 @@ class DebugTasksCommand extends Command
/**
* @var TaskExecutionRepositoryInterface
*/
- private $storage;
+ private $taskExecutionRepository;
/**
* @param string $name
- * @param TaskExecutionRepositoryInterface $storage
+ * @param TaskExecutionRepositoryInterface $taskExecutionRepository
*/
- public function __construct($name, TaskExecutionRepositoryInterface $storage)
+ public function __construct($name, TaskExecutionRepositoryInterface $taskExecutionRepository)
{
parent::__construct($name);
- $this->storage = $storage;
+ $this->taskExecutionRepository = $taskExecutionRepository;
}
/**
@@ -45,7 +45,8 @@ public function __construct($name, TaskExecutionRepositoryInterface $storage)
protected function configure()
{
$this->setDescription('Debug tasks')
- ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, '', null);
+ ->addOption('page', 'p', InputOption::VALUE_REQUIRED, '', 1)
+ ->addOption('page-size', null, InputOption::VALUE_REQUIRED, '', null);
}
/**
@@ -53,9 +54,10 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $limit = $input->getOption('limit');
+ $page = $input->getOption('page');
+ $pageSize = $input->getOption('page-size');
- $executions = $this->storage->findAll($limit);
+ $executions = $this->taskExecutionRepository->findAll($page, $pageSize);
$table = new Table($output);
$table->setHeaders(['uuid', 'status', 'handler', 'schedule time', 'end time', 'duration']);
diff --git a/src/Command/RunCommand.php b/src/Command/RunCommand.php
index f7a3c68..f496513 100644
--- a/src/Command/RunCommand.php
+++ b/src/Command/RunCommand.php
@@ -15,7 +15,7 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Task\Runner\TaskRunnerInterface;
-use Task\Scheduler\SchedulerInterface;
+use Task\Scheduler\TaskSchedulerInterface;
/**
* Run pending tasks.
@@ -28,16 +28,16 @@ class RunCommand extends Command
private $runner;
/**
- * @var SchedulerInterface
+ * @var TaskSchedulerInterface
*/
private $scheduler;
/**
* @param string $name
* @param TaskRunnerInterface $runner
- * @param SchedulerInterface $scheduler
+ * @param TaskSchedulerInterface $scheduler
*/
- public function __construct($name, TaskRunnerInterface $runner, SchedulerInterface $scheduler)
+ public function __construct($name, TaskRunnerInterface $runner, TaskSchedulerInterface $scheduler)
{
parent::__construct($name);
diff --git a/src/Command/ScheduleTaskCommand.php b/src/Command/ScheduleTaskCommand.php
index 6a104b7..063ecda 100644
--- a/src/Command/ScheduleTaskCommand.php
+++ b/src/Command/ScheduleTaskCommand.php
@@ -16,7 +16,7 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
-use Task\Scheduler\SchedulerInterface;
+use Task\Scheduler\TaskSchedulerInterface;
/**
* Schedule task.
@@ -24,15 +24,15 @@
class ScheduleTaskCommand extends Command
{
/**
- * @var SchedulerInterface
+ * @var TaskSchedulerInterface
*/
private $scheduler;
/**
* @param string $name
- * @param SchedulerInterface $runner
+ * @param TaskSchedulerInterface $runner
*/
- public function __construct($name, SchedulerInterface $runner)
+ public function __construct($name, TaskSchedulerInterface $runner)
{
parent::__construct($name);
@@ -46,9 +46,10 @@ protected function configure()
{
$this
->setDescription('Run pending tasks')
- ->addArgument('handler', InputArgument::REQUIRED)
+ ->addArgument('handlerClass', InputArgument::REQUIRED)
->addArgument('workload', InputArgument::OPTIONAL)
->addOption('cron-expression', 'c', InputOption::VALUE_REQUIRED)
+ ->addOption('execution-date', null, InputOption::VALUE_REQUIRED)
->addOption('end-date', null, InputOption::VALUE_REQUIRED);
}
@@ -57,16 +58,17 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
- $handler = $input->getArgument('handler');
+ $handlerClass = $input->getArgument('handlerClass');
$workload = $input->getArgument('workload');
$cronExpression = $input->getOption('cron-expression');
+ $executionDateString = $input->getOption('execution-date');
$endDateString = $input->getOption('end-date');
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
- $output->writeln(sprintf('Schedule task "%s" with workload "%s"', $handler, $workload));
+ $output->writeln(sprintf('Schedule task "%s" with workload "%s"', $handlerClass, $workload));
}
- $taskBuilder = $this->scheduler->createTask($input->getArgument('handler'), $input->getArgument('workload'));
+ $taskBuilder = $this->scheduler->createTask($handlerClass, $workload);
if ($cronExpression !== null) {
$endDate = null;
@@ -77,6 +79,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
$taskBuilder->cron($cronExpression, new \DateTime(), $endDate);
}
+ if ($executionDateString !== null) {
+ $taskBuilder->executeAt(new \DateTime($executionDateString));
+ }
+
$this->scheduler->addTask($taskBuilder->getTask());
}
}
diff --git a/src/DoctrineStorage/TaskExecutionRepository.php b/src/DoctrineStorage/TaskExecutionRepository.php
deleted file mode 100644
index 2ad759b..0000000
--- a/src/DoctrineStorage/TaskExecutionRepository.php
+++ /dev/null
@@ -1,94 +0,0 @@
-objectManager = $objectManager;
- $this->taskExecutionRepository = $taskExecutionRepository;
- }
-
- /**
- * {@inheritdoc}
- */
- public function store(TaskExecutionInterface $execution)
- {
- $this->objectManager->persist($execution);
-
- // FIXME move this flush to somewhere else (:
- $this->objectManager->flush();
-
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function save(TaskExecutionInterface $execution)
- {
- $this->objectManager->persist($execution);
-
- // FIXME move this flush to somewhere else (:
- $this->objectManager->flush();
-
- return $this;
- }
-
- /**
- * {@inheritdoc}
- */
- public function findByStartTime(TaskInterface $task, \DateTime $scheduleTime)
- {
- return $this->taskExecutionRepository->findByScheduledTime($task, $scheduleTime);
- }
-
- /**
- * {@inheritdoc}
- */
- public function findAll($limit = null)
- {
- return $this->taskExecutionRepository->findBy([], ['scheduleTime' => 'ASC'], $limit);
- }
-
- /**
- * {@inheritdoc}
- */
- public function findScheduled()
- {
- return $this->taskExecutionRepository->findScheduled(new \DateTime());
- }
-}
diff --git a/src/DoctrineStorage/TaskRepository.php b/src/DoctrineStorage/TaskRepository.php
deleted file mode 100644
index 7e55b9c..0000000
--- a/src/DoctrineStorage/TaskRepository.php
+++ /dev/null
@@ -1,83 +0,0 @@
-objectManager = $objectManager;
- $this->taskRepository = $taskRepository;
- }
-
- /**
- * {@inheritdoc}
- */
- public function store(TaskInterface $task)
- {
- $this->objectManager->persist($task);
-
- // FIXME move this flush to somewhere else (:
- $this->objectManager->flush();
- }
-
- /**
- * {@inheritdoc}
- */
- public function findAll($limit = null)
- {
- return $this->taskRepository->findBy([], null, $limit);
- }
-
- /**
- * {@inheritdoc}
- */
- public function findEndBeforeNow()
- {
- return $this->taskRepository->findEndBefore(new \DateTime());
- }
-
- /**
- * {@inheritdoc}
- */
- public function clear()
- {
- foreach ($this->taskRepository->findAll() as $task) {
- $this->objectManager->remove($task);
- }
-
- // FIXME move this flush to somewhere else (:
- $this->objectManager->flush();
- }
-}
diff --git a/src/Entity/TaskExecutionRepository.php b/src/Entity/TaskExecutionRepository.php
index 8e39c74..ae79d34 100644
--- a/src/Entity/TaskExecutionRepository.php
+++ b/src/Entity/TaskExecutionRepository.php
@@ -14,23 +14,64 @@
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Task\Execution\TaskExecutionInterface;
+use Task\Storage\TaskExecutionRepositoryInterface;
use Task\TaskInterface;
use Task\TaskStatus;
/**
* Repository for task-execution.
*/
-class TaskExecutionRepository extends EntityRepository
+class TaskExecutionRepository extends EntityRepository implements TaskExecutionRepositoryInterface
{
/**
- * Returns task-execution by task and scheduled-time.
- *
- * @param TaskInterface $task
- * @param \DateTime $scheduleTime
- *
- * @return TaskExecutionInterface
+ * {@inheritdoc}
*/
- public function findByScheduledTime(TaskInterface $task, \DateTime $scheduleTime)
+ public function create(TaskInterface $task, \DateTime $scheduleTime)
+ {
+ return new TaskExecution($task, $task->getHandlerClass(), $scheduleTime, $task->getWorkload());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function persist(TaskExecutionInterface $execution)
+ {
+ $this->_em->persist($execution);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function flush()
+ {
+ $this->_em->flush();
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function findAll($page = 1, $pageSize = null)
+ {
+ $query = $this->createQueryBuilder('e')
+ ->innerJoin('e.task', 't')
+ ->getQuery();
+
+ if ($pageSize) {
+ $query->setMaxResults($pageSize);
+ $query->setFirstResult(($page - 1) * $pageSize);
+ }
+
+ return $query->getResult();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function findByStartTime(TaskInterface $task, \DateTime $scheduleTime)
{
try {
return $this->createQueryBuilder('e')
@@ -47,11 +88,7 @@ public function findByScheduledTime(TaskInterface $task, \DateTime $scheduleTime
}
/**
- * Returns scheduled task-execution.
- *
- * @param \DateTime|null $dateTime
- *
- * @return TaskExecutionInterface[]
+ * {@inheritdoc}
*/
public function findScheduled(\DateTime $dateTime = null)
{
diff --git a/src/Entity/TaskRepository.php b/src/Entity/TaskRepository.php
index 7f670d1..8feacaf 100644
--- a/src/Entity/TaskRepository.php
+++ b/src/Entity/TaskRepository.php
@@ -12,13 +12,66 @@
namespace Task\TaskBundle\Entity;
use Doctrine\ORM\EntityRepository;
+use Task\Storage\TaskRepositoryInterface;
use Task\TaskInterface;
/**
* Repository for task.
*/
-class TaskRepository extends EntityRepository
+class TaskRepository extends EntityRepository implements TaskRepositoryInterface
{
+ /**
+ * {@inheritdoc}
+ */
+ public function create($handlerClass, $workload = null)
+ {
+ return new Task($handlerClass, $workload);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function persist(TaskInterface $task)
+ {
+ $this->_em->persist($task);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function flush()
+ {
+ $this->_em->flush();
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function findAll($page = 1, $pageSize = null)
+ {
+ $query = $this->createQueryBuilder('t')
+ ->getQuery();
+
+ if ($pageSize) {
+ $query->setMaxResults($pageSize);
+ $query->setFirstResult(($page - 1) * $pageSize);
+ }
+
+ return $query->getResult();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function findEndBeforeNow()
+ {
+ return $this->findEndBefore(new \DateTime());
+ }
+
/**
* Returns task where last-execution is before given date-time.
*
@@ -29,7 +82,7 @@ class TaskRepository extends EntityRepository
public function findEndBefore(\DateTime $dateTime)
{
return $this->createQueryBuilder('t')
- ->where('t.lastExecution IS NULL OR t.lastExecution >= :dateTime')
+ ->where('t.lastExecution IS NULL OR t.lastExecution > :dateTime')
->setParameter('dateTime', $dateTime)
->getQuery()
->getResult();
diff --git a/src/Factory.php b/src/Factory.php
deleted file mode 100644
index e4af578..0000000
--- a/src/Factory.php
+++ /dev/null
@@ -1,38 +0,0 @@
-getHandlerClass(), $scheduleTime, $task->getWorkload());
- }
-}
diff --git a/src/Handler/TaskHandlerFactory.php b/src/Handler/TaskHandlerFactory.php
index 9cd1040..d49061f 100644
--- a/src/Handler/TaskHandlerFactory.php
+++ b/src/Handler/TaskHandlerFactory.php
@@ -11,8 +11,8 @@
namespace Task\TaskBundle\Handler;
-use Symfony\Component\CssSelector\Parser\Handler\HandlerInterface;
use Task\Handler\TaskHandlerFactoryInterface;
+use Task\Handler\TaskHandlerInterface;
use Task\Handler\TaskHandlerNotExistsException;
/**
@@ -21,7 +21,7 @@
class TaskHandlerFactory implements TaskHandlerFactoryInterface
{
/**
- * @var HandlerInterface[]
+ * @var TaskHandlerInterface[]
*/
private $handler = [];
diff --git a/src/Resources/config/command.xml b/src/Resources/config/command.xml
index dd863c4..69c6e13 100644
--- a/src/Resources/config/command.xml
+++ b/src/Resources/config/command.xml
@@ -11,7 +11,7 @@
-
+
task:run:handler
diff --git a/src/Resources/config/scheduler.xml b/src/Resources/config/scheduler.xml
index 34540a1..9ccad0f 100644
--- a/src/Resources/config/scheduler.xml
+++ b/src/Resources/config/scheduler.xml
@@ -3,10 +3,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
+
-
-
+
+
diff --git a/src/Resources/config/storage/doctrine.xml b/src/Resources/config/storage/doctrine.xml
index bf46469..fb22e29 100644
--- a/src/Resources/config/storage/doctrine.xml
+++ b/src/Resources/config/storage/doctrine.xml
@@ -8,20 +8,13 @@
TaskBundle:Task
+
-
-
-
-
TaskBundle:TaskExecution
-
-
-
-
-
+
diff --git a/src/TaskBundle.php b/src/TaskBundle.php
index a32c821..36805a5 100644
--- a/src/TaskBundle.php
+++ b/src/TaskBundle.php
@@ -8,8 +8,6 @@
/**
* Integrates php-task into symfony.
- *
- * @author @wachterjohannes
*/
class TaskBundle extends Bundle
{
diff --git a/tests/Functional/BaseCommandTestCase.php b/tests/Functional/BaseCommandTestCase.php
new file mode 100644
index 0000000..3d7b7e7
--- /dev/null
+++ b/tests/Functional/BaseCommandTestCase.php
@@ -0,0 +1,175 @@
+taskRunner = self::$kernel->getContainer()->get('task.runner');
+ $this->taskScheduler = self::$kernel->getContainer()->get('task.scheduler');
+ $this->taskRepository = self::$kernel->getContainer()->get('task.storage.task');
+ $this->taskExecutionRepository = self::$kernel->getContainer()->get('task.storage.task_execution');
+
+ $command = $this->getCommand();
+
+ $this->application = new Application(self::$kernel);
+ $this->application->add($command);
+
+ $this->command = $this->application->find($command->getName());
+ $this->commandTester = new CommandTester($this->command);
+
+ $this->purgeDatabase();
+ }
+
+ /**
+ * Create new task.
+ *
+ * @param string $workload
+ * @param CronExpression $cronExpression
+ * @param string $handlerClass
+ *
+ * @return TaskInterface
+ */
+ protected function createTask($workload, CronExpression $cronExpression = null, $handlerClass = TestHandler::class)
+ {
+ $task = $this->taskRepository->create($handlerClass, $workload);
+ if ($cronExpression) {
+ $task->setInterval($cronExpression, new \DateTime(), new \DateTime('+1 year'));
+ }
+ $this->taskRepository->persist($task);
+ $this->taskRepository->flush();
+
+ return $task;
+ }
+
+ /**
+ * Create task-execution.
+ *
+ * @param TaskInterface $task
+ * @param \DateTime $scheduleTime
+ * @param string $status
+ *
+ * @return TaskExecutionInterface
+ */
+ protected function createTaskExecution(TaskInterface $task, \DateTime $scheduleTime, $status = TaskStatus::PLANNED)
+ {
+ $execution = $this->taskExecutionRepository->create($task, $scheduleTime);
+ $execution->setStatus($status);
+ $this->taskExecutionRepository->persist($execution);
+ $this->taskExecutionRepository->flush();
+
+ return $execution;
+ }
+
+ /**
+ * Purge the Doctrine ORM database.
+ */
+ protected function purgeDatabase()
+ {
+ if (!self::$kernel->getContainer()->has('doctrine')) {
+ return;
+ }
+
+ $manager = $this->getEntityManager();
+ $connection = $manager->getConnection();
+
+ if ($connection->getDriver() instanceof Driver) {
+ $connection->executeUpdate('SET foreign_key_checks = 0;');
+ }
+
+ $purger = new ORMPurger();
+ $executor = new ORMExecutor($manager, $purger);
+ $referenceRepository = new ProxyReferenceRepository($manager);
+ $executor->setReferenceRepository($referenceRepository);
+ $executor->purge();
+
+ if ($connection->getDriver() instanceof Driver) {
+ $connection->executeUpdate('SET foreign_key_checks = 1;');
+ }
+ }
+
+ /**
+ * Returns entity-manager.
+ *
+ * @return EntityManagerInterface
+ */
+ protected function getEntityManager()
+ {
+ return self::$kernel->getContainer()->get('doctrine')->getManager();
+ }
+
+ /**
+ * Returns command.
+ *
+ * @return Command
+ */
+ abstract protected function getCommand();
+}
diff --git a/tests/Functional/BootstrapTest.php b/tests/Functional/BootstrapTest.php
index 1dab5c7..7e64c74 100644
--- a/tests/Functional/BootstrapTest.php
+++ b/tests/Functional/BootstrapTest.php
@@ -9,15 +9,18 @@
* with this source code in the file LICENSE.
*/
-namespace Functional;
+namespace Task\TaskBundle\Tests\Functional;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
-use Task\Scheduler\SchedulerInterface;
+use Task\Scheduler\TaskSchedulerInterface;
use Task\Storage\ArrayStorage\ArrayTaskExecutionRepository;
use Task\Storage\ArrayStorage\ArrayTaskRepository;
-use Task\TaskBundle\DoctrineStorage\TaskExecutionRepository;
-use Task\TaskBundle\DoctrineStorage\TaskRepository;
+use Task\TaskBundle\Entity\TaskExecutionRepository;
+use Task\TaskBundle\Entity\TaskRepository;
+/**
+ * Tests the service definitions.
+ */
class BootstrapTest extends KernelTestCase
{
public function testBootstrap()
@@ -28,7 +31,7 @@ public function testBootstrap()
$taskRepository = self::$kernel->getContainer()->get('task.storage.task');
$taskExecutionRepository = self::$kernel->getContainer()->get('task.storage.task_execution');
- $this->assertInstanceOf(SchedulerInterface::class, $scheduler);
+ $this->assertInstanceOf(TaskSchedulerInterface::class, $scheduler);
switch (self::$kernel->getContainer()->getParameter('kernel.storage')) {
case 'array':
diff --git a/tests/Functional/Command/DebugTasksCommandTest.php b/tests/Functional/Command/DebugTasksCommandTest.php
new file mode 100644
index 0000000..4119b92
--- /dev/null
+++ b/tests/Functional/Command/DebugTasksCommandTest.php
@@ -0,0 +1,113 @@
+createTask('Test workload 1');
+
+ /** @var TaskExecutionInterface[] $executions */
+ $executions = [
+ $this->createTaskExecution($task, new \DateTime('-1 hour'), TaskStatus::COMPLETE),
+ $this->createTaskExecution($task, new \DateTime('-2 hour'), TaskStatus::COMPLETE),
+ ];
+
+ $executions[0]->setResult(strrev($executions[0]->getWorkload()));
+ $executions[0]->setDuration(0.1);
+ $executions[1]->setResult(strrev($executions[1]->getWorkload()));
+ $executions[1]->setDuration(0.0001);
+
+ $this->taskExecutionRepository->flush();
+
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertContains($executions[0]->getUuid(), $output);
+ $this->assertContains($executions[1]->getUuid(), $output);
+ $this->assertContains('100000ms', $output);
+ $this->assertContains('100ms', $output);
+ $this->assertContains('completed', $output);
+ }
+
+ public function testExecutePaginated()
+ {
+ $task = $this->createTask('Test workload 1');
+
+ /** @var TaskExecutionInterface[] $executions */
+ $executions = [
+ $this->createTaskExecution($task, new \DateTime('-1 hour')),
+ $this->createTaskExecution($task, new \DateTime('-2 hour')),
+ $this->createTaskExecution($task, new \DateTime('+1 hour')),
+ ];
+
+ $this->taskExecutionRepository->flush();
+
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ '--page-size' => 2,
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertContains($executions[0]->getUuid(), $output);
+ $this->assertContains($executions[1]->getUuid(), $output);
+ $this->assertNotContains($executions[2]->getUuid(), $output);
+
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ '--page' => 2,
+ '--page-size' => 2,
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertNotContains($executions[0]->getUuid(), $output);
+ $this->assertNotContains($executions[1]->getUuid(), $output);
+ $this->assertContains($executions[2]->getUuid(), $output);
+
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ '--page' => 3,
+ '--page-size' => 2,
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertNotContains($executions[0]->getUuid(), $output);
+ $this->assertNotContains($executions[1]->getUuid(), $output);
+ $this->assertNotContains($executions[2]->getUuid(), $output);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getCommand()
+ {
+ return self::$kernel->getContainer()->get('task.command.debug_tasks');
+ }
+}
diff --git a/tests/Functional/Command/RunCommandTest.php b/tests/Functional/Command/RunCommandTest.php
new file mode 100644
index 0000000..9f6daab
--- /dev/null
+++ b/tests/Functional/Command/RunCommandTest.php
@@ -0,0 +1,121 @@
+createTask('Test workload 1');
+ $laterTask = $this->createTask('Test workload 2');
+ $intervalTask = $this->createTask('Test workload 3', CronExpression::factory('@daily'));
+
+ /** @var TaskExecutionInterface[] $executions */
+ $executions = [
+ $this->createTaskExecution($singleTask, new \DateTime('-1 hour')),
+ $this->createTaskExecution($laterTask, new \DateTime('+1 hour')),
+ $this->createTaskExecution($intervalTask, new \DateTime('-2 hour')),
+ ];
+
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ ]
+ );
+
+ $this->assertEquals(TaskStatus::COMPLETE, $executions[0]->getStatus());
+ $this->assertEquals(strrev('Test workload 1'), $executions[0]->getResult());
+ $this->assertGreaterThan(0, $executions[0]->getDuration());
+ $this->assertGreaterThanOrEqual($executions[0]->getStartTime(), $executions[0]->getEndTime());
+
+ $this->assertEquals(TaskStatus::PLANNED, $executions[1]->getStatus());
+ $this->assertNull($executions[1]->getResult());
+ $this->assertNull($executions[1]->getDuration());
+ $this->assertNull($executions[1]->getStartTime());
+ $this->assertNull($executions[1]->getEndTime());
+
+ $this->assertEquals(TaskStatus::COMPLETE, $executions[2]->getStatus());
+ $this->assertEquals(strrev('Test workload 3'), $executions[2]->getResult());
+ $this->assertGreaterThan(0, $executions[2]->getDuration());
+ $this->assertGreaterThanOrEqual($executions[2]->getStartTime(), $executions[2]->getEndTime());
+
+ $result = $this->taskExecutionRepository->findAll(2, 3);
+ $this->assertCount(1, $result);
+
+ $this->assertEquals($intervalTask, $result[0]->getTask());
+ $this->assertEquals(TaskStatus::PLANNED, $result[0]->getStatus());
+ $this->assertEquals(TestHandler::class, $result[0]->getHandlerClass());
+ $this->assertEquals('Test workload 3', $result[0]->getWorkload());
+ }
+
+ public function testExecuteWithFail()
+ {
+ $singleTask = $this->createTask('Test workload 1', null, FailTestHandler::class);
+ $laterTask = $this->createTask('Test workload 2', null, FailTestHandler::class);
+ $intervalTask = $this->createTask('Test workload 3', CronExpression::factory('@daily'), FailTestHandler::class);
+
+ /** @var TaskExecutionInterface[] $executions */
+ $executions = [
+ $this->createTaskExecution($singleTask, new \DateTime('-1 hour')),
+ $this->createTaskExecution($laterTask, new \DateTime('+1 hour')),
+ $this->createTaskExecution($intervalTask, new \DateTime('-2 hour')),
+ ];
+
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ ]
+ );
+
+ $this->assertEquals(TaskStatus::FAILED, $executions[0]->getStatus());
+ $this->assertNull($executions[0]->getResult());
+ $this->assertGreaterThan(0, $executions[0]->getDuration());
+ $this->assertGreaterThanOrEqual($executions[0]->getStartTime(), $executions[0]->getEndTime());
+
+ $this->assertEquals(TaskStatus::PLANNED, $executions[1]->getStatus());
+ $this->assertNull($executions[1]->getResult());
+ $this->assertNull($executions[1]->getDuration());
+ $this->assertNull($executions[1]->getStartTime());
+ $this->assertNull($executions[1]->getEndTime());
+
+ $this->assertEquals(TaskStatus::FAILED, $executions[2]->getStatus());
+ $this->assertNull($executions[2]->getResult());
+ $this->assertGreaterThan(0, $executions[2]->getDuration());
+ $this->assertGreaterThanOrEqual($executions[2]->getStartTime(), $executions[2]->getEndTime());
+
+ $result = $this->taskExecutionRepository->findAll(2, 3);
+ $this->assertCount(1, $result);
+
+ $this->assertEquals($intervalTask, $result[0]->getTask());
+ $this->assertEquals(TaskStatus::PLANNED, $result[0]->getStatus());
+ $this->assertEquals(FailTestHandler::class, $result[0]->getHandlerClass());
+ $this->assertEquals('Test workload 3', $result[0]->getWorkload());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getCommand()
+ {
+ return self::$kernel->getContainer()->get('task.command.run');
+ }
+}
diff --git a/tests/Functional/Command/RunHandlerCommandTest.php b/tests/Functional/Command/RunHandlerCommandTest.php
new file mode 100644
index 0000000..ddc9f7b
--- /dev/null
+++ b/tests/Functional/Command/RunHandlerCommandTest.php
@@ -0,0 +1,77 @@
+commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ ],
+ [
+ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE,
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertContains('No workload.', $output);
+ }
+
+ public function testExecuteWithWorkload()
+ {
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ 'workload' => 'Test workload 1',
+ ],
+ [
+ 'verbosity' => OutputInterface::VERBOSITY_VERBOSE,
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertContains(strrev('Test workload 1'), $output);
+ }
+
+ public function testExecuteWithWorkloadNoVerbosity()
+ {
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ 'workload' => 'Test workload 1',
+ ]
+ );
+
+ $output = $this->commandTester->getDisplay();
+ $this->assertEquals('', $output);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getCommand()
+ {
+ return self::$kernel->getContainer()->get('task.command.run_handler');
+ }
+}
diff --git a/tests/Functional/Command/ScheduleTaskCommandTest.php b/tests/Functional/Command/ScheduleTaskCommandTest.php
new file mode 100644
index 0000000..b7df0ea
--- /dev/null
+++ b/tests/Functional/Command/ScheduleTaskCommandTest.php
@@ -0,0 +1,132 @@
+commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ ]
+ );
+
+ $tasks = $this->taskRepository->findAll();
+ $this->assertCount(1, $tasks);
+
+ $this->assertEquals(TestHandler::class, $tasks[0]->getHandlerClass());
+
+ $executions = $this->taskExecutionRepository->findAll();
+ $this->assertCount(1, $executions);
+
+ $this->assertEquals(TestHandler::class, $executions[0]->getHandlerClass());
+ }
+
+ public function testExecuteWithWorkload()
+ {
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ 'workload' => 'Test workload 1',
+ ]
+ );
+
+ $tasks = $this->taskRepository->findAll();
+ $this->assertCount(1, $tasks);
+
+ $this->assertEquals(TestHandler::class, $tasks[0]->getHandlerClass());
+ $this->assertEquals('Test workload 1', $tasks[0]->getWorkload());
+ }
+
+ public function testExecuteWithWorkloadAndInterval()
+ {
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ 'workload' => 'Test workload 1',
+ '--cron-expression' => '0 * * * *',
+ ]
+ );
+
+ $tasks = $this->taskRepository->findAll();
+ $this->assertCount(1, $tasks);
+
+ $this->assertEquals(TestHandler::class, $tasks[0]->getHandlerClass());
+ $this->assertEquals('Test workload 1', $tasks[0]->getWorkload());
+ $this->assertEquals('0 * * * *', $tasks[0]->getInterval());
+ }
+
+ public function testExecuteWithWorkloadAndIntervalAndEndDate()
+ {
+ $date = new \DateTime('+1 day');
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ 'workload' => 'Test workload 1',
+ '--cron-expression' => '0 * * * *',
+ '--end-date' => $date->format(\DateTime::RFC3339),
+ ]
+ );
+
+ $tasks = $this->taskRepository->findAll();
+ $this->assertCount(1, $tasks);
+
+ $this->assertEquals(TestHandler::class, $tasks[0]->getHandlerClass());
+ $this->assertEquals('Test workload 1', $tasks[0]->getWorkload());
+ $this->assertEquals('0 * * * *', $tasks[0]->getInterval());
+ $this->assertEquals($date, $tasks[0]->getLastExecution());
+ }
+
+ public function testExecuteWithExecutionDate()
+ {
+ $date = new \DateTime('+1 day');
+ $this->commandTester->execute(
+ [
+ 'command' => $this->command->getName(),
+ 'handlerClass' => TestHandler::class,
+ 'workload' => 'Test workload 1',
+ '--execution-date' => '+1 day',
+ ]
+ );
+
+ $tasks = $this->taskRepository->findAll();
+ $this->assertCount(1, $tasks);
+
+ $this->assertEquals(TestHandler::class, $tasks[0]->getHandlerClass());
+ $this->assertEquals($date, $tasks[0]->getFirstExecution());
+
+ $executions = $this->taskExecutionRepository->findAll();
+ $this->assertCount(1, $executions);
+
+ $this->assertEquals(TestHandler::class, $executions[0]->getHandlerClass());
+ $this->assertEquals($date, $executions[0]->getScheduleTime());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getCommand()
+ {
+ return self::$kernel->getContainer()->get('task.command.schedule_task');
+ }
+}
diff --git a/tests/Functional/FailTestHandler.php b/tests/Functional/FailTestHandler.php
new file mode 100644
index 0000000..05f373f
--- /dev/null
+++ b/tests/Functional/FailTestHandler.php
@@ -0,0 +1,28 @@
+taskHandlerFactory = self::$kernel->getContainer()->get('task.handler.factory');
}
- public function testRun()
+ public function testCreate()
{
- $this->assertInstanceOf(\TestHandler::class, $this->taskHandlerFactory->create(\TestHandler::class));
+ $this->assertInstanceOf(TestHandler::class, $this->taskHandlerFactory->create(TestHandler::class));
+ }
+
+ public function testCreateNotExists()
+ {
+ $this->setExpectedException(TaskHandlerNotExistsException::class);
+
+ $this->taskHandlerFactory->create(\stdClass::class);
}
}
diff --git a/tests/Functional/TestHandler.php b/tests/Functional/TestHandler.php
new file mode 100644
index 0000000..399259e
--- /dev/null
+++ b/tests/Functional/TestHandler.php
@@ -0,0 +1,32 @@
+prophesize(ContainerBuilder::class);
+
+ $container->has(HandlerCompilerPass::REGISTRY_ID)->willReturn(true);
+ $container->findTaggedServiceIds(HandlerCompilerPass::HANDLER_TAG)->willReturn(
+ ['service1' => [], 'service2' => []]
+ );
+ $container->getDefinition('service1')->willReturn(new Definition(\stdClass::class));
+ $container->getDefinition('service2')->willReturn(new Definition(self::class));
+
+ $serviceDefinition = $this->prophesize(Definition::class);
+ $container->findDefinition(HandlerCompilerPass::REGISTRY_ID)->willReturn($serviceDefinition);
+
+ $compilerPass = new HandlerCompilerPass();
+ $compilerPass->process($container->reveal());
+
+ $serviceDefinition->replaceArgument(
+ 0,
+ [\stdClass::class => new Reference('service1'), self::class => new Reference('service2')]
+ )->shouldBeCalled();
+ }
+
+ public function testProcessNoTaggedService()
+ {
+ $container = $this->prophesize(ContainerBuilder::class);
+
+ $container->has(HandlerCompilerPass::REGISTRY_ID)->willReturn(true);
+ $container->findTaggedServiceIds(HandlerCompilerPass::HANDLER_TAG)->willReturn([]);
+
+ $serviceDefinition = $this->prophesize(Definition::class);
+ $container->findDefinition(HandlerCompilerPass::REGISTRY_ID)->willReturn($serviceDefinition);
+
+ $compilerPass = new HandlerCompilerPass();
+ $compilerPass->process($container->reveal());
+
+ $serviceDefinition->replaceArgument(0, [])->shouldBeCalled();
+ }
+}
diff --git a/tests/Unit/EventListener/RunListenerTest.php b/tests/Unit/EventListener/RunListenerTest.php
index f3938b4..656e95f 100644
--- a/tests/Unit/EventListener/RunListenerTest.php
+++ b/tests/Unit/EventListener/RunListenerTest.php
@@ -9,12 +9,15 @@
* with this source code in the file LICENSE.
*/
-namespace Unit\EventListener;
+namespace Task\TaskBundle\Tests\Unit\EventListener;
use Symfony\Component\EventDispatcher\Event;
use Task\Runner\TaskRunnerInterface;
use Task\TaskBundle\EventListener\RunListener;
+/**
+ * Tests for class RunListener.
+ */
class RunListenerTest extends \PHPUnit_Framework_TestCase
{
public function testRun()
diff --git a/tests/Unit/Handler/TaskHandlerFactoryTest.php b/tests/Unit/Handler/TaskHandlerFactoryTest.php
new file mode 100644
index 0000000..c6b2089
--- /dev/null
+++ b/tests/Unit/Handler/TaskHandlerFactoryTest.php
@@ -0,0 +1,48 @@
+ $handler]);
+
+ $this->assertEquals($handler, $taskHandlerFactory->create(TestHandler::class));
+ }
+
+ public function testCreateNotExists()
+ {
+ $this->setExpectedException(TaskHandlerNotExistsException::class);
+
+ $taskHandlerFactory = new TaskHandlerFactory([TestHandler::class => new TestHandler()]);
+
+ $taskHandlerFactory->create(\stdClass::class);
+ }
+
+ public function testCreateNoHandler()
+ {
+ $this->setExpectedException(TaskHandlerNotExistsException::class);
+
+ $taskHandlerFactory = new TaskHandlerFactory([]);
+
+ $taskHandlerFactory->create(\stdClass::class);
+ }
+}
diff --git a/tests/app/TestKernel.php b/tests/app/TestKernel.php
index ab35657..2d49551 100644
--- a/tests/app/TestKernel.php
+++ b/tests/app/TestKernel.php
@@ -84,14 +84,3 @@ protected function initializeContainer()
}
}
}
-
-class TestHandler implements \Task\Handler\TaskHandlerInterface
-{
- /**
- * {@inheritdoc}
- */
- public function handle($workload)
- {
- return strrev($workload);
- }
-}
diff --git a/tests/app/config/services.xml b/tests/app/config/services.xml
index 63d1716..7af7798 100644
--- a/tests/app/config/services.xml
+++ b/tests/app/config/services.xml
@@ -3,7 +3,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
+
+
+
+