public function writeToLog($msg) { // what are we doing? $log = usingLog()->startAction($msg); // all done $log->endAction(); }
/** * get * * @param mixed $url URL to request * @param array $params GET params to add to the URL * @param array $headers HTTP headers to use * * @return object|string Response sent by the server. If it's JSON, we'll decode it */ public function get($url, $params = array(), $headers = array()) { if (count($headers)) { // "FromCurl does not support headers yet" throw new E5xx_NotImplemented(__METHOD__); } // create the full URL if (count($params) > 0) { $url = $url . '?' . http_build_query($params); } // what are we doing? $log = usingLog()->startAction("HTTP GET '{$url}'"); // create a new cURL resource $ch = curl_init(); // set URL and other appropriate options curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, 0); // grab URL and pass it to the browser $response = curl_exec($ch); $error = curl_error($ch); // close cURL resource, and free up system resources curl_close($ch); if ($error) { throw new E5xx_ActionFailed(__METHOD__ . ': ' . $error); } // Try and decode it $decoded = json_decode($response); if ($decoded) { $response = $decoded; } // all done $log->endAction(); return $response; }
public function reportShouldAlwaysSucceed() { // what are we doing? $log = usingLog()->startAction("this story is expected to always succeed"); // all done $log->endAction(); }
public function writeDataToFile($params) { // shorthand $filename = $this->args[0]; // what are we doing? $printer = new DataPrinter(); $logParams = $printer->convertToString($params); $log = usingLog()->startAction("create YAML file '{$filename}' with contents '{$logParams}'"); // create an instance of the Symfony YAML writer $writer = new Dumper(); // create the YAML data $yamlData = $writer->dump($params, 2); if (!is_string($yamlData) || strlen($yamlData) < 6) { throw new E5xx_ActionFailed(__METHOD__, "unable to convert data to YAML"); } // prepend the YAML marker $yamlData = '---' . PHP_EOL . $yamlData; // write the file // // the loose FALSE test here is exactly what we want, because we want to catch // both the situation when the write fails, and when there's zero bytes written if (!file_put_contents($filename, $yamlData)) { throw new E5xx_ActionFailed(__METHOD__, "unable to write file '{$filename}'"); } // all done $log->endAction(); }
public function getDataFor($metric, $startTime, $endTime) { // when are we looking for? $humanStartTime = date('Y-m-d H:i:s', $startTime); $humanEndTime = date('Y-m-d H:i:s', $endTime); // what are we doing? $log = usingLog()->startAction("get raw data from graphite for '{$metric}' between '{$humanStartTime}' and '{$humanEndTime}'"); // find out where graphite is $graphiteUrl = fromConfig()->getModuleSetting('graphite.url'); if (substr($graphiteUrl, -1, 1) !== '/') { $graphiteUrl .= '/'; } // get the requested data $response = fromHttp()->get("{$graphiteUrl}render?format=json&target={$metric}&from={$startTime}&until={$endTime}"); // are there any stats in the response? assertsArray($response->chunks)->isExpectedType(); assertsArray($response->chunks)->isNotEmpty(); // assemble the raw chunks into one string to decode $rawStats = implode("", $response->chunks); assertsString($rawStats)->isValidJson(); $stats = json_decode($rawStats); // all done $log->endAction(); return $stats; }
public function getProgramIsRunning($programName) { // what are we doing? $log = usingLog()->startAction("is program '{$programName}' running under supervisor on host '{$this->args[0]}'?"); // get the host details $hostDetails = $this->getHostDetails(); //run the supervisorctl command $result = usingHost($hostDetails->hostId)->runCommandAndIgnoreErrors("sudo supervisorctl status"); // |egrep '^$programName' | awk '{print \\$2}'"); // did the command succeed? if ($result->didCommandFail()) { $msg = "command failed with return code '{$result->returnCode}' and output '{$result->output}'"; $log->endAction($msg); throw new E5xx_ActionFailed(__METHOD__); } // reduce the output down $lines = explode("\n", $result->output); $lines = FilterForMatchingRegex::against($lines, "/^{$programName} /"); $lines = FilterColumns::from($lines, "1", ' '); if (empty($lines)) { $log->endAction("supervisor does not know about '{$programName}'"); return false; } // what happened? if ($lines[0] == 'RUNNING') { $log->endAction('current status is RUNNING'); return true; } // if we get here, then the program is not RUNNING, and we // treat that as a failure $log->endAction('current status is ' . $lines[0]); return false; }
public function createVm($vmName, $osName, $amiId, $instanceType, $securityGroup) { // what are we doing? $log = usingLog()->startAction("start EC2 VM '{$vmName}', running guest OS '{$osName}', using AMI ID '{$amiId}' and security group '{$securityGroup}'"); // get the aws settings $awsSettings = fromConfig()->getModuleSetting('aws'); // put the details into an array $vmDetails = new Ec2VmDetails(); $vmDetails->hostId = $vmName; $vmDetails->environment = $this->st->getTestEnvironmentName(); $vmDetails->osName = $osName; $vmDetails->amiId = $amiId; $vmDetails->type = 'Ec2Vm'; $vmDetails->instanceType = $instanceType; $vmDetails->securityGroup = $securityGroup; $vmDetails->keyPairName = $awsSettings->ec2->keyPairName; $vmDetails->sshUsername = $awsSettings->ec2->sshUsername; $vmDetails->sshKeyFile = $awsSettings->ec2->sshKeyFile; $vmDetails->sshOptions = array("-i '" . $awsSettings->ec2->sshKeyFile . "'"); $vmDetails->scpOptions = array("-i '" . $awsSettings->ec2->sshKeyFile . "'"); // create our host adapter $host = HostLib::getHostAdapter($this->st, $vmDetails->type); // create our virtual machine $host->createHost($vmDetails); // all done $log->endAction(); }
public function query($sql) { // what are we doing? $log = usingLog()->startAction(["run SQL against '{$this->args[0]}':", $sql]); // connect $conn = new mysqli($this->args[0], $this->args[1], $this->args[2]); if ($conn->connect_errno) { $log->endAction('unable to connect to database :( - ' . $conn->connect_error); throw new E5xx_ActionFailed(__METHOD__); } // switch database if (isset($this->args[2])) { if (!$conn->select_db($this->args[3])) { $log->endAction("unable to switch to database '{$this->args[2]}' - " . $conn->error); throw new E5xx_ActionFailed(__METHOD__); } } // run the SQL $result = $conn->query($sql); // what happened? if (!$result) { $log->endAction("failed to run query"); throw new E5xx_ActionFailed(__METHOD__, "query failed - " . $conn->error); } // success $log->endAction(); return $result; }
public function runSilently($cmd) { // enforce our inputs Contract::RequiresValue($cmd, is_string($cmd)); // what are we doing? $log = usingLog()->startAction("run command: {$cmd}"); // the output that we will return to the caller $output = ''; // how we will talk with the command $pipesSpec = [['file', 'php://stdin', 'r'], ['pipe', 'w'], ['pipe', 'w']]; $pipes = []; // start the process $process = proc_open($cmd, $pipesSpec, $pipes); // was there a problem? // // NOTE: this only occurs when something like a fork() failure // happens, which makes it very difficult to test for in a // unit test // @codeCoverageIgnoreStart if (!$process) { $return = new CommandResult(255, ''); return $return; } // @codeCoverageIgnoreEnd // we do not want to block whilst reading from the child process's // stdout and stderr stream_set_blocking($pipes[1], 0); stream_set_blocking($pipes[2], 0); // at this point, our command may be running ... // OR our command may have failed with an error // // best thing to do is to keep reading from our pipes until // the pipes no longer exist while (!feof($pipes[1]) || !feof($pipes[2])) { // block until there is something to read, or until the // timeout has happened // // this makes sure that we do not burn CPU for the sake of it $readable = [$pipes[1], $pipes[2]]; $writeable = $except = []; stream_select($readable, $writeable, $except, 1); // check all the streams for output if ($line = fgets($pipes[1])) { $log->captureOutput(rtrim($line)); $output = $output . $line; } if ($line = fgets($pipes[2])) { $log->captureOutput(rtrim($line)); $output = $output . $line; } } // at this point, our pipes have been closed // we can assume that the child process has finished $retval = proc_close($process); // all done $log->endAction("return code is '{$retval}'"); $result = new CommandResult($retval, $output); return $result; }
public function createDefinition() { // what are we doing? $log = usingLog()->startAction("create empty provisioning definition"); // all done $log->endAction(); return new ProvisioningDefinition(); }
/** * @return void */ public function removeCurrentTestEnvironment() { // what are we doing? $log = usingLog()->startAction("remove current test environment from targets table"); // get the details to remove $testEnvName = $this->st->getTestEnvironmentName(); // remove it usingRuntimeTable($this->entryKey)->removeItem($testEnvName); // all done $log->endAction(); }
public function generateUuid() { // what are we doing? $log = usingLog()->startAction("generate a UUID"); // do we have the UUID extension? $uuid = uuid_create(); // log it $log->endAction("'{$uuid}'"); // all done return $uuid; }
public function getTmpFileName() { // what are we doing? $log = usingLog()->startAction("generate a temporary filename"); // create it $filename = tempnam(null, 'storyplayer-data-'); // log it $log->endAction("'{$filename}'"); // all done return $filename; }
public function __call($moduleName, $params) { // what are we doing? $log = usingLog()->startAction("for each host with role '{$this->roleName}' ..."); // get the hosts details $hostsDetails = $this->retrieveHostsDetails(); // build the iterator that we're going to use $return = new DelayedHostsModuleIterator($this->st, $hostsDetails, $moduleName); // all done $log->endAction(); return $return; }
public function startHornetDrone($clientName, $clientParams) { // what are we doing? $log = usingLog()->startAction("start hornet-drone '{$clientName}' with params '(" . implode(', ', $clientParams) . ")"); // build the command to run $appSettings = fromStoryplayer()->getAppSettings('hornet'); $command = $appSettings->path . '/hornet-drone ' . implode(' ', $clientParams); // run the command in a screen session usingShell()->startInScreen($clientName, $command); // all done $log->endAction(); }
public function canSendmultiNonBlocking($socket, $message) { // what are we doing? $log = usingLog()->startAction("make sure ZMQ::sendmulti() does not block"); // send the data $sent = $socket->sendmulti($message, ZMQ::MODE_NOBLOCK); // would it have blocked? if (!$sent) { throw new E5xx_ExpectFailed(__METHOD__, "sendmulti() would not block", "sendmulti() would have blocked"); } // all done $log->endAction(); }
public function set($fieldName, $value) { // convert $value into something that can appear in our logs $convertor = new DataPrinter(); $printable = $convertor->convertToString($value); // what are we doing? $log = usingLog()->startAction("set checkpoint field '{$fieldName}' to '{$printable}'"); // get the checkpoint $checkpoint = getCheckpoint(); // set the value $checkpoint->{$fieldName} = $value; // all done $log->endAction(); }
public function get($fieldName) { // what are we doing? $log = usingLog()->startAction("get value of checkpoint field '{$fieldName}'"); // get the checkpoint $checkpoint = getCheckpoint(); // does the value exist? if (!isset($checkpoint->{$fieldName})) { throw new E5xx_ActionFailed(__METHOD__); } // all done $log->endAction(); return $checkpoint->{$fieldName}; }
public function removeFile($filename) { // what are we doing? $log = usingLog()->startAction("delete the file '{$filename}'"); // remove the file if (file_exists($filename)) { unlink($filename); } else { $log->endAction("file not found"); } // all done $log->endAction(); return $this; }
public function programIsNotRunning($programName) { // what are we doing? $log = usingLog()->startAction("make sure program '{$programName}' is not running on host '{$this->args[0]}'"); // make sure we have valid host details $hostDetails = $this->getHostDetails(); // is it running? $running = fromSupervisor($hostDetails->hostId)->getProgramIsRunning($programName); if ($running) { $log->endAction(); throw new E5xx_ExpectFailed(__METHOD__, 'program is not running', 'program is running'); } // all done $log->endAction(); }
/** * return a user from the test users file * * @param string $userId * the ID of the user to retrieve * @return \DataSift\Stone\ObjectLib\BaseObject */ public function getUser($userId) { // what are we doing? $log = usingLog()->startAction("get user ID '{$userId}'"); // do we have this user? $users = $this->st->getTestUsers(); if (!isset($users->{$userId})) { $msg = "user ID '{$userId}' not found"; $log->endAction($msg); throw new E5xx_ActionFailed($msg); } // all done $log->endAction($users->{$userId}); return $users->{$userId}; }
public function stopProgram($programName) { // what are we doing? $log = usingLog()->startAction("stop program '{$programName}' on host '{$this->args[0]}'"); // get the host details $hostDetails = $this->getHostDetails(); // stop the program $result = usingHost($hostDetails->hostId)->runCommand("sudo supervisorctl stop '{$programName}'"); // did the command succeed? if ($result->didCommandFail()) { throw new E5xx_ActionFailed(__METHOD__, "failed to start process '{$programName} (via supervisord)'"); } // all done $log->endAction(); return true; }
public function connect($dsn) { // what are we doing? $log = usingLog()->startAction("connect to Redis server '{$dsn}'"); // make the connection try { $conn = new PredisClient($dsn); } catch (Exception $e) { $log->endAction("connection failed: " . $e->getMessage()); throw new E5xx_ActionFailed(__METHOD__); } // if we get here, all is good // all done $log->endAction("connected"); return $conn; }
public function getEc2Client() { // the client to return static $ec2Client = null; if (!$ec2Client) { // what are we doing? $log = usingLog()->startAction("create AWS client for EC2"); // get the Aws client factory $awsFactory = fromAws()->getAwsClientFactory(); // create the EC2 client $ec2Client = $awsFactory->get('ec2'); $log->endAction(); } // all done return $ec2Client; }
public function __construct($st, $args) { // call our parent constructor first parent::__construct($st, $args); // $args[0] contains the rolename // we need to replace this with the hostId for FromHost() to // function correctly // what are we doing? $log = usingLog()->startAction("select first host with role '{$this->args[0]}' ..."); // get the hosts details $hostDetails = $this->retrieveFirstHost($this->args[0]); // we only need to remember the hostId $this->args[0] = $hostDetails->hostId; // all done $log->endAction("selected host '{$this->args[0]}'"); }
/** * @return \DataSift\WebDriver\WebDriverElement */ public function returnNthVisibleElement($nth, $elements) { // what are we doing? $count = count($elements); $log = usingLog()->startAction("looking for element '{$nth}' out of array of {$count} element(s)"); // special case - not enough elements, even if they were all // visible if ($nth >= count($elements)) { $log->endAction("not enough elements :("); throw new E5xx_ActionFailed(__METHOD__, "no matching element found"); } // let's track which visible element we're looking at $checkedIndex = 0; // if the page contains multiple matches, return the first one // that the user can see foreach ($elements as $element) { if (!$element->displayed()) { // DO NOT increment $checkedIndex here // // we only increment it for elements that are visible continue; } // skip hidden input fields // if ($element->name() == 'input') { // try { // $typeAttr = $element->attribute('type'); // if ($typeAttr == 'hidden') { // // skip this // continue; // } // } // catch (Exception $e) { // // no 'type' attribute // // // // not fatal // } // } if ($checkedIndex == $nth) { // a match! $log->endAction(); return $element; } } $msg = "no matching element found"; $log->endAction($msg); throw new E5xx_ActionFailed(__METHOD__, $msg); }
public function when($what, $callback) { // what are we doing? $log = usingLog()->startAction("expect {$what} to fail"); // let's do it try { $callback(); } catch (E5xx_ProseException $e) { // do nothing $log->endAction("{$what} failed (this is the expected behaviour)"); return; } // do not catch any other exceptions ... they are unexpected // failures // if we get here, then the action did not fail - and THAT // is a failure throw new E5xx_ExpectFailed(__METHOD__, "{$what} failed", "{$what} did not fail"); }
public function __call($methodName, $params) { // what are we doing? $log = usingLog()->startAction(["run redis command", $methodName, "with params:", $params]); // do we have such a redis call? if (!method_exists($this->args[0], $methodName)) { throw new E5xx_ActionFailed(__METHOD__, "no such redis command '{$methodName}'"); } // make the call try { $return = call_user_method_array($methodName, $this->args[0], $params); // all done $log->endAction($return); return $return; } catch (Exception $e) { throw new E5xx_ActionFailed(__METHOD__, $e->getMessage()); } }
public function connect($dsn, $username = null, $password = null, $options = []) { // what are we doing? $log = usingLog()->startAction("connect to database '{$dsn}'"); // make the connection try { $db = new PDO($dsn, $username, $password, $options); } catch (PDOException $e) { $log->endAction("connection failed: " . $e->getMessage()); throw new E5xx_ActionFailed(__METHOD__); } // if we get here, all is good // // make sure that PDO throws exceptions when things go wrong $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // all done $log->endAction("connected"); return $db; }
public function requirementsAreMet() { // what are we doing? $log = usingLog()->startAction("make sure the UUID module's requirements are installed"); // do we have the UUID extension? if (!function_exists('uuid_create')) { // we really want this $log->endAction("PECL uuid extension missing"); throw new E5xx_ExpectFailed(__METHOD__, "PECL uuid extension installed", "extension is not installed"); } // is Stone's TokenLib available? if (!class_exists('DataSift\\Stone\\TokenLib\\TokenGenerator')) { // we really want this $log->endAction("DataSift\\Stone\\TokenLib missing"); throw new E5xx_ExpectFailed(__METHOD__, "DataSift's Stone library includes TokenLib", "TokenLib not found"); } // if we get here, we are good $log->endAction(); }