/**
  * Gives access to moodle codebase, ensures all is ready and sets up the test lock.
  *
  * Includes config.php to use moodle codebase with $CFG->behat_*
  * instead of $CFG->prefix and $CFG->dataroot, called once per suite.
  *
  * @param SuiteEvent $event event before suite.
  * @static
  * @throws Exception
  * @BeforeSuite
  */
 public static function before_suite(SuiteEvent $event)
 {
     global $CFG;
     define('CLI_SCRIPT', 1);
     $moodlepath = util::get_moodle_path();
     require_once $moodlepath . '/config.php';
     require_once __DIR__ . '/inc.php';
     // Now that we are MOODLE_INTERNAL.
     require_once $CFG->libdir . '/behat/classes/behat_command.php';
     require_once $CFG->libdir . '/behat/classes/behat_selectors.php';
     require_once $CFG->libdir . '/behat/classes/behat_context_helper.php';
     require_once $CFG->libdir . '/behat/classes/util.php';
     require_once $CFG->libdir . '/testing/classes/test_lock.php';
     require_once $CFG->libdir . '/testing/classes/nasty_strings.php';
 }
 /**
  * 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);
 }
 /**
  * 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_generator\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;
     }
     // Include moodle config.
     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.
     if (!($moodlepath = util::get_moodle_path())) {
         util::performance_exception("Moodlepath should have been set by now.");
     }
     // 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.
     $sitedatagenerator = new \moodlehq\behat_generator\generator();
     if ($input->getOption('drop')) {
         // Don't check for any option, just try drop site..
         $force = $input->getOption('force') ? true : false;
         $status = $sitedatagenerator->run_drop($output, $force);
     } else {
         if ($input->getOption('dropsite')) {
             // Don't check for any option, just try drop site..
             $force = $input->getOption('force') ? true : false;
             $status = $sitedatagenerator->run_dropsite($output, $force);
         }
     }
     // Check if site enable/disable is needed.
     if ($input->getOption('enable')) {
         $status = $sitedatagenerator->run_enable($output, $input->getOption('enable'));
     } else {
         if ($input->getOption('disable')) {
             $status = $sitedatagenerator->run_disable($output);
         }
     }
     if ($input->getOption('install')) {
         $status = $sitedatagenerator->run_install($output);
     }
     // Check if testdata needs to be generated.
     if ($input->getOption('testdata')) {
         $status = $sitedatagenerator->run_testdata($output, $input->getOption('testdata'), $input->getOption('force'));
     }
     // Finally, check if backup/restore is needed.
     if ($input->getOption('backup')) {
         $status = $sitedatagenerator->run_backup($output, $input->getOption('backup'));
     } else {
         if ($input->getOption('restore')) {
             $status = $sitedatagenerator->run_restore($output, $input->getOption('restore'));
         }
     }
     if ($status === false) {
         $output->write($this->getHelp(), true);
     }
     return $status;
 }
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * Data generators for acceptance testing.
 *
 * @package   core_generator
 * @copyright 2015 rajesh Taneja
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once __DIR__ . '/util.php';
$moodlepath = \moodlehq\behat_generator\util::get_moodle_path();
require_once $moodlepath . '/lib/tests/behat/behat_data_generators.php';
use Behat\Gherkin\Node\TableNode;
use Behat\Behat\Exception\PendingException;
use moodlehq\behat_generator\generator;
/**
 * Class containing bulk steps for setting up site for performance testing.
 *
 * @package   core_generator
 * @copyright 2015 rajesh Taneja
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class behat_tool_generator extends behat_base
{
    /**
     * Creates the specified element. More info about available elements in http://docs.moodle.org/dev/Acceptance_testing#Fixtures.
 /**
  * Execute behat command for featurename and return exit status.
  *
  * @param string $featurename name of the feature
  * @param string $featurepath path of feature file
  * @return int status code.
  */
 protected function execute_behat_generator($featurename, $featurepath)
 {
     $cmd = "vendor/bin/behat --config " . util::get_tool_dir() . DIRECTORY_SEPARATOR . 'behat.yml ' . $featurepath;
     $process = new symfonyprocess($cmd);
     $moodlepath = util::get_moodle_path();
     $process->setWorkingDirectory($moodlepath);
     $process->setTimeout(null);
     $process->start();
     if ($process->getStatus() !== 'started') {
         echo "Error starting process: {$featurename}";
         $process->signal(SIGKILL);
         exit(1);
     }
     while ($process->isRunning()) {
         $output = $process->getIncrementalOutput();
         // Don't show start data everytime.
         $output = preg_replace('/[a-z0-9.\\(\\)].*/im', '', $output);
         $op = trim($output);
         if (!empty($op)) {
             echo $output;
         }
     }
     return $process->getExitCode();
 }
 /**
  * Restore state of current site. Dataroot and database.
  *
  * @param string $statename
  * @return int 0 on success else error code.
  */
 public static function restore_site_state($statename = "default")
 {
     // Clean up the dataroot folder.
     util::drop_dir(self::get_dataroot() . '/');
     // Restore database and dataroot state, before proceeding.
     echo "Restoring database state" . PHP_EOL;
     if (!self::restore_database_state($statename)) {
         util::performance_exception("Error restoring state db: " . $statename);
     }
     echo "Restoring dataroot state" . PHP_EOL;
     if (!self::restore_dataroot($statename)) {
         util::performance_exception("Error restoring state data: " . $statename);
     }
     echo "Site restored to {$statename} state" . PHP_EOL;
     return 0;
 }