/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Process status must be one of "prepared, queued, done", but "WrongStatus" given */ public function testFailIfWrongProcessStatusGiven() { $this->set->add(new Process(''), 'Foo'); $this->set->setStatus('Foo', 'WrongStatus'); }
/** * 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; }