Release of RC1 #7
|
@ -15,14 +15,14 @@ steps:
|
|||
- name: basetest
|
||||
image: phpunit:7.3
|
||||
commands:
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --coverage-text
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --coverage-php test/temp/covbase.cov
|
||||
environment:
|
||||
TASKSTORAGE_TYPE: DummyTaskStorage
|
||||
|
||||
- name: redistest
|
||||
image: phpunit:7.3
|
||||
commands:
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --coverage-text
|
||||
- vendor/bin/phpunit -c test/phpunit.xml --coverage-php test/temp/covredis.cov
|
||||
environment:
|
||||
SUPERVISOR_TYPE: ParallelSuperVisor
|
||||
TASKSTORAGE_TYPE: RedisTaskStorage
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9",
|
||||
"phpunit/phpcov": "^7",
|
||||
"fuzeworks/mvcr": "~1.2.0"
|
||||
},
|
||||
"config": {
|
||||
|
|
|
@ -36,9 +36,25 @@
|
|||
|
||||
namespace FuzeWorks\Async;
|
||||
|
||||
/**
|
||||
* Interface Executor
|
||||
*
|
||||
*
|
||||
* @todo Implement ListRunningTasks
|
||||
* @package FuzeWorks\Async
|
||||
*/
|
||||
interface Executor
|
||||
{
|
||||
|
||||
/**
|
||||
* Executor constructor.
|
||||
*
|
||||
* Parameters are a unique array which can differ for each Executor.
|
||||
*
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct(array $parameters);
|
||||
|
||||
// Control methods
|
||||
/**
|
||||
* Start executing a task.
|
||||
|
@ -57,16 +73,12 @@ interface Executor
|
|||
* Returns the task since it makes modifications. Has to be modified in TaskStorage by SuperVisor.
|
||||
*
|
||||
* @param Task $task
|
||||
* @return Task
|
||||
* @param bool $harshly True to KILL a process
|
||||
* @return Task|null Returns modified Task on success, or null if no PID is found
|
||||
*/
|
||||
public function stopTask(Task $task): Task;
|
||||
public function stopTask(Task $task, bool $harshly = false): ?Task;
|
||||
|
||||
// Task info
|
||||
public function getTaskRunning(Task $task): bool;
|
||||
public function getTaskStats(Task $task): ?array;
|
||||
public function getTaskExitCode(Task $task): ?int;
|
||||
|
||||
// All tasks info
|
||||
public function getRunningTasks(): array;
|
||||
|
||||
}
|
|
@ -56,22 +56,21 @@ class ShellExecutor implements Executor
|
|||
* @param array $parameters
|
||||
* @throws TasksException
|
||||
*/
|
||||
public function __construct(string $bootstrapFile, array $parameters)
|
||||
public function __construct(array $parameters)
|
||||
{
|
||||
// Fetch workerFile
|
||||
$workerFile = $parameters['workerFile'];
|
||||
$this->worker = $parameters['workerFile'];
|
||||
if (!file_exists($this->worker))
|
||||
throw new TasksException("Could not construct ShellExecutor. ShellWorker script does not exist.");
|
||||
|
||||
// First determine the PHP binary
|
||||
$this->binary = PHP_BINDIR . DS . 'php';
|
||||
$this->bootstrapFile = $bootstrapFile;
|
||||
|
||||
if (!file_exists($workerFile))
|
||||
throw new TasksException("Could not construct ShellExecutor. ShellWorker script does not exist.");
|
||||
|
||||
$this->worker = $workerFile;
|
||||
$this->bootstrapFile = $parameters['bootstrapFile'];
|
||||
if (!file_exists($this->bootstrapFile))
|
||||
throw new TasksException("Could not construct ShellExecutor. No bootstrap file found.");
|
||||
}
|
||||
|
||||
private function shellExec($format, array $parameters = [])
|
||||
protected function shellExec($format, array $parameters = [])
|
||||
{
|
||||
$parameters = array_map("escapeshellarg", $parameters);
|
||||
array_unshift($parameters, $format);
|
||||
|
@ -88,15 +87,28 @@ class ShellExecutor implements Executor
|
|||
// Then execute the command using the base64_encoded string of the taskID
|
||||
$output = $this->shellExec($commandString, [base64_encode($task->getId())]);
|
||||
$pid = intval($output[0]);
|
||||
$task->setProcess(new Process($pid));
|
||||
$task->addAttribute('pid', $pid);
|
||||
|
||||
// And finally return the task
|
||||
return $task;
|
||||
}
|
||||
|
||||
public function stopTask(Task $task): Task
|
||||
public function stopTask(Task $task, bool $harshly = false): ?Task
|
||||
{
|
||||
// TODO: Implement stopTask() method.
|
||||
// First prepare the kill command
|
||||
$commandString = "kill " . ($harshly ? '-9 ' : '') . "%s";
|
||||
|
||||
// Fetch the process ID from the task
|
||||
$pid = $task->attribute('pid');
|
||||
if (is_null($pid))
|
||||
return null;
|
||||
|
||||
// Then execute the command
|
||||
$this->shellExec($commandString, [$pid]);
|
||||
if (!$this->getTaskRunning($task))
|
||||
$task->removeAttribute('pid');
|
||||
|
||||
return $task;
|
||||
}
|
||||
|
||||
public function getTaskRunning(Task $task): bool
|
||||
|
@ -111,13 +123,10 @@ class ShellExecutor implements Executor
|
|||
$commandString = "ps -o pid,%%cpu,%%mem,state,start -p %s | sed 1d";
|
||||
|
||||
// First we must determine what process is used.
|
||||
$process = $task->getProcess();
|
||||
if (is_null($process))
|
||||
$pid = $task->attribute('pid');
|
||||
if (is_null($pid))
|
||||
return null;
|
||||
|
||||
// Then using that process we determine the ProcessID
|
||||
$pid = $process->getPid();
|
||||
|
||||
// And we execute the commandString to fetch info on the process
|
||||
$output = $this->shellExec($commandString, [$pid]);
|
||||
|
||||
|
@ -141,16 +150,6 @@ class ShellExecutor implements Executor
|
|||
return null;
|
||||
|
||||
// Finally, return the Task information
|
||||
return $parts;
|
||||
}
|
||||
|
||||
public function getTaskExitCode(Task $task): int
|
||||
{
|
||||
// TODO: Implement getTaskExitCode() method.
|
||||
}
|
||||
|
||||
public function getRunningTasks(): array
|
||||
{
|
||||
// TODO: Implement getRunningTasks() method.
|
||||
return ['pid' => (int) $parts[0], 'cpu' => (float) $parts[1], 'mem' => (float) $parts[2], 'state' => $parts[3], 'start' => $parts[4]];
|
||||
}
|
||||
}
|
|
@ -111,6 +111,7 @@ class ParallelSuperVisor implements SuperVisor
|
|||
// CANCELLED/COMPLETED: remove the task if requested to do so
|
||||
elseif ($task->getStatus() === Task::COMPLETED || $task->getStatus() === Task::CANCELLED)
|
||||
{
|
||||
// @todo Remove old tasks automatically
|
||||
}
|
||||
|
||||
// RUNNING: check if task is still running. If not, set result based on output
|
||||
|
@ -216,7 +217,9 @@ class ParallelSuperVisor implements SuperVisor
|
|||
$task->addRetry();
|
||||
$task = $this->executor->startTask($task, true);
|
||||
}
|
||||
elseif ($settings['maxRetries'] <= $task->getRetries())
|
||||
elseif ($settings['retryOnFail'] === true && $settings['retryPostFailures'] === true && $settings['maxRetries'] <= $task->getRetries())
|
||||
$task->setStatus(Task::CANCELLED);
|
||||
else
|
||||
$task->setStatus(Task::CANCELLED);
|
||||
}
|
||||
// @todo Retry after $max_Time
|
||||
|
|
|
@ -338,6 +338,20 @@ class Task
|
|||
$this->attributes[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an attribute from a Task
|
||||
*
|
||||
* @param string $key
|
||||
* @throws TasksException
|
||||
*/
|
||||
public function removeAttribute(string $key)
|
||||
{
|
||||
if (!isset($this->attributes[$key]))
|
||||
throw new TasksException("Could not remove Task '$this->taskId' attribute '$key'. Not found.");
|
||||
|
||||
unset($this->attributes[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the output of this task execution
|
||||
*
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks Async Library
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2020, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 1.0.0
|
||||
*
|
||||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
use FuzeWorks\Async\Executors\ShellExecutor;
|
||||
use FuzeWorks\Async\Task;
|
||||
use FuzeWorks\Async\Tasks;
|
||||
use FuzeWorks\Async\TasksException;
|
||||
use FuzeWorks\Async\TaskStorage;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class ShellExecutorTest
|
||||
*
|
||||
* @coversDefaultClass \FuzeWorks\Async\Executors\ShellExecutor
|
||||
*/
|
||||
class ShellExecutorTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var ShellExecutor
|
||||
*/
|
||||
private $executor;
|
||||
|
||||
/**
|
||||
* @var TaskStorage
|
||||
*/
|
||||
private $taskStorage;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
// Load the TaskStorage so temporary tasks can be stored
|
||||
// Tasks shall NOT be reset between individual tests automatically
|
||||
$tasks = new Tasks();
|
||||
$this->taskStorage = $tasks->getTaskStorage();
|
||||
$this->taskStorage->reset();
|
||||
|
||||
// And load the ShellExecutor using the execution settings
|
||||
$this->executor = new ShellExecutor([
|
||||
'bootstrapFile' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'bootstrap.php',
|
||||
'workerFile' => dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'worker'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testClass()
|
||||
{
|
||||
$this->assertInstanceOf('FuzeWorks\Async\Executors\ShellExecutor', $this->executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testClass
|
||||
*/
|
||||
public function testNoWorkerFile()
|
||||
{
|
||||
$this->expectException(TasksException::class);
|
||||
new ShellExecutor(['bootstrapFile' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'bootstrap.php']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testClass
|
||||
*/
|
||||
public function testNoBoostrapFile()
|
||||
{
|
||||
$this->expectException(TasksException::class);
|
||||
new ShellExecutor(['workerFile' => dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'worker']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testClass
|
||||
*/
|
||||
public function testInvalidWorkerFile()
|
||||
{
|
||||
$this->expectException(TasksException::class);
|
||||
new ShellExecutor([
|
||||
'bootstrapFile' => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'bootstrap.php',
|
||||
'workerFile' => 'not_found'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testClass
|
||||
*/
|
||||
public function testInvalidBootstrapFile()
|
||||
{
|
||||
$this->expectException(TasksException::class);
|
||||
new ShellExecutor([
|
||||
'bootstrapFile' => 'not_found',
|
||||
'workerFile' => dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'worker'
|
||||
]);
|
||||
}
|
||||
|
||||
/* ---------------------------------- Writing and reading tasks ----------------------- */
|
||||
|
||||
/**
|
||||
* @depends testClass
|
||||
* @covers ::startTask
|
||||
* @covers ::getTaskRunning
|
||||
*/
|
||||
public function testStartAndReadTasks()
|
||||
{
|
||||
// First we create a dummy task
|
||||
$dummyTask = new Task('testStartAndReadTasks', 'Mock\Handlers\TestStartAndReadTasksHandler');
|
||||
|
||||
// Then we write this task to the TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Assert that no PID exists yet
|
||||
$this->assertNull($dummyTask->attribute('pid'));
|
||||
|
||||
// Then we fire the task
|
||||
$task = $this->executor->startTask($dummyTask);
|
||||
|
||||
// Assert that the output is the same
|
||||
$this->assertSame($dummyTask, $task);
|
||||
|
||||
// Also assert that a PID has been added
|
||||
$this->assertIsInt($task->attribute('pid'));
|
||||
|
||||
// Also assert that the task is currently running
|
||||
$this->assertTrue($this->executor->getTaskRunning($task));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStartAndReadTasks
|
||||
*/
|
||||
public function testGetStats()
|
||||
{
|
||||
// First we create a dummy task, using the previous handler since nothing changes
|
||||
$dummyTask = new Task('testGetStats', 'Mock\Handlers\TestStartAndReadTasksHandler');
|
||||
|
||||
// Then we write this task to the TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Then we start the task
|
||||
$dummyTask = $this->executor->startTask($dummyTask);
|
||||
|
||||
// And we fetch some task statistics
|
||||
$stats = $this->executor->getTaskStats($dummyTask);
|
||||
|
||||
// Assert some assumptions
|
||||
$this->assertNotNull($stats);
|
||||
$this->assertIsInt($stats['pid']);
|
||||
$this->assertIsFloat($stats['cpu']);
|
||||
$this->assertIsFloat($stats['mem']);
|
||||
$this->assertIsString($stats['state']);
|
||||
$this->assertIsString($stats['start']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testGetStats
|
||||
*/
|
||||
public function testGetStatsNotExist()
|
||||
{
|
||||
// First we create a dummy task, using the previous handler since nothing changes
|
||||
$dummyTask = new Task('testGetStatsNotExist', 'none');
|
||||
|
||||
// And add a fake PID, since otherwise it will immediately fail
|
||||
$dummyTask->addAttribute('pid', 1005);
|
||||
|
||||
// Then we fetch the process details
|
||||
$this->assertNull($this->executor->getTaskStats($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStartAndReadTasks
|
||||
*/
|
||||
public function testStopTask()
|
||||
{
|
||||
// First we create a dummy task
|
||||
$dummyTask = new Task('testStopTask', 'Mock\Handlers\TestStopTaskHandler');
|
||||
|
||||
// Then we write this task to the TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// First we start the task and confirm its running
|
||||
$dummyTask = $this->executor->startTask($dummyTask);
|
||||
$this->assertTrue($this->executor->getTaskRunning($dummyTask));
|
||||
|
||||
// But then we try and stop it
|
||||
$output = $this->executor->stopTask($dummyTask);
|
||||
|
||||
// We check that the output actually is the task
|
||||
$this->assertSame($dummyTask, $output);
|
||||
|
||||
// And check if the Task has actually stopped now
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,9 @@ use FuzeWorks\Async\TaskStorage;
|
|||
use FuzeWorks\Async\TaskStorage\DummyTaskStorage;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* Class TaskStorageTest
|
||||
*/
|
||||
class TaskStorageTest extends TestCase
|
||||
{
|
||||
|
||||
|
|
|
@ -151,6 +151,14 @@ class TaskTest extends TestCase
|
|||
// Now add it and test if it is there
|
||||
$dummyTask->addAttribute('testKey', 'SomeContent');
|
||||
$this->assertEquals('SomeContent', $dummyTask->attribute('testKey'));
|
||||
|
||||
// Remove attribute
|
||||
$dummyTask->removeAttribute('testKey');
|
||||
$this->assertNull($dummyTask->attribute('testKey'));
|
||||
|
||||
// Remove attribute not found
|
||||
$this->expectException(TasksException::class);
|
||||
$dummyTask->removeAttribute('NotExistant');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
require_once(dirname(__DIR__) . '/vendor/autoload.php');
|
||||
|
||||
use FuzeWorks\Logger;
|
||||
use FuzeWorks\Core;
|
||||
use FuzeWorks\Priority;
|
||||
|
||||
// Open configurator
|
||||
|
@ -55,7 +55,8 @@ $configurator->deferComponentClassMethod('libraries', 'addLibraryClass', null, '
|
|||
// Add test directory so that config.tasks.php can be loaded
|
||||
$configurator->addDirectory(dirname(__FILE__), 'config', Priority::HIGH);
|
||||
|
||||
// Add mock directory for tests and other classes
|
||||
Core::addAutoloadMap('\Mock', dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mock');
|
||||
|
||||
// Create container
|
||||
$container = $configurator->createContainer();
|
||||
Logger::enableScreenLog();
|
||||
return $container;
|
||||
return $configurator->createContainer();
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks Async Library
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2020, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 1.0.0
|
||||
*
|
||||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
namespace Mock\Handlers;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Task;
|
||||
|
||||
class ArgumentedHandler implements Handler
|
||||
{
|
||||
|
||||
private $output;
|
||||
|
||||
private $sleeptime;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function primaryHandler(Task $task): bool
|
||||
{
|
||||
$arguments = $task->getArguments();
|
||||
$this->sleeptime = $arguments[0];
|
||||
$this->output = $arguments[1];
|
||||
|
||||
sleep($this->sleeptime);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function postHandler(Task $task)
|
||||
{
|
||||
sleep($this->sleeptime);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks Async Library
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2020, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 1.0.0
|
||||
*
|
||||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
namespace Mock\Handlers;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Task;
|
||||
|
||||
class TestStartAndReadTasksHandler implements Handler
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function primaryHandler(Task $task): bool
|
||||
{
|
||||
sleep(2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return "Valid Output";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function postHandler(Task $task)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -34,40 +34,43 @@
|
|||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
namespace FuzeWorks\Async;
|
||||
class Process
|
||||
namespace Mock\Handlers;
|
||||
use FuzeWorks\Async\Handler;
|
||||
use FuzeWorks\Async\Task;
|
||||
|
||||
class TestStopTaskHandler implements Handler
|
||||
{
|
||||
|
||||
const PENDING = 1;
|
||||
const RUNNING = 2;
|
||||
const FAILED = 3;
|
||||
const FINISHED = 4;
|
||||
|
||||
/**
|
||||
* The current status of the process
|
||||
*
|
||||
* @var int
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected $status = Process::PENDING;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $pid;
|
||||
|
||||
public function __construct(int $pid)
|
||||
public function primaryHandler(Task $task): bool
|
||||
{
|
||||
$this->pid = $pid;
|
||||
sleep(30);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive the process Id of this process
|
||||
*
|
||||
* @return int
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPid(): int
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->pid;
|
||||
return "Valid Output";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function postHandler(Task $task)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getPostOutput()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
<testsuites>
|
||||
<testsuite name="Base Functionality">
|
||||
<directory>./base/</directory>
|
||||
<directory>./system/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
|
|
|
@ -0,0 +1,464 @@
|
|||
<?php
|
||||
/**
|
||||
* FuzeWorks Async Library
|
||||
*
|
||||
* The FuzeWorks PHP FrameWork
|
||||
*
|
||||
* Copyright (C) 2013-2020 TechFuze
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @author TechFuze
|
||||
* @copyright Copyright (c) 2013 - 2020, TechFuze. (http://techfuze.net)
|
||||
* @license https://opensource.org/licenses/MIT MIT License
|
||||
*
|
||||
* @link http://techfuze.net/fuzeworks
|
||||
* @since Version 1.0.0
|
||||
*
|
||||
* @version Version 1.0.0
|
||||
*/
|
||||
|
||||
use FuzeWorks\Async\Constraint\FixedTimeConstraint;
|
||||
use FuzeWorks\Async\Executors\ShellExecutor;
|
||||
use FuzeWorks\Async\SuperVisor;
|
||||
use FuzeWorks\Async\Supervisors\ParallelSuperVisor;
|
||||
use FuzeWorks\Async\Task;
|
||||
use FuzeWorks\Async\Tasks;
|
||||
use FuzeWorks\Async\TaskStorage;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ParallelSuperVisorTest extends TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var ShellExecutor
|
||||
*/
|
||||
private $executor;
|
||||
|
||||
/**
|
||||
* @var TaskStorage
|
||||
*/
|
||||
private $taskStorage;
|
||||
|
||||
/**
|
||||
* @var ParallelSuperVisor
|
||||
*/
|
||||
private $superVisor;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
// Load the TaskStorage so temporary tasks can be stored
|
||||
// Tasks shall NOT be reset between individual tests automatically
|
||||
$tasks = new Tasks();
|
||||
$this->taskStorage = $tasks->getTaskStorage();
|
||||
$this->taskStorage->reset();
|
||||
|
||||
// And load the ShellExecutor using the execution settings
|
||||
$this->executor = new ShellExecutor([
|
||||
'bootstrapFile' => dirname(__DIR__) . DIRECTORY_SEPARATOR,
|
||||
'workerFile' => dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'worker'
|
||||
]);
|
||||
|
||||
$this->superVisor = new ParallelSuperVisor($this->taskStorage, $this->executor, ['outstream' => null]);
|
||||
}
|
||||
|
||||
public function testClass()
|
||||
{
|
||||
$this->assertInstanceOf('FuzeWorks\Async\Supervisors\ParallelSuperVisor', $this->superVisor);
|
||||
}
|
||||
|
||||
/* ---------------------------------- Writing and reading tasks ----------------------- */
|
||||
|
||||
/**
|
||||
* @depends testClass
|
||||
*/
|
||||
public function testEmptyCycle()
|
||||
{
|
||||
$this->assertEquals(SuperVisor::FINISHED, $this->superVisor->cycle());
|
||||
}
|
||||
|
||||
public function testToRunning()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testToRunning', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Write the dummy to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Assert that the status is PENDING and not running
|
||||
$this->assertEquals(Task::PENDING, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it is running for real
|
||||
$this->assertEquals(Task::RUNNING, $dummyTask->getStatus());
|
||||
$this->assertTrue($this->executor->getTaskRunning($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testToRunning
|
||||
*/
|
||||
public function testConstrainedPending()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testConstrainedPending', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Add a constraint
|
||||
$dummyTask->addConstraint(new FixedTimeConstraint(time() + 3600));
|
||||
|
||||
// Write the dummy to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Assert that the status is PENDING and not running
|
||||
$this->assertEquals(Task::PENDING, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it is delayed
|
||||
$this->assertEquals(Task::DELAYED, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testToRunning
|
||||
*/
|
||||
public function testChangeDelayedToPending()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testChangeDelayedToPending', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set to delayed and set to NOW
|
||||
$dummyTask->setStatus(Task::DELAYED);
|
||||
$dummyTask->setDelayTime(time() - 3600);
|
||||
|
||||
// Write the dummy to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Assert that the status is DELAYED and not running
|
||||
$this->assertEquals(Task::DELAYED, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it is delayed
|
||||
$this->assertEquals(Task::PENDING, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testToRunning
|
||||
*/
|
||||
public function testKeepDelayed()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testKeepDelayed', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set to delayed and set to NOW
|
||||
$dummyTask->setStatus(Task::DELAYED);
|
||||
$dummyTask->setDelayTime(time() + 3600);
|
||||
|
||||
// Write the dummy to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Assert that the status is DELAYED and not running
|
||||
$this->assertEquals(Task::DELAYED, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it is delayed
|
||||
$this->assertEquals(Task::DELAYED, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testToRunning
|
||||
*/
|
||||
public function testFinishedTask()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testFinishedTask', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set status to running
|
||||
$dummyTask->setStatus(Task::RUNNING);
|
||||
$dummyTask->addAttribute('pid', 1005);
|
||||
|
||||
// Write the dummy and some output to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
$this->taskStorage->writeTaskOutput($dummyTask, 'Some Output', '', Task::SUCCESS);
|
||||
|
||||
// Test if everything is set
|
||||
$this->assertEquals(Task::RUNNING, $dummyTask->getStatus());
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it is finished indeed
|
||||
$this->assertEquals(Task::SUCCESS, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
$this->assertEquals('Some Output', $dummyTask->getOutput());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFinishedTask
|
||||
*/
|
||||
public function testMissingTask()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testMissingTask', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set status to running
|
||||
$dummyTask->setStatus(Task::RUNNING);
|
||||
$dummyTask->addAttribute('pid', 1006);
|
||||
|
||||
// Write the dummy and no output to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Test if everything is set
|
||||
$this->assertEquals(Task::RUNNING, $dummyTask->getStatus());
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it has failed indeed
|
||||
$this->assertEquals(Task::PFAILED, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFinishedTask
|
||||
*/
|
||||
public function testFailedTask()
|
||||
{
|
||||
// First create a dummy task
|
||||
$dummyTask = new Task('testFailedTask', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set status to running
|
||||
$dummyTask->setStatus(Task::RUNNING);
|
||||
$dummyTask->addAttribute('pid', 1007);
|
||||
|
||||
// Write the dummy and some output to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
$this->taskStorage->writeTaskOutput($dummyTask, 'Some Output', 'Some Errors', Task::FAILED);
|
||||
|
||||
// Test if everything is set
|
||||
$this->assertEquals(Task::RUNNING, $dummyTask->getStatus());
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Then re-fetch the Task
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
|
||||
// And check that it is finished indeed
|
||||
$this->assertEquals(Task::FAILED, $dummyTask->getStatus());
|
||||
$this->assertFalse($this->executor->getTaskRunning($dummyTask));
|
||||
$this->assertEquals('Some Errors', $dummyTask->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFailedTask
|
||||
*/
|
||||
public function testRetryFailedTask()
|
||||
{
|
||||
// First create the dummy tasks
|
||||
$dummyTaskFailedYes = new Task('testRetryFailedTaskY', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
$dummyTaskPFailedYes = new Task('testRetryFailedTaskPY', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
$dummyTaskFailedNo = new Task('testRetryFailedTaskN', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
$dummyTaskPFailedNo = new Task('testRetryFailedTaskPN', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set statuses
|
||||
$dummyTaskFailedYes->setStatus(Task::FAILED);
|
||||
$dummyTaskPFailedYes->setStatus(Task::PFAILED);
|
||||
$dummyTaskFailedNo->setStatus(Task::FAILED);
|
||||
$dummyTaskPFailedNo->setStatus(Task::FAILED);
|
||||
|
||||
// Set retry settings
|
||||
$dummyTaskFailedYes->setRetrySettings(true, 5, true, true,true);
|
||||
$dummyTaskPFailedYes->setRetrySettings(true, 5, true, true,true);
|
||||
$dummyTaskFailedNo->setRetrySettings(true, 5, false, false,true);
|
||||
$dummyTaskPFailedNo->setRetrySettings(true, 5, false, false,true);
|
||||
|
||||
// Save all these tasks
|
||||
$this->taskStorage->addTask($dummyTaskFailedYes);
|
||||
$this->taskStorage->addTask($dummyTaskPFailedYes);
|
||||
$this->taskStorage->addTask($dummyTaskFailedNo);
|
||||
$this->taskStorage->addTask($dummyTaskPFailedNo);
|
||||
|
||||
// Then cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// Reload all tasks from TaskStorage
|
||||
$dummyTaskFailedYes = $this->taskStorage->getTaskById($dummyTaskFailedYes->getId());
|
||||
$dummyTaskPFailedYes = $this->taskStorage->getTaskById($dummyTaskPFailedYes->getId());
|
||||
$dummyTaskFailedNo = $this->taskStorage->getTaskById($dummyTaskFailedNo->getId());
|
||||
$dummyTaskPFailedNo = $this->taskStorage->getTaskById($dummyTaskPFailedNo->getId());
|
||||
|
||||
// Check if the tasks that should retry are running
|
||||
$this->assertEquals(Task::RUNNING, $dummyTaskFailedYes->getStatus());
|
||||
$this->assertEquals(Task::RUNNING, $dummyTaskPFailedYes->getStatus());
|
||||
$this->assertTrue($this->executor->getTaskRunning($dummyTaskFailedYes));
|
||||
$this->assertTrue($this->executor->getTaskRunning($dummyTaskPFailedYes));
|
||||
|
||||
// Check if the tasks that shouldn't have been cancelled
|
||||
$this->assertEquals(Task::CANCELLED, $dummyTaskFailedNo->getStatus());
|
||||
$this->assertEquals(Task::CANCELLED, $dummyTaskPFailedNo->getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFailedTask
|
||||
*/
|
||||
public function testExceedMaxRetries()
|
||||
{
|
||||
// First create the dummy tasks
|
||||
$dummyTask = new Task('testExceedMaxRetries', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
$dummyTask2 = new Task('testExceedMaxRetries2', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
|
||||
// Set status and retry settings
|
||||
$dummyTask->setStatus(Task::FAILED);
|
||||
$dummyTask2->setStatus(Task::FAILED);
|
||||
$dummyTask->setRetrySettings(true, 2, true, true, true);
|
||||
$dummyTask2->setRetrySettings(true, 2, true, true, true);
|
||||
|
||||
// Set retries to 2 for the first task, and 1 for the second task
|
||||
$dummyTask->addRetry();
|
||||
$dummyTask->addRetry();
|
||||
$dummyTask2->addRetry();
|
||||
|
||||
// Write the task to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
$this->taskStorage->addTask($dummyTask2);
|
||||
|
||||
// Cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// And check if the Task has been cancelled
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
$dummyTask2 = $this->taskStorage->getTaskById($dummyTask2->getId());
|
||||
$this->assertEquals(Task::CANCELLED, $dummyTask->getStatus());
|
||||
$this->assertEquals(Task::RUNNING, $dummyTask2->getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFailedTask
|
||||
*/
|
||||
public function testFailedToPost()
|
||||
{
|
||||
// First create the dummy tasks
|
||||
$dummyTask = new Task('testFailedToPost', 'Mock\Handlers\ArgumentedHandler', true, 10, 'Some Output');
|
||||
|
||||
// Set status and settings
|
||||
$dummyTask->setStatus(Task::FAILED);
|
||||
$dummyTask->addAttribute('pid', 1010);
|
||||
|
||||
// Write the task to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTask);
|
||||
|
||||
// Cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// And check if the Task has been moved to Post
|
||||
$dummyTask = $this->taskStorage->getTaskById($dummyTask->getId());
|
||||
$this->assertEquals(Task::POST, $dummyTask->getStatus());
|
||||
$this->assertTrue($this->executor->getTaskRunning($dummyTask));
|
||||
$this->assertIsInt($dummyTask->attribute('pid'));
|
||||
$this->assertNotEquals(1010, $dummyTask->attribute('pid'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFinishedTask
|
||||
*/
|
||||
public function testSuccessfulTasks()
|
||||
{
|
||||
// First create the dummy tasks
|
||||
$dummyTaskPostNo = new Task('testSuccessfulTasksN', 'Mock\Handlers\ArgumentedHandler', false, 10, 'Some Output');
|
||||
$dummyTaskPostYes = new Task('testSuccessfulTasksY', 'Mock\Handlers\ArgumentedHandler', true, 10, 'Some Output');
|
||||
|
||||
// Set status and settings
|
||||
$dummyTaskPostNo->setStatus(Task::SUCCESS);
|
||||
$dummyTaskPostYes->setStatus(Task::SUCCESS);
|
||||
|
||||
// Write the tasks to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTaskPostNo);
|
||||
$this->taskStorage->addTask($dummyTaskPostYes);
|
||||
|
||||
// Cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// And check if the Tasks have been completed or moved to post
|
||||
$dummyTaskPostNo = $this->taskStorage->getTaskById($dummyTaskPostNo->getId());
|
||||
$dummyTaskPostYes = $this->taskStorage->getTaskById($dummyTaskPostYes->getId());
|
||||
$this->assertEquals(Task::COMPLETED, $dummyTaskPostNo->getStatus());
|
||||
$this->assertEquals(Task::POST, $dummyTaskPostYes->getStatus());
|
||||
$this->assertTrue($this->executor->getTaskRunning($dummyTaskPostYes));
|
||||
}
|
||||
|
||||
public function testPostTasks()
|
||||
{
|
||||
// First create the dummy tasks
|
||||
$dummyTaskFinished = new Task('testPostTasksFinished', 'Mock\Handlers\ArgumentedHandler', true, 10, 'Some Output');
|
||||
$dummyTaskMissing = new Task('testPostTasksMissing', 'Mock\Handlers\ArgumentedHandler', true, 10, 'Some Output');
|
||||
|
||||
// Set status and settings
|
||||
$dummyTaskFinished->setStatus(Task::POST);
|
||||
$dummyTaskMissing->setStatus(Task::POST);
|
||||
$dummyTaskFinished->addAttribute('pid', 1011);
|
||||
$dummyTaskMissing->addAttribute('pid', 1012);
|
||||
|
||||
// Write the tasks to TaskStorage
|
||||
$this->taskStorage->addTask($dummyTaskFinished);
|
||||
$this->taskStorage->addTask($dummyTaskMissing);
|
||||
$this->taskStorage->writePostOutput($dummyTaskFinished, 'Post Output', 'Post Errors', Task::COMPLETED);
|
||||
|
||||
// Cycle the SuperVisor
|
||||
$this->superVisor->cycle();
|
||||
|
||||
// And check if the Tasks have been completed or failed
|
||||
$dummyTaskFinished = $this->taskStorage->getTaskById($dummyTaskFinished->getId());
|
||||
$dummyTaskMissing = $this->taskStorage->getTaskById($dummyTaskMissing->getId());
|
||||
$this->assertEquals(Task::COMPLETED, $dummyTaskFinished->getStatus());
|
||||
$this->assertEquals(Task::CANCELLED, $dummyTaskMissing->getStatus());
|
||||
$this->assertEquals('Post Output', $dummyTaskFinished->getPostOutput());
|
||||
$this->assertNull($dummyTaskMissing->getPostOutput());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue