[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |