Async/test/base/ShellWorkerTest.php

240 lines
8.7 KiB
PHP

<?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\Handler;
use FuzeWorks\Async\ShellWorker;
use FuzeWorks\Async\Task;
use FuzeWorks\Async\TaskStorage;
use FuzeWorks\Events;
use PHPUnit\Framework\TestCase;
class ShellWorkerTest extends TestCase
{
/**
* @var ShellWorker
*/
protected $shellWorker;
/**
* @var TaskStorage
*/
protected $taskStorage;
public function setUp(): void
{
// Load the TaskStorage so temporary tasks can be stored
// This system uses DummyTaskStorage because Redis can't serialize the Mock Handlers. Doesn't matter much anyway.
$this->taskStorage = new TaskStorage\DummyTaskStorage([]);
$this->shellWorker = new ShellWorker($this->taskStorage);
$this->taskStorage->reset();
// Clear events
Events::$listeners = [];
}
public function testClass()
{
$this->assertInstanceOf(ShellWorker::class, $this->shellWorker);
}
/* ---------------------------------- Writing and reading tasks ----------------------- */
// @todo Add lots of tests and amend ShellWorker to return results
/**
* @depends testClass
*/
public function testUseHandler()
{
// First prepare a Mock Handler
$mockHandler = $this->createMock(Handler::class);
$mockHandler->expects($this->exactly(2))->method('getParentHandler')->willReturn(null);
$mockHandler->expects($this->once())
->method('primaryHandler')
->with($this->callback(function($subject){return $subject instanceof Task;}))
->willReturn(true);
$mockHandler->expects($this->once())
->method('postHandler')
->with($this->callback(function($subject){return $subject instanceof Task;}))
->willReturn(true);
$mockHandler->expects($this->once())->method('getOutput')->willReturn('Some Output!');
$mockHandler->expects($this->once())->method('getPostOutput')->willReturn('Post Output!');
// Create a Dummy task
$dummyTask = new Task('testUseHandler', $mockHandler);
$this->taskStorage->addTask($dummyTask);
// Run the task in ShellWorker
$this->shellWorker->run($dummyTask, false);
// And verify if the Output is correctly set
$output = $this->taskStorage->readTaskOutput($dummyTask, 1);
$this->assertEquals('Some Output!', $output['output']);
$this->assertEquals(Task::SUCCESS, $output['statusCode']);
// And run the post handler
$this->shellWorker->run($dummyTask, true);
$output = $this->taskStorage->readPostOutput($dummyTask, 1);
$this->assertEquals('Post Output!', $output['output']);
$this->assertEquals(Task::SUCCESS, $output['statusCode']);
}
/**
* @depends testUseHandler
*/
public function testFailingHandlers()
{
$mockHandler = $this->createMock(Handler::class);
$mockHandler->expects($this->once())
->method('primaryHandler')
->with($this->callback(function($subject){return $subject instanceof Task;}))
->willReturn(false);
$mockHandler->expects($this->once())
->method('postHandler')
->with($this->callback(function($subject){return $subject instanceof Task;}))
->willReturn(false);
// Create a Dummy task
$dummyTask = new Task('testFailingHandlers1', $mockHandler);
$this->taskStorage->addTask($dummyTask);
// Run the task in ShellWorker
$this->shellWorker->run($dummyTask, false);
// And verify if the Output is correctly set
$output = $this->taskStorage->readTaskOutput($dummyTask, 1);
$this->assertEquals('', $output['output']);
$this->assertEquals(Task::FAILED, $output['statusCode']);
// And run a post failure
$this->shellWorker->run($dummyTask, true);
$output = $this->taskStorage->readPostOutput($dummyTask, 1);
$this->assertEquals('', $output['output']);
$this->assertEquals(Task::FAILED, $output['statusCode']);
}
/**
* @depends testUseHandler
*/
public function testParentHandlers()
{
// First create the Handlers
$parentHandler = $this->createMock(Handler::class);
$childHandler = $this->createMock(Handler::class);
// Prepare parent handler output
$parentHandler->expects($this->once())
->method('primaryHandler')
->with($this->callback(function($subject){return $subject instanceof Task;}))
->willReturn(true);
$parentHandler->expects($this->once())
->method('getOutput')
->willReturn('Parent Output');
// Prepare the child handler
$childHandler->expects($this->once())
->method('getParentHandler')
->willReturn($parentHandler);
$childHandler->expects($this->once())
->method('setParentInput')
->with($this->equalTo('Parent Output'));
$childHandler->expects($this->once())
->method('primaryHandler')
->with($this->callback(function($subject){return $subject instanceof Task;}))
->willReturn(true);
$childHandler->expects($this->once())
->method('getOutput')
->willReturn('Child Output');
// Set the relation
$childHandler->setParentHandler($parentHandler);
// Create the Dummy Task
$dummyTask = new Task('testParentHandlers', $childHandler);
$this->taskStorage->addTask($dummyTask);
// Run the task in ShellWorker
$this->shellWorker->run($dummyTask, false);
// And verify if the Output is correctly set
$output = $this->taskStorage->readTaskOutput($dummyTask, 1);
$this->assertEquals('Child Output', $output['output']);
$this->assertEquals(Task::SUCCESS, $output['statusCode']);
}
/**
* @depends testParentHandlers
*/
public function testCascadingParentFailure()
{
// First create the Handlers
$parentHandler = $this->createMock(Handler::class);
$childHandler = $this->createMock(Handler::class);
// Set the relation
$childHandler->setParentHandler($parentHandler);
$childHandler->expects($this->once())
->method('getParentHandler')
->willReturn($parentHandler);
// Set the results
$parentHandler->expects($this->once())
->method('primaryHandler')
->willReturn(false);
$childHandler->expects($this->never())
->method('primaryHandler')
->willReturn(true);
// And some methods which shall be called in the end
$childHandler->expects($this->once())
->method('getOutput')
->willReturn('Task failed successfully');
// Create the task to run this
$dummyTask = new Task('testCascadingParentFailure', $childHandler);
$this->taskStorage->addTask($dummyTask);
// Run the task in ShellWorker
$this->shellWorker->run($dummyTask, false);
// And verify whether the task has indeed failed
$output = $this->taskStorage->readTaskOutput($dummyTask, 1);
$this->assertEquals('Task failed successfully', $output['output']);
$this->assertEquals(Task::FAILED, $output['statusCode']);
}
}