/** * */ public function testApiSome_RejectsPromise_IfAnyInputPromiseRejects_BeforeDesiredNumberOfInputsAreResolved() { $test = $this->getTest(); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo([1 => 2, 2 => 3])); Promise::some([Promise::doResolve(1), Promise::doReject(2), Promise::doReject(3)], 2)->then($test->expectCallableNever(), $mock); }
/** * */ public function testApiMap_RejectsPromise_WhenInputContainsRejection() { $test = $this->getTest(); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo(2)); Promise::map([Promise::doResolve(1), Promise::doReject(2), Promise::doResolve(3)], $this->mapper())->then($test->expectCallableNever(), $mock); }
/** * */ public function testApiAny_ResolvesPromise_IfAnyInputPromisesResolve() { $test = $this->getTest(); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo(2)); Promise::any([Promise::doReject(1), Promise::doResolve(2), Promise::doReject(3)])->then($mock); }
/** * @override * @inheritDoc */ public function solve($ex, $params = []) { foreach ($this->requires as $require) { if (!isset($params[$require])) { return Promise::doReject(new IllegalCallException('Missing parameter [' . $require . '] for [' . get_class($this) . '].')); } } return Promise::doResolve($this->solver($ex, $params)); }
/** * */ public function testApiCancel_CancelsPromise_WithRejectedPromise() { $deferred = $this->createDeferred(); $test = $this->getTest(); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo(1)); $deferred->getPromise()->then($test->expectCallableNever(), $test->expectCallableNever(), $mock); $deferred->cancel(Promise::doReject(1)); }
/** * @param Error|Exception $ex * @param mixed[] $params * @return mixed */ protected function solver($ex, $params = []) { $manager = $this->runtime->getManager(); $hash = isset($params['hash']) ? $params['hash'] : ''; $alias = $params['origin']; if ($manager->existsThread($alias)) { return $manager->createThread($alias, null, Runtime::CREATE_FORCE, ['hash' => $hash]); } else { if ($manager->existsProcess($alias)) { return $manager->createProcess($alias, null, Runtime::CREATE_FORCE, ['hash' => $hash]); } } return Promise::doReject(new RejectionException("Runtime [{$alias}] does not exists.")); }
/** * @param string $command * @param mixed[] $params * @return PromiseInterface * @resolves mixed * @rejects Error|Exception|string|null * @cancels Error|Exception|string|null */ private function executeCommand($command, $params = []) { try { return $this->commander->execute($command, $params); } catch (Error $ex) { return Promise::doReject($ex); } catch (Exception $ex) { return Promise::doReject($ex); } }
/** * @override * @inheritDoc */ public function stopProcesses($aliases, $params = []) { return Promise::doReject(new RejectionException("Processes could not be stopped.")); }
/** * */ public function testApiSolver_RejectsPromise_OnFirstRejection() { $ex1 = new Exception('Exception'); $ex2 = new Exception('Other Exception'); $params = ['params1' => 'value1']; $queue = ''; $solver1 = $this->getMock(SolverInterface::class, [], [], '', false); $solver1->expects($this->once())->method('solve')->with($ex1, $params)->will($this->returnCallback(function () use(&$queue, $ex2) { $queue .= 'A'; return Promise::doReject($ex2); })); $solver2 = $this->getMock(SolverInterface::class, [], [], '', false); $solver2->expects($this->never())->method('solve')->with($ex1, $params)->will($this->returnCallback(function () use(&$queue) { $queue .= 'B'; })); $solver3 = $this->getMock(SolverInterface::class, [], [], '', false); $solver3->expects($this->never())->method('solve')->with($ex1, $params)->will($this->returnCallback(function () use(&$queue) { $queue .= 'C'; })); $solver = $this->createSolver([$solver1, $solver2, $solver3]); $callable = $this->createCallableMock(); $callable->expects($this->once())->method('__invoke')->with($ex2); $result = $this->callProtectedMethod($solver, 'solver', [$ex1, $params]); $result->then(null, $callable); $this->assertSame('A', $queue); }
/** * @override * @inheritDoc */ public function flushProcesses($flags = Runtime::DESTROY_KEEP) { $promises = []; if ($flags === Runtime::DESTROY_KEEP) { return Promise::doReject(new RejectionException('Process storage could not be flushed because of force level set to DESTROY_KEEP.')); } foreach ($this->processes as $alias => $process) { $promises[] = $this->destroyProcess($alias, $flags); } return Promise::all($promises)->then(function () { $this->processes = []; $this->updateStorage(); return 'Processes storage has been flushed.'; }); }
/** * @override * @inheritDoc */ public function destroyProject($flags = Runtime::DESTROY_FORCE_SOFT) { if (!isset($this->data['pid'])) { return Promise::doResolve("Project was not needed to be destroyed, because it had not existed."); } $manager = $this; $pid = $this->data['pid']; $alias = $this->data['alias']; $name = $this->data['name']; if ($flags === Runtime::DESTROY_KEEP) { return Promise::doReject(new ResourceOccupiedException("Project could not be destroyed with force level=DESTROY_KEEP.")); } else { if ($flags === Runtime::DESTROY_FORCE_SOFT) { $req = $this->createRequest($this->channel, $alias, new RuntimeCommand('container:destroy')); return $req->call()->then(function ($value) use($manager) { usleep(1000.0); $manager->freeProject(); return $value; }); } else { if ($flags === Runtime::DESTROY_FORCE) { return $this->destroyProject(Runtime::DESTROY_FORCE_SOFT)->then(null, function () use($manager) { return $manager->destroyProject(Runtime::DESTROY_FORCE_HARD); }); } } } if (!$this->system->existsPid($pid)) { return Promise::doResolve()->then(function () use($manager) { $manager->freeProject(); return "Project was not needed to be destroyed, because it had not existed."; }); } else { if (!$this->system->kill($pid)) { return Promise::doReject(new ResourceOccupiedException("Project could not be killed forcefully.")); } } return Promise::doResolve()->then(function () use($manager) { $manager->freeProject(); return "Process has been destroyed!"; }); }
/** * @override * @inheritDoc */ public function solve($ex, $params = [], &$try = 0) { $classBaseEx = get_class($ex); $classes = array_merge([$classBaseEx], class_parents($ex)); $indexMin = -1; $chosen = null; foreach ($classes as $class) { $indexCurrent = array_search($class, array_keys($this->rules), true); if ($indexCurrent !== false && ($indexMin === -1 || $indexCurrent < $indexMin)) { $indexMin = $indexCurrent; $chosen = $class; } } if ($chosen === null) { return Promise::doReject(new ExecutionException("SolverInterface for [{$classBaseEx}] is not registered.")); } $try++; $params = array_merge($this->params, $params); $valueOrPromise = $this->getSolver($chosen)->solve($ex, $params); return Promise::doResolve($valueOrPromise); }
/** * @override * @inheritDoc */ public function stop() { $state = $this->getState(); if ($state === Runtime::STATE_CREATED || $state === Runtime::STATE_DESTROYED) { return Promise::doReject(new RejectionException("It is not possible to stop runtime from state [{$state}].")); } else { if ($state === Runtime::STATE_STOPPED) { return Promise::doResolve('Runtime has been already stopped.'); } } $this->setState(Runtime::STATE_STOPPED); $emitter = $this->getEventEmitter(); $emitter->emit('beforeStop'); $emitter->emit('stop'); $emitter->emit('afterStop'); return Promise::doResolve('Runtime has been stopped.'); }
/** * */ public function testApiSpread_Returns_FromRejectionHandler_ForRejectedPromise() { $deferred = $this->createDeferred(); $test = $this->getTest(); $ex = new Exception('Error'); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo($ex)); $deferred->reject(); $deferred->getPromise()->spread(null, function () use($ex) { return Promise::doReject($ex); })->then(null, $mock); }
/** * */ public function testApiDoReject_ReturnsPromise() { $test = $this->getTest(); $test->assertInstanceOf(PromiseInterface::class, Promise::doReject(1)); }
/** * @override * @inheritDoc */ public function stopRuntime($alias, $params = []) { if ($this->existsThread($alias)) { return $this->threadManager->stopThread($alias, $params); } else { if ($this->existsProcess($alias)) { return $this->processManager->stopProcess($alias, $params); } } return Promise::doReject(new ResourceUndefinedException("Runtime with alias [{$alias}] does not exist.")); }
/** * */ public function testApiAlways_DoesNotSuppressCancellation_WhenHandlerRejects_ForCancelledPromise() { $deferred = $this->createDeferred(); $test = $this->getTest(); $ex1 = new Exception(); $ex2 = new Exception(); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo($ex1)); $deferred->cancel($ex1); $deferred->getPromise()->always(function () use($ex2) { return Promise::doReject($ex2); })->then(null, null, $mock); }
/** * */ public function testApiAlways_RejectsPromise_WhenHandlerRejects_AfterResolved() { $deferred = $this->createDeferred(); $test = $this->getTest(); $exception = new Exception(); $mock = $test->createCallableMock(); $mock->expects($test->once())->method('__invoke')->with($test->identicalTo($exception)); $deferred->getPromise()->always(function () use($exception) { return Promise::doReject($exception); })->then(null, $mock); $deferred->resolve(1); }
/** * @override * @inheritDoc */ public function flushThreads($flags = Runtime::DESTROY_KEEP) { return Promise::doReject(new RejectionException('Threads storage cannot be flushed.')); }