/**
  * Return request index which is defined in config with updated query data, leaving global values untouched.
  *
  * @param $getrequests
  * @param $postrequests
  * @param $postdata
  * @param $requestsfromconfig
  * @return array requestindex, method and path.
  */
 private function is_request_in_config($capturelabel, $requests)
 {
     $requestsfromconfig = $this->get_capture_request_from_config($capturelabel, \behat_hooks::$featurefile);
     $requestfromhar = null;
     // Check if request is already set by user in config.
     if (!empty($requestsfromconfig)) {
         // Loop though each request from har and find the appropriate one.
         // We need this to replace query values except the global set by user.
         foreach ($requests as $index => $request) {
             if ($requestsfromconfig['method'] == $request['method'] && $requestsfromconfig['path'] == $request['path']) {
                 break;
             }
         }
         if (empty($request)) {
             util::performance_exception("Request from har is not found in config. Check: " . \behat_hooks::$featurefile . " : " . $capturelabel);
         }
         // Replace global values in query array with config values.
         foreach ($requestsfromconfig['query'] as $key => $value) {
             if (preg_match('/^\\$\\{.*\\}/', $value)) {
                 $request['query'][$key] = $value;
             }
         }
         return $request;
     }
     return array();
 }
 /**
  * Execute the command.
  *
  * @param InputInterface $input
  * @param OutputInterface $output
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // We don't need moodle for getting value.
     if ($value = $input->getOption('value')) {
         switch ($value) {
             case 'version':
                 $output->writeln(\moodlehq\behat_2jmx\util::get_tool_version());
                 break;
             case 'moodlepath':
                 $output->writeln(util::get_moodle_path());
                 break;
             case 'datapath':
                 $output->writeln(util::get_data_path());
                 break;
             default:
                 $output->writeln('<error>Not a valid option.</error><info> Should be wither version|moodlepath|datapath</info>');
                 return 1;
                 break;
         }
         return 0;
     }
     // Describe this script.
     define('PERFORMANCE_SITE_GENERATOR', true);
     define('CLI_SCRIPT', true);
     define('NO_OUTPUT_BUFFERING', true);
     define('IGNORE_COMPONENT_CACHE', true);
     // Load moodle config and all classes.
     $moodlepath = util::get_moodle_path();
     // Autoload files and ensure we load moodle config, as we will be using moodle code for behat context.
     require_once $moodlepath . '/config.php';
     require_once __DIR__ . '/inc.php';
     raise_memory_limit(MEMORY_HUGE);
     $status = false;
     // Do action.
     $behat2jmx = new \moodlehq\behat_2jmx\generator();
     $testplan = $input->getOption('testplan');
     $proxyurl = $input->getOption('proxyurl');
     // make sure proxyport and proxy url is provided.
     if (empty($proxyurl) || empty($testplan)) {
         $output->write($this->getHelp(), true);
         return 1;
     }
     $status = $behat2jmx->create_test_plan(strtolower($testplan), $proxyurl, $input->getOption('proxyport'), $input->getOption('force'));
     return $status;
 }
 /**
  * Updates the composer installer and the dependencies.
  *
  * @param string $dirroot root of directory where to check for composer install.
  * @return void exit() if something goes wrong
  */
 public static function testing_update_composer_dependencies($dirroot)
 {
     // To restore the value after finishing.
     $cwd = getcwd();
     $composerpath = $dirroot . DIRECTORY_SEPARATOR . 'composer.phar';
     $composerurl = 'https://getcomposer.org/composer.phar';
     // Switch to Moodle's dirroot for easier path handling.
     chdir($dirroot);
     // Download or update composer.phar. Unfortunately we can't use the curl
     // class in filelib.php as we're running within one of the test platforms.
     if (!file_exists($composerpath)) {
         $file = @fopen($composerpath, 'w');
         if ($file === false) {
             $errordetails = error_get_last();
             util::performance_exception(sprintf("Unable to create composer.phar\nPHP error: %s", $errordetails['message']));
         }
         $curl = curl_init();
         curl_setopt($curl, CURLOPT_URL, $composerurl);
         curl_setopt($curl, CURLOPT_FILE, $file);
         $result = curl_exec($curl);
         $curlerrno = curl_errno($curl);
         $curlerror = curl_error($curl);
         $curlinfo = curl_getinfo($curl);
         curl_close($curl);
         fclose($file);
         if (!$result) {
             $error = sprintf("Unable to download composer.phar\ncURL error (%d): %s", $curlerrno, $curlerror);
             util::performance_exception($error);
         } else {
             if ($curlinfo['http_code'] === 404) {
                 if (file_exists($composerpath)) {
                     // Deleting the resource as it would contain HTML.
                     unlink($composerpath);
                 }
                 $error = sprintf("Unable to download composer.phar\n" . "404 http status code fetching {$composerurl}");
                 util::performance_exception($error);
             }
         }
     } else {
         passthru("php composer.phar self-update", $code);
         if ($code != 0) {
             exit($code);
         }
     }
     // Update composer dependencies.
     passthru("php composer.phar install", $code);
     if ($code != 0) {
         exit($code);
     }
     // Return to our original location.
     chdir($cwd);
 }
 /**
  * After suite event.
  *
  * @param SuiteEvent $event
  * @AfterSuite
  */
 public static function after_suite(SuiteEvent $event)
 {
     $browsermobproxy = new browsermobproxyclient(util::get_option('proxyurl'));
     $browsermobproxy->close_connection();
     echo PHP_EOL . "Test plan has been generated under:" . PHP_EOL;
     echo " - " . util::get_final_testplan_path() . PHP_EOL;
 }
 /**
  * Method for creating a new HAR file
  *
  * @param string $label optional label
  *
  * @return string
  */
 public static function new_har($label = '')
 {
     $proxyurl = util::get_option('proxyurl');
     $proxyport = util::get_option('proxyport');
     $data = array("captureContent" => 'true', "initialPageRef" => $label, "captureHeaders" => 'true', "captureBinaryContent" => 'true');
     $url = $proxyurl . "/proxy/" . $proxyport . "/har";
     $response = self::curl_put($url, $data);
     return $response;
 }
 /**
  * Save final har data approved by user.
  *
  * @param string $capturelabel capture label
  * @param array $request request to be saved.
  * @return bool true
  */
 public static function save_final_har_data($capturelabel, $request)
 {
     $updatedtestplanconfigfile = self::get_final_testplan_path() . DIRECTORY_SEPARATOR . 'testplan.json-dist';
     // If we have already written something then update the new file.
     if (file_exists($updatedtestplanconfigfile)) {
         $config = file_get_contents($updatedtestplanconfigfile);
         $config = json_decode($config, true);
     } else {
         $config = util::get_config();
     }
     $config['scenarios'][\behat_hooks::$featurefile]['requests'][$capturelabel] = $request;
     // Update config so it can be used in final release.
     file_put_contents($updatedtestplanconfigfile, json_encode($config, JSON_PRETTY_PRINT));
     // Remove har file as it's work is done.
     unlink(self::get_har_file_path($capturelabel));
     return true;
 }
 /**
  * Execute behat command for featurename and return exit status.
  *
  * @return int status code.
  */
 protected function execute_behat_generator()
 {
     $cmd = "vendor/bin/behat --config " . util::get_tool_dir() . DIRECTORY_SEPARATOR . 'behat.yml ';
     $process = new Process($cmd);
     $moodlepath = util::get_moodle_path();
     $process->setWorkingDirectory($moodlepath);
     $process->setTimeout(null);
     $process->start();
     if ($process->getStatus() !== 'started') {
         echo "Error starting process";
         $process->signal(SIGKILL);
         exit(1);
     }
     while ($process->isRunning()) {
         $output = $process->getIncrementalOutput();
         $op = trim($output);
         if (!empty($op)) {
             echo $output;
         }
     }
     if ($process->getExitCode() !== 0) {
         echo $process->getErrorOutput();
     }
     return $process->getExitCode();
 }