| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- <?php
- use Behat\Behat\Tester\Exception\PendingException;
- use Behat\Behat\Context\Context;
- use Behat\Behat\Context\SnippetAcceptingContext;
- use Behat\Behat\Hook\Scope\BeforeScenarioScope;
- use Behat\Behat\Hook\Scope\AfterScenarioScope;
- use Behat\Gherkin\Node\PyStringNode;
- use Behat\Gherkin\Node\TableNode;
- use Supervisor\Configuration\Parser\File as Parser;
- use Supervisor\Configuration\Writer\File as Writer;
- use Supervisor\Configuration\Section;
- use Supervisor\Connector\XmlRpc;
- use Supervisor\Supervisor;
- use fXmlRpc\Client;
- use fXmlRpc\Transport\Guzzle4Bridge;
- use GuzzleHttp\Client as GuzzleClient;
- /**
- * Defines application features from the specific context.
- */
- class FeatureContext implements Context, SnippetAcceptingContext
- {
- /**
- * Initializes context.
- *
- * Every scenario gets its own context instance.
- * You can also pass arbitrary arguments to the
- * context constructor through behat.yml.
- */
- public function __construct($bin = 'supervisord')
- {
- $this->bin = $bin;
- }
- /**
- * @BeforeScenario
- */
- public function setUpSupervisor(BeforeScenarioScope $scope)
- {
- $parser = new Parser(__DIR__.'/../../resources/supervisord.conf');
- $this->configuration = $parser->parse();
- $this->setUpConnector();
- }
- protected function setUpConnector()
- {
- $client = new Client(
- 'http://127.0.0.1:9001/RPC2',
- new Guzzle4Bridge(new GuzzleClient(['defaults' => ['auth' => ['user', '123']]]))
- );
- $connector = new XmlRpc($client);
- $this->supervisor = new Supervisor($connector);
- }
- /**
- * @AfterScenario
- */
- public function stopSupervisor(AfterScenarioScope $scope)
- {
- isset($this->process) and posix_kill($this->process, SIGKILL);
- }
- /**
- * @Given I have Supervisor running
- */
- public function iHaveSupervisorRunning()
- {
- $writer = new Writer($file = tempnam(sys_get_temp_dir(), 'supervisord_'));
- $writer->write($this->configuration);
- if ($this->supervisor->isConnected()) {
- posix_kill($this->supervisor->getPID(), SIGKILL);
- }
- $command = sprintf('(%s --configuration %s > /dev/null 2>&1 & echo $!)&', $this->bin, $file);
- exec($command, $op);
- $this->process = (int)$op[0];
- $c = 0;
- while (!$this->supervisor->isConnected() and $c < 100) {
- usleep(10000);
- $c++;
- }
- if ($c >= 100) {
- throw new \RuntimeException('Could not connect to supervisord');
- }
- if ($this->process !== $this->supervisor->getPID()) {
- throw new \RuntimeException('Connected to supervisord with a different PID');
- }
- }
- /**
- * @When I ask for the API version
- */
- public function iAskForTheApiVersion()
- {
- $this->version = $this->supervisor->getAPIVersion();
- }
- /**
- * @Then I should get at least :ver version
- */
- public function iShouldGetAtLeastVersion($ver)
- {
- if (version_compare($this->version, $ver) == -1) {
- throw new \Exception(sprintf('Version "%s" does not match the minimum required "%s"', $this->version, $ver));
- }
- }
- /**
- * @When I ask for Supervisor version
- */
- public function iAskForSupervisorVersion()
- {
- $this->version = $this->supervisor->getVersion();
- }
- /**
- * @Given my Supervisor instance is called :identifier
- */
- public function mySupervisorInstanceIsCalled($identifier)
- {
- $supervisord = $this->configuration->getSection('supervisord');
- $supervisord->setProperty('identifier', $identifier);
- }
- /**
- * @When I ask for Supervisor identification
- */
- public function iAskForSupervisorIdentification()
- {
- $this->identifier = $this->supervisor->getIdentification();
- }
- /**
- * @Then I should get :identifier as identifier
- */
- public function iShouldGetAsIdentifier($identifier)
- {
- if ($this->identifier !== $identifier) {
- throw new \Exception(sprintf('Identification "%s" does not match the required "%s"', $this->identifier, $identifier));
- }
- }
- /**
- * @When I ask for the state
- */
- public function iAskForTheState()
- {
- $this->state = $this->supervisor->getState();
- }
- /**
- * @Then I should get :code as statecode and :name as statename
- */
- public function iShouldGetAsStatecodeAndAsStatename($code, $name)
- {
- if ($this->state['statecode'] != $code) {
- throw new \Exception(sprintf('State code "%s" does not match the required "%s"', $this->state['statecode'], $code));
- }
- if ($this->state['statename'] !== $name) {
- throw new \Exception(sprintf('Statename "%s" does not match the required "%s"', $this->state['statename'], $name));
- }
- }
- /**
- * @When I ask for the PID
- */
- public function iAskForThePid()
- {
- $this->pid = $this->supervisor->getPID();
- }
- /**
- * @Then I should get the real PID
- */
- public function iShouldGetTheRealPid()
- {
- if ($this->process !== $this->pid) {
- throw new \Exception(sprintf('PID "%s" does not match the real "%s"', $this->pid, $this->process));
- }
- }
- /**
- * @When I ask for the log
- */
- public function iAskForTheLog()
- {
- $this->log = trim($this->supervisor->readLog(-(35 + strlen($this->process)), 0));
- }
- /**
- * @Then I should get an INFO about supervisord started
- */
- public function iShouldGetAnInfoAboutSupervisordStarted()
- {
- if ($this->log !== 'INFO supervisord started with pid '.$this->process) {
- throw new \Exception(sprintf('The following log entry was expected: "%s", but we got this: "%s"', 'INFO supervisord started with pid '.$this->process, $this->log));
- }
- }
- /**
- * @When I try to call :action action
- */
- public function iTryToCallAction($action)
- {
- $this->action = $action;
- $this->response = call_user_func([$this->supervisor, $action]);
- }
- /**
- * @When I check if the log is really empty
- */
- public function iCheckIfTheLogIsReallyEmpty()
- {
- $this->log = trim($this->supervisor->readLog(-24, 0));
- }
- /**
- * @Then I should get a success response
- */
- public function iShouldGetASuccessResponse()
- {
- if ($this->response !== true) {
- throw new \Exception(sprintf('Action "%s" was unsuccessful', $this->action));
- }
- }
- /**
- * @Then I should get a cleared log
- */
- public function iShouldGetAClearedLog()
- {
- if ($this->log !== 'INFO reopening log file') {
- throw new \Exception('Empty log cannot be confirmed');
- }
- }
- /**
- * @Then it should be stopped
- */
- public function itShouldBeStopped()
- {
- if ($this->supervisor->isConnected() === true) {
- throw new \Exception('Supervisor is still available');
- }
- }
- /**
- * @Then it should be running again
- */
- public function itShouldBeRunningAgain()
- {
- if ($this->supervisor->isConnected() !== true) {
- throw new \Exception('Supervisor is unavailable');
- }
- }
- /**
- * @Given I have a process called :process
- */
- public function iHaveAProcessCalled($process)
- {
- $this->processName = $this->processes[] = $process;
- $program = new Section\Program($process, [
- 'command' => exec('which '.$process),
- ]);
- $this->configuration->addSection($program);
- }
- /**
- * @When I wait for start
- */
- public function iWaitForStart()
- {
- usleep(100000);
- }
- /**
- * @When I get information about the processes
- */
- public function iGetInformationAboutTheProcesses()
- {
- $processInfo = $this->supervisor->getAllProcessInfo();
- $processNames = array_column($processInfo, 'name');
- $this->processInfo = array_combine($processNames, $processInfo);
- }
- /**
- * @Then I should see running
- */
- public function iShouldSeeRunning()
- {
- foreach ($this->processes as $process) {
- if (!isset($this->processInfo[$process]) or $this->processInfo[$process]['state'] < 10) {
- throw new \Exception(sprintf('Process "%s" is not running', $process));
- }
- }
- }
- /**
- * @Given autostart is disabled
- */
- public function autostartIsDisabled()
- {
- $program = $this->configuration->getSection('program:'.$this->processName);
- $program->setProperty('autostart', false);
- }
- /**
- * @When I get information about the processes before action
- */
- public function iGetInformationAboutTheProcessesBeforeAction()
- {
- $processInfo = $this->supervisor->getAllProcessInfo();
- $processNames = array_column($processInfo, 'name');
- $this->firstProcessInfo = array_combine($processNames, $processInfo);
- }
- /**
- * @When I :action the process
- */
- public function iTheProcess($action)
- {
- $this->action = $action.'Process';
- $this->response = call_user_func([$this->supervisor, $this->action], $this->processName, false);
- }
- /**
- * @Then I should see not running first
- */
- public function iShouldSeeNotRunningFirst()
- {
- foreach ($this->processes as $process) {
- if (!isset($this->firstProcessInfo[$process]) or $this->firstProcessInfo[$process]['state'] > 0) {
- throw new \Exception(sprintf('Process "%s" is running', $process));
- }
- }
- }
- /**
- * @When I :action the processes
- */
- public function iTheProcesses($action)
- {
- $this->action = $action.'AllProcesses';
- $this->response = call_user_func([$this->supervisor, $this->action], false);
- }
- /**
- * @Then I should get a success response for all
- */
- public function iShouldGetASuccessResponseForAll()
- {
- foreach ($this->response as $response) {
- if ($response['description'] !== 'OK') {
- throw new \Exception(sprintf('Action "%s" was unsuccessful', $this->action));
- }
- }
- }
- /**
- * @Then I should see running first
- */
- public function iShouldSeeRunningFirst()
- {
- foreach ($this->processes as $process) {
- if (!isset($this->firstProcessInfo[$process]) or $this->firstProcessInfo[$process]['state'] < 10) {
- throw new \Exception(sprintf('Process "%s" is not running before "%s"', $process, $this->action));
- }
- }
- }
- /**
- * @Then I should see not running
- */
- public function iShouldSeeNotRunning()
- {
- foreach ($this->processes as $process) {
- if (!isset($this->processInfo[$process]) or $this->processInfo[$process]['state'] > 0) {
- throw new \Exception(sprintf('Process "%s" is running', $process));
- }
- }
- }
- /**
- * @Given it is part of group called :grp
- */
- public function itIsPartOfGroupCalled($grp)
- {
- $this->groupName = $grp;
- $program = $this->configuration->getSection('program:'.$this->processName);
- $group = $this->configuration->getSection('group:'.$grp);
- if (is_null($group)) {
- $group = new Section\Group($grp, ['programs' => $this->processName]);
- $this->configuration->addSection($group);
- } else {
- $programs = $group->getProperty('programs');
- $programs[] = $this->processName;
- $group->setProperty('programs', $programs);
- }
- }
- /**
- * @When I :action the processes in the group
- */
- public function iTheProcessesInTheGroup($action)
- {
- $this->action = $action.'ProcessGroup';
- $this->response = call_user_func([$this->supervisor, $this->action], $this->groupName, false);
- }
- /**
- * @Then I should see them as part of the group
- */
- public function iShouldSeeThemAsPartOfTheGroup()
- {
- foreach ($this->response as $response) {
- if ($response['group'] !== $this->groupName) {
- throw new \Exception(sprintf('Process "%s" is not part of the group "%s"', $response['name'], $this->groupName));
- }
- }
- }
- }
|