/** * @return ProcessSet */ protected function getProcessSet() { if (!$this->processSet) { $this->processSet = new ProcessSet(); $this->processSet->setPublisher($this->publisher); } return $this->processSet; }
public function testShouldChangeOrderOfProcessesByGivenStrategy() { // ROOT // / \ // A B // 3 / \ 5 // C D $this->set->add(new Process(''), 'A'); $this->set->add(new Process(''), 'B'); $this->set->add(new Process(''), 'C', 'B', 3); $this->set->add(new Process(''), 'D', 'B', 5); // The MockOrderStrategy return processes with order values A - 0, B - 1, C - 2, D - 3. // Thus after optimization the processes in processSet should be sorted descending $processesBefore = $this->set->get(ProcessSet::PROCESS_STATUS_QUEUED); $this->assertSame(['A', 'B', 'C', 'D'], array_keys($processesBefore)); $this->set->optimizeOrder(new MockOrderStrategy()); $processesAfter = $this->set->get(ProcessSet::PROCESS_STATUS_QUEUED); $this->assertSame(['D', 'C', 'B', 'A'], array_keys($processesAfter)); }
/** * Start planner execution loop * * @param OutputInterface $output * @param ProcessSet $processSet * @return bool Return true if all test returned exit code 0 (or if none test was run) */ protected function executionLoop(OutputInterface $output, ProcessSet $processSet) { $counterWaitingOutput = 1; $counterProcessesLast = 0; $allTestsPassed = true; // Iterate over prepared and queued until everything is done while (true) { $prepared = $processSet->get(ProcessSet::PROCESS_STATUS_PREPARED); $queued = $processSet->get(ProcessSet::PROCESS_STATUS_QUEUED); if (count($prepared) == 0 && count($queued) == 0) { $output->writeln('No tasks left, exiting the execution loop...'); break; } // Start all prepared tasks and set status of not running as finished foreach ($prepared as $testClass => $processObject) { if (!$processObject->process->isStarted()) { if ($output->isDebug()) { $output->writeln(sprintf('Running command for class "%s":' . "\n" . '%s', $testClass, $processObject->process->getCommandLine())); } $processObject->process->start(); usleep(50000); // wait for a while (0,05 sec) to let processes be started in intended order continue; } $timeoutError = $this->checkProcessTimeout($processObject->process, $testClass); if ($timeoutError) { $output->writeln('<error>' . $timeoutError . '</error>'); } $processOutput = $this->getProcessOutput($processObject->process); if ($processOutput) { $output->write($processOutput); } // Mark no longer running processes as finished if (!$processObject->process->isRunning()) { if ($processObject->process->getExitCode()) { // non-zero exit code (= failed/exception) $allTestsPassed = false; } $output->writeln(sprintf('Process for class "%s" finished', $testClass)); $processSet->setStatus($testClass, ProcessSet::PROCESS_STATUS_DONE); $processObject->finishedTime = time(); } } // Add queued tasks to prepared if their dependent task is done and delay has passed $done = $processSet->get(ProcessSet::PROCESS_STATUS_DONE); $doneClasses = []; foreach ($done as $testClass => $processObject) { $doneClasses[] = $testClass; } foreach ($queued as $testClass => $processObject) { $delaySeconds = $processObject->delayMinutes * 60; if (in_array($processObject->delayAfter, $doneClasses) && time() - $done[$processObject->delayAfter]->finishedTime > $delaySeconds) { $output->writeln(sprintf('Unqueing class "%s"', $testClass)); $processSet->setStatus($testClass, ProcessSet::PROCESS_STATUS_PREPARED); } } $countProcessesPrepared = count($processSet->get(ProcessSet::PROCESS_STATUS_PREPARED)); $countProcessesQueued = count($processSet->get(ProcessSet::PROCESS_STATUS_QUEUED)); $countProcessesDone = count($processSet->get(ProcessSet::PROCESS_STATUS_DONE)); $counterProcesses = [$countProcessesPrepared, $countProcessesQueued, $countProcessesDone]; // if the output didn't change, wait 10 seconds before printing it again if ($counterProcesses === $counterProcessesLast && $counterWaitingOutput % 10 !== 0) { $counterWaitingOutput++; } else { $output->writeln(sprintf("[%s]: waiting (running: %d, queued: %d, done: %d)", date("Y-m-d H:i:s"), $countProcessesPrepared, $countProcessesQueued, $countProcessesDone)); $counterWaitingOutput = 1; } $counterProcessesLast = $counterProcesses; sleep(1); } return $allTestsPassed; }