[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/admin/tool/generator/classes/ -> testplan_backend.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Test plan generator.
  19   *
  20   * @package tool_generator
  21   * @copyright 2013 David Monllaó
  22   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  /**
  28   * Generates the files required by JMeter.
  29   *
  30   * @package tool_generator
  31   * @copyright 2013 David Monllaó
  32   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  33   */
  34  class tool_generator_testplan_backend extends tool_generator_backend {
  35  
  36      /**
  37       * @var The URL to the repository of the external project.
  38       */
  39      protected static $repourl = 'https://github.com/moodlehq/moodle-performance-comparison';
  40  
  41      /**
  42       * @var Number of users depending on the selected size.
  43       */
  44      protected static $users = array(1, 30, 100, 1000, 5000, 10000);
  45  
  46      /**
  47       * @var Number of loops depending on the selected size.
  48       */
  49      protected static $loops = array(5, 5, 5, 6, 6, 7);
  50  
  51      /**
  52       * @var Rampup period depending on the selected size.
  53       */
  54      protected static $rampups = array(1, 6, 40, 100, 500, 800);
  55  
  56      /**
  57       * Gets a list of size choices supported by this backend.
  58       *
  59       * @return array List of size (int) => text description for display
  60       */
  61      public static function get_size_choices() {
  62  
  63          $options = array();
  64          for ($size = self::MIN_SIZE; $size <= self::MAX_SIZE; $size++) {
  65              $a = new stdClass();
  66              $a->users = self::$users[$size];
  67              $a->loops = self::$loops[$size];
  68              $a->rampup = self::$rampups[$size];
  69              $options[$size] = get_string('testplansize_' . $size, 'tool_generator', $a);
  70          }
  71          return $options;
  72      }
  73  
  74      /**
  75       * Gets the list of courses that can be used used to generate a test.
  76       *
  77       * @return array The list of options as courseid => name
  78       */
  79      public static function get_course_options() {
  80          $courses = get_courses('all', 'c.sortorder ASC', 'c.id, c.shortname, c.fullname');
  81          if (!$courses) {
  82              print_error('error_nocourses', 'tool_generator');
  83          }
  84  
  85          $options = array();
  86          unset($courses[1]);
  87          foreach ($courses as $course) {
  88              $options[$course->id] = $course->fullname . '(' . $course->shortname . ')';
  89          }
  90          return $options;
  91      }
  92  
  93      /**
  94       * Getter for moodle-performance-comparison project URL.
  95       *
  96       * @return string
  97       */
  98      public static function get_repourl() {
  99          return self::$repourl;
 100      }
 101  
 102      /**
 103       * Creates the test plan file.
 104       *
 105       * @param int $courseid The target course id
 106       * @param int $size The test plan size
 107       * @return stored_file
 108       */
 109      public static function create_testplan_file($courseid, $size) {
 110          $jmxcontents = self::generate_test_plan($courseid, $size);
 111  
 112          $fs = get_file_storage();
 113          $filerecord = self::get_file_record('testplan', 'jmx');
 114          return $fs->create_file_from_string($filerecord, $jmxcontents);
 115      }
 116  
 117      /**
 118       * Creates the users data file.
 119       *
 120       * @param int $courseid The target course id
 121       * @param bool $updateuserspassword Updates the course users password to $CFG->tool_generator_users_password
 122       * @return stored_file
 123       */
 124      public static function create_users_file($courseid, $updateuserspassword) {
 125          $csvcontents = self::generate_users_file($courseid, $updateuserspassword);
 126  
 127          $fs = get_file_storage();
 128          $filerecord = self::get_file_record('users', 'csv');
 129          return $fs->create_file_from_string($filerecord, $csvcontents);
 130      }
 131  
 132      /**
 133       * Generates the test plan according to the target course contents.
 134       *
 135       * @param int $targetcourseid The target course id
 136       * @param int $size The test plan size
 137       * @return string The test plan as a string
 138       */
 139      protected static function generate_test_plan($targetcourseid, $size) {
 140          global $CFG;
 141  
 142          // Getting the template.
 143          $template = file_get_contents(__DIR__ . '/../testplan.template.jmx');
 144  
 145          // Getting the course modules data.
 146          $coursedata = self::get_course_test_data($targetcourseid);
 147  
 148          // Host and path to the site.
 149          $urlcomponents = parse_url($CFG->wwwroot);
 150          if (empty($urlcomponents['path'])) {
 151              $urlcomponents['path'] = '';
 152          }
 153  
 154          $replacements = array(
 155              $CFG->version,
 156              self::$users[$size],
 157              self::$loops[$size],
 158              self::$rampups[$size],
 159              $urlcomponents['host'],
 160              $urlcomponents['path'],
 161              get_string('shortsize_' . $size, 'tool_generator'),
 162              $targetcourseid,
 163              $coursedata->pageid,
 164              $coursedata->forumid,
 165              $coursedata->forumdiscussionid,
 166              $coursedata->forumreplyid
 167          );
 168  
 169          $placeholders = array(
 170              '{{MOODLEVERSION_PLACEHOLDER}}',
 171              '{{USERS_PLACEHOLDER}}',
 172              '{{LOOPS_PLACEHOLDER}}',
 173              '{{RAMPUP_PLACEHOLDER}}',
 174              '{{HOST_PLACEHOLDER}}',
 175              '{{SITEPATH_PLACEHOLDER}}',
 176              '{{SIZE_PLACEHOLDER}}',
 177              '{{COURSEID_PLACEHOLDER}}',
 178              '{{PAGEACTIVITYID_PLACEHOLDER}}',
 179              '{{FORUMACTIVITYID_PLACEHOLDER}}',
 180              '{{FORUMDISCUSSIONID_PLACEHOLDER}}',
 181              '{{FORUMREPLYID_PLACEHOLDER}}'
 182          );
 183  
 184          // Fill the template with the target course values.
 185          return str_replace($placeholders, $replacements, $template);
 186      }
 187  
 188      /**
 189       * Generates the user's credentials file with all the course's users
 190       *
 191       * @param int $targetcourseid
 192       * @param bool $updateuserspassword Updates the course users password to $CFG->tool_generator_users_password
 193       * @return string The users csv file contents.
 194       */
 195      protected static function generate_users_file($targetcourseid, $updateuserspassword) {
 196          global $CFG;
 197  
 198          $coursecontext = context_course::instance($targetcourseid);
 199  
 200          $users = get_enrolled_users($coursecontext, '', 0, 'u.id, u.username, u.auth', 'u.username ASC');
 201          if (!$users) {
 202              print_error('coursewithoutusers', 'tool_generator');
 203          }
 204  
 205          $lines = array();
 206          foreach ($users as $user) {
 207  
 208              // Updating password to the one set in config.php.
 209              if ($updateuserspassword) {
 210                  $userauth = get_auth_plugin($user->auth);
 211                  if (!$userauth->user_update_password($user, $CFG->tool_generator_users_password)) {
 212                      print_error('errorpasswordupdate', 'auth');
 213                  }
 214              }
 215  
 216              // Here we already checked that $CFG->tool_generator_users_password is not null.
 217              $lines[] = $user->username . ',' . $CFG->tool_generator_users_password;
 218          }
 219  
 220          return implode(PHP_EOL, $lines);
 221      }
 222  
 223      /**
 224       * Returns a tool_generator file record
 225       *
 226       * @param string $filearea testplan or users
 227       * @param string $filetype The file extension jmx or csv
 228       * @return stdClass The file record to use when creating tool_generator files
 229       */
 230      protected static function get_file_record($filearea, $filetype) {
 231  
 232          $systemcontext = context_system::instance();
 233  
 234          $filerecord = new stdClass();
 235          $filerecord->contextid = $systemcontext->id;
 236          $filerecord->component = 'tool_generator';
 237          $filerecord->filearea = $filearea;
 238          $filerecord->itemid = 0;
 239          $filerecord->filepath = '/';
 240  
 241          // Random generated number to avoid concurrent execution problems.
 242          $filerecord->filename = $filearea . '_' . date('YmdHi', time()) . '_' . rand(1000, 9999) . '.' . $filetype;
 243  
 244          return $filerecord;
 245      }
 246  
 247      /**
 248       * Gets the data required to fill the test plan template with the database contents.
 249       *
 250       * @param int $targetcourseid The target course id
 251       * @return stdClass The ids required by the test plan
 252       */
 253      protected static function get_course_test_data($targetcourseid) {
 254          global $DB, $USER;
 255  
 256          $data = new stdClass();
 257  
 258          // Getting course contents info as the current user (will be an admin).
 259          $course = new stdClass();
 260          $course->id = $targetcourseid;
 261          $courseinfo = new course_modinfo($course, $USER->id);
 262  
 263          // Getting the first page module instance.
 264          if (!$pages = $courseinfo->get_instances_of('page')) {
 265              print_error('error_nopageinstances', 'tool_generator');
 266          }
 267          $data->pageid = reset($pages)->id;
 268  
 269          // Getting the first forum module instance and it's first discussion and reply as well.
 270          if (!$forums = $courseinfo->get_instances_of('forum')) {
 271              print_error('error_noforuminstances', 'tool_generator');
 272          }
 273          $forum = reset($forums);
 274  
 275          // Getting the first discussion (and reply).
 276          if (!$discussions = forum_get_discussions($forum, 'd.timemodified ASC', false, -1, 1)) {
 277              print_error('error_noforumdiscussions', 'tool_generator');
 278          }
 279          $discussion = reset($discussions);
 280  
 281          $data->forumid = $forum->id;
 282          $data->forumdiscussionid = $discussion->discussion;
 283          $data->forumreplyid = $discussion->id;
 284  
 285          // According to the current test plan.
 286          return $data;
 287      }
 288  
 289      /**
 290       * Checks if the selected target course is ok.
 291       *
 292       * @param int|string $course
 293       * @param int $size
 294       * @return array Errors array or false if everything is ok
 295       */
 296      public static function has_selected_course_any_problem($course, $size) {
 297          global $DB;
 298  
 299          $errors = array();
 300  
 301          if (!is_numeric($course)) {
 302              if (!$course = $DB->get_field('course', 'id', array('shortname' => $course))) {
 303                  $errors['courseid'] = get_string('error_nonexistingcourse', 'tool_generator');
 304                  return $errors;
 305              }
 306          }
 307  
 308          $coursecontext = context_course::instance($course, IGNORE_MISSING);
 309          if (!$coursecontext) {
 310              $errors['courseid'] = get_string('error_nonexistingcourse', 'tool_generator');
 311              return $errors;
 312          }
 313  
 314          if (!$users = get_enrolled_users($coursecontext, '', 0, 'u.id')) {
 315              $errors['courseid'] = get_string('coursewithoutusers', 'tool_generator');
 316          }
 317  
 318          // Checks that the selected course has enough users.
 319          $coursesizes = tool_generator_course_backend::get_users_per_size();
 320          if (count($users) < self::$users[$size]) {
 321              $errors['size'] = get_string('notenoughusers', 'tool_generator');
 322          }
 323  
 324          if (empty($errors)) {
 325              return false;
 326          }
 327  
 328          return $errors;
 329      }
 330  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1