From 217a5f97adcc26aeaae055ab7e9f419d57031d7e Mon Sep 17 00:00:00 2001 From: David Monllao Date: Wed, 28 Aug 2013 10:09:05 +0800 Subject: [PATCH 1/4] MDL-41421 tool_generator: Refactoring make_form to make_course_form Also: - Added a soft password for the newly generated users so we can use them to log in the site when running performance tests. - Added a method to see the courses-users relation from outside course_backend class. --- admin/tool/generator/classes/course_backend.php | 17 +++++++++++++++++ .../{make_form.php => make_course_form.php} | 14 +++++++++++++- admin/tool/generator/maketestcourse.php | 6 +++--- 3 files changed, 33 insertions(+), 4 deletions(-) rename admin/tool/generator/classes/{make_form.php => make_course_form.php} (88%) diff --git a/admin/tool/generator/classes/course_backend.php b/admin/tool/generator/classes/course_backend.php index 07e1e7b1c85..5171b835a85 100644 --- a/admin/tool/generator/classes/course_backend.php +++ b/admin/tool/generator/classes/course_backend.php @@ -111,6 +111,15 @@ class tool_generator_course_backend extends tool_generator_backend { parent::__construct($size, $fixeddataset, $progress); } + /** + * Returns the relation between users and course sizes. + * + * @return array + */ + public static function get_users_per_size() { + return self::$paramusers; + } + /** * Gets a list of size choices supported by this backend. * @@ -280,6 +289,8 @@ class tool_generator_course_backend extends tool_generator_backend { * @param int $last Number of last user */ private function create_user_accounts($first, $last) { + global $CFG; + $this->log('createaccounts', (object)array('from' => $first, 'to' => $last), true); $count = $last - $first + 1; $done = 0; @@ -294,6 +305,12 @@ class tool_generator_course_backend extends tool_generator_backend { // Create user account. $record = array('firstname' => get_string('firstname', 'tool_generator'), 'lastname' => $number, 'username' => $username); + + // We add a user password if it has been specified. + if (!empty($CFG->tool_generator_users_password)) { + $record['password'] = $CFG->tool_generator_users_password; + } + $user = $this->generator->create_user($record); $this->userids[$number] = (int)$user->id; $this->dot($done, $count); diff --git a/admin/tool/generator/classes/make_form.php b/admin/tool/generator/classes/make_course_form.php similarity index 88% rename from admin/tool/generator/classes/make_form.php rename to admin/tool/generator/classes/make_course_form.php index 879364d2174..7f7f629c5b3 100644 --- a/admin/tool/generator/classes/make_form.php +++ b/admin/tool/generator/classes/make_course_form.php @@ -25,8 +25,13 @@ require_once($CFG->libdir . '/formslib.php'); * @copyright 2013 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class tool_generator_make_form extends moodleform { +class tool_generator_make_course_form extends moodleform { + /** + * Course generation tool form definition. + * + * @return void + */ public function definition() { $mform = $this->_form; @@ -41,6 +46,13 @@ class tool_generator_make_form extends moodleform { $mform->addElement('submit', 'submit', get_string('createcourse', 'tool_generator')); } + /** + * Form validation. + * + * @param array $data + * @param array $files + * @return void + */ public function validation($data, $files) { global $DB; $errors = array(); diff --git a/admin/tool/generator/maketestcourse.php b/admin/tool/generator/maketestcourse.php index 82af097cb8f..c5f9c82ab10 100644 --- a/admin/tool/generator/maketestcourse.php +++ b/admin/tool/generator/maketestcourse.php @@ -32,7 +32,7 @@ require('../../../config.php'); require_once($CFG->libdir . '/adminlib.php'); // Initialise page and check permissions. -admin_externalpage_setup('toolgenerator'); +admin_externalpage_setup('toolgeneratorcourse'); // Start page. echo $OUTPUT->header(); @@ -40,7 +40,7 @@ echo $OUTPUT->heading(get_string('maketestcourse', 'tool_generator')); // Information message. $context = context_system::instance(); -echo $OUTPUT->box(format_text(get_string('explanation', 'tool_generator'), +echo $OUTPUT->box(format_text(get_string('courseexplanation', 'tool_generator'), FORMAT_MARKDOWN, array('context' => $context))); // Check debugging is set to DEVELOPER. @@ -51,7 +51,7 @@ if (!debugging('', DEBUG_DEVELOPER)) { } // Set up the form. -$mform = new tool_generator_make_form('maketestcourse.php'); +$mform = new tool_generator_make_course_form('maketestcourse.php'); if ($data = $mform->get_data()) { // Do actual work. echo $OUTPUT->heading(get_string('creating', 'tool_generator')); From 8520de1ee40eac335bbcac0070326c35d63d2c54 Mon Sep 17 00:00:00 2001 From: David Monllao Date: Wed, 28 Aug 2013 16:48:58 +0800 Subject: [PATCH 2/4] MDL-41421 tool_generator: Import .jmx template Ideally we should generate all the XML based on modular components so we can also switch templates between different sizes, this is a first step and more work should be done in future in this direction. --- admin/tool/generator/testplan.template.jmx | 900 +++++++++++++++++++++ 1 file changed, 900 insertions(+) create mode 100644 admin/tool/generator/testplan.template.jmx diff --git a/admin/tool/generator/testplan.template.jmx b/admin/tool/generator/testplan.template.jmx new file mode 100644 index 00000000000..d08a9b50f56 --- /dev/null +++ b/admin/tool/generator/testplan.template.jmx @@ -0,0 +1,900 @@ + + + + + + false + true + + + + runtimestamp + ${__time()} + = + + + users + {{USERS_PLACEHOLDER}} + = + + + loops + {{LOOPS_PLACEHOLDER}} + = + + + rampup + {{RAMPUP_PLACEHOLDER}} + = + + + host + {{HOST_PLACEHOLDER}} + = + + + sitepath + {{SITEPATH_PLACEHOLDER}} + = + + + courseid + {{COURSEID_PLACEHOLDER}} + = + + + pageactivityid + {{PAGEACTIVITYID_PLACEHOLDER}} + = + + + forumactivityid + {{FORUMACTIVITYID_PLACEHOLDER}} + = + + + forumdiscussionid + {{FORUMDISCUSSIONID_PLACEHOLDER}} + = + + + forumreplyid + {{FORUMREPLYID_PLACEHOLDER}} + = + + + + + + + + + all active threads (shared) + + throughput + 120.0 + 0.0 + + + + + Used to fill the caches, logs in every user + continue + + false + 1 + + ${users} + ${rampup} + 1378187955000 + 1378187955000 + false + + + + + + + + + ${host} + + + + + + ${sitepath} + 4 + + + + , + + ${__P(usersfile,YOU_FORGOT_TO_SPECIFY_USERS_CSV_FILE.csv)} + false + true + All threads + false + username,password + + + + true + 1 + + + + + true + rfc2109 + + + + + + + + + + + + + + GET + true + false + true + false + false + + + + + + + + false + ${username} + = + true + username + + + false + ${password} + = + true + password + + + + + + + + + + ${sitepath}/login/index.php + POST + true + false + true + false + false + + + + + + + + + + + + + + + GET + true + false + true + false + false + + + + + + + + false + ${courseid} + = + true + id + + + + + + + + + + ${sitepath}/course/view.php + GET + true + false + true + false + false + + + + + + false + SESSION_SESSKEY + sesskey=([^"]+)" + $1$ + + 2 + all + + + + + + + + false + ${SESSION_SESSKEY} + = + true + sesskey + + + + + + + + + + ${sitepath}/login/logout.php + GET + true + false + true + false + false + + + + + + + continue + + false + ${loops} + + ${users} + ${rampup} + 1376636813000 + 1376636813000 + false + + + + + + + + + ${host} + + + + + + ${sitepath} + 4 + + + + , + + ${__P(usersfile,YOU_FORGOT_TO_SPECIFY_USERS_CSV_FILE.csv)} + false + true + All threads + false + username,password + + + + true + 1 + + + + + true + rfc2109 + + + + + + + + + + + + + + GET + true + false + true + false + false + + + + + + + + false + ${username} + = + true + username + + + false + ${password} + = + true + password + + + + + + + + + + ${sitepath}/login/index.php + POST + true + false + true + false + false + + + + + + <div class="logininfo">You are logged in as + + Assertion.response_data + false + 2 + + + + + + + + + + + + + + + GET + true + false + true + false + false + + + + + + + + false + ${courseid} + = + true + id + + + + + + + + + + ${sitepath}/course/view.php + GET + true + false + true + false + false + + + + + + + + + false + ${pageactivityid} + = + true + id + + + + + + + + + + ${sitepath}/mod/page/view.php + GET + true + false + true + false + false + + + + + + + + false + ${courseid} + = + true + id + + + + + + + + + + ${sitepath}/course/view.php + GET + true + false + true + false + false + + + + + + + + false + ${forumactivityid} + = + true + id + + + + + + + + + + ${sitepath}/mod/forum/view.php + GET + true + false + true + false + false + + + + + + + + false + ${forumdiscussionid} + = + true + d + + + + + + + + + + ${sitepath}/mod/forum/discuss.php + GET + true + false + true + false + false + + + + + + + + false + ${forumreplyid} + = + true + reply + + + + + + + + + + ${sitepath}/mod/forum/post.php + GET + true + false + true + false + false + + + + + false + SESSION_USERID + name="userid"\stype="hidden"\svalue="(\d+)" + $1$ + 0 + 1 + + + + false + SESSION_SESSKEY + name="sesskey"\stype="hidden"\svalue="([^"]+)" + $1$ + 0 + 1 + + + + false + SESSION_FORUMFORMATTACHMENTS + value="(\d+)"\sname="attachments"\stype="hidden" + $1$ + 0 + 1 + + + + false + SESSION_FORUMFORMITEMID + type="hidden"\sname="message\[itemid\]"\svalue="(\d+)" + $1$ + 0 + 1 + + + + + + + + false + ${courseid} + = + true + course + + + false + 0 + = + true + forum + + + false + ${forumdiscussionid} + = + true + discussion + + + false + ${SESSION_USERID} + = + true + userid + + + false + 0 + = + true + groupid + + + false + 0 + = + true + edit + + + false + ${forumreplyid} + = + true + reply + + + false + ${SESSION_SESSKEY} + = + true + sesskey + + + false + 1 + = + true + _qf__mod_forum_post_form + + + false + Re: I am the test plan reply subject + = + true + subject + + + false + ${SESSION_FORUMFORMITEMID} + = + true + message[itemid] + + + false + 1 + = + true + message[format] + + + false + I am the test plan reply message + = + true + message[text] + + + false + ${forumreplyid} + = + true + parent + + + false + 1 + = + true + subscribe + + + false + ${SESSION_FORUMFORMATTACHMENTS} + = + true + attachments + + + false + 0 + = + true + timestart + + + false + 0 + = + true + timeend + + + false + Post to forum + = + true + submitbutton + + + + + + + + + + ${sitepath}/mod/forum/post.php + POST + true + false + true + false + false + + + + + + + + false + ${courseid} + = + true + id + + + + + + + + + + ${sitepath}/course/view.php + GET + true + false + true + false + false + + + + + + + + false + ${courseid} + = + true + id + + + + + + + + + + ${sitepath}/user/index.php + GET + true + false + true + false + false + + + + + + + + false + ${SESSION_SESSKEY} + = + true + sesskey + + + + + + + + + + ${sitepath}/login/logout.php + GET + true + false + true + false + false + + + + + + recorder.bsf + + false + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + true + false + false + false + false + false + 0 + true + + + runs_samples/data.${runtimestamp}.jtl + + + + + + From 1325d493cd99b637117a59e150c3d732805ea037 Mon Sep 17 00:00:00 2001 From: David Monllao Date: Wed, 28 Aug 2013 16:50:00 +0800 Subject: [PATCH 3/4] MDL-41421 tool_generator: Adding a test plan generator to feed JMeter Also changing course_backend.php coding style according to codechecker. --- .../tool/generator/classes/course_backend.php | 8 +- .../generator/classes/make_course_form.php | 10 +- .../generator/classes/make_testplan_form.php | 90 ++++++ .../generator/classes/testplan_backend.php | 273 ++++++++++++++++++ .../tool/generator/lang/en/tool_generator.php | 70 ++++- admin/tool/generator/lib.php | 59 ++++ admin/tool/generator/maketestcourse.php | 3 +- admin/tool/generator/maketestplan.php | 88 ++++++ admin/tool/generator/settings.php | 6 +- admin/tool/generator/testplan.template.jmx | 33 +-- config-dist.php | 14 + 11 files changed, 611 insertions(+), 43 deletions(-) create mode 100644 admin/tool/generator/classes/make_testplan_form.php create mode 100644 admin/tool/generator/classes/testplan_backend.php create mode 100644 admin/tool/generator/lib.php create mode 100644 admin/tool/generator/maketestplan.php diff --git a/admin/tool/generator/classes/course_backend.php b/admin/tool/generator/classes/course_backend.php index 5171b835a85..28eda175fd0 100644 --- a/admin/tool/generator/classes/course_backend.php +++ b/admin/tool/generator/classes/course_backend.php @@ -328,7 +328,7 @@ class tool_generator_course_backend extends tool_generator_backend { // Create pages. $number = self::$parampages[$this->size]; $this->log('createpages', $number, true); - for ($i=0; $i<$number; $i++) { + for ($i = 0; $i < $number; $i++) { $record = array('course' => $this->course->id); $options = array('section' => $this->get_target_section()); $pagegenerator->create_instance($record, $options); @@ -385,7 +385,7 @@ class tool_generator_course_backend extends tool_generator_backend { return substr($data, -$length); } $length -= strlen($data); - for ($j=0; $j < $length; $j++) { + for ($j = 0; $j < $length; $j++) { $data .= chr(rand(1, 255)); } return $data; @@ -463,13 +463,13 @@ class tool_generator_course_backend extends tool_generator_backend { // Add discussions and posts. $sofar = 0; - for ($i=0; $i < $discussions; $i++) { + for ($i = 0; $i < $discussions; $i++) { $record = array('forum' => $forum->id, 'course' => $this->course->id, 'userid' => $this->get_target_user()); $discussion = $forumgenerator->create_discussion($record); $parentid = $DB->get_field('forum_posts', 'id', array('discussion' => $discussion->id), MUST_EXIST); $sofar++; - for ($j=0; $j < $posts - 1; $j++, $sofar++) { + for ($j = 0; $j < $posts - 1; $j++, $sofar++) { $record = array('discussion' => $discussion->id, 'userid' => $this->get_target_user(), 'parent' => $parentid); $forumgenerator->create_post($record); diff --git a/admin/tool/generator/classes/make_course_form.php b/admin/tool/generator/classes/make_course_form.php index 7f7f629c5b3..5c965152501 100644 --- a/admin/tool/generator/classes/make_course_form.php +++ b/admin/tool/generator/classes/make_course_form.php @@ -14,6 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . +/** + * Course form. + * + * @package tool_generator + * @copyright 2013 The Open University + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir . '/formslib.php'); @@ -60,7 +68,7 @@ class tool_generator_make_course_form extends moodleform { // Check course doesn't already exist. if (!empty($data['shortname'])) { // Check shortname. - $error = tool_generator_course_backend::check_shortname_available($data['shortname']); + $error = tool_generator_course_backend::check_shortname_available($data['shortname']); if ($error) { $errors['shortname'] = $error; } diff --git a/admin/tool/generator/classes/make_testplan_form.php b/admin/tool/generator/classes/make_testplan_form.php new file mode 100644 index 00000000000..b4c05e0731e --- /dev/null +++ b/admin/tool/generator/classes/make_testplan_form.php @@ -0,0 +1,90 @@ +. + +/** + * Test plan form. + * + * @package tool_generator + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir . '/formslib.php'); + +/** + * Form with options for creating large course. + * + * @package tool_generator + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class tool_generator_make_testplan_form extends moodleform { + + /** + * Test plan form definition. + * + * @return void + */ + public function definition() { + $mform = $this->_form; + + $mform->addElement('select', 'size', get_string('size', 'tool_generator'), + tool_generator_testplan_backend::get_size_choices()); + $mform->setDefault('size', tool_generator_testplan_backend::DEFAULT_SIZE); + + $mform->addElement('select', 'courseid', get_string('targetcourse', 'tool_generator'), + tool_generator_testplan_backend::get_course_options()); + + $mform->addElement('advcheckbox', 'updateuserspassword', get_string('updateuserspassword', 'tool_generator')); + $mform->addHelpButton('updateuserspassword', 'updateuserspassword', 'tool_generator'); + + $mform->addElement('submit', 'submit', get_string('createtestplan', 'tool_generator')); + } + + /** + * Checks that the submitted data allows us to create a test plan. + * + * @param array $data + * @param array $files + * @return array An array of errors + */ + public function validation($data, $files) { + global $CFG, $DB; + + $errors = array(); + if (empty($CFG->tool_generator_users_password) || is_bool($CFG->tool_generator_users_password)) { + $errors['updateuserspassword'] = get_string('error_nouserspassword', 'tool_generator'); + } + + // Check the course has users. + // Better to repeat here the query than to do it afterwards and end up with an exception. + $coursecontext = context_course::instance($data['courseid']); + if (!$users = get_enrolled_users($coursecontext, '', 0, 'u.id')) { + $errors['courseid'] = get_string('coursewithoutusers', 'tool_generator'); + } + + // Checks that the selected course has enough users. + $coursesizes = tool_generator_course_backend::get_users_per_size(); + if (count($users) < $coursesizes[$data['size']]) { + $errors['size'] = get_string('notenoughusers', 'tool_generator'); + } + + return $errors; + } + +} diff --git a/admin/tool/generator/classes/testplan_backend.php b/admin/tool/generator/classes/testplan_backend.php new file mode 100644 index 00000000000..af1b7439ecf --- /dev/null +++ b/admin/tool/generator/classes/testplan_backend.php @@ -0,0 +1,273 @@ +. + +/** + * Test plan generator. + * + * @package tool_generator + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Generates the files required by JMeter. + * + * @package tool_generator + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class tool_generator_testplan_backend extends tool_generator_backend { + + /** + * @var Number of users depending on the selected size. + */ + protected static $users = array(1, 30, 200, 1000, 5000, 10000); + + /** + * @var Number of loops depending on the selected size. + */ + protected static $loops = array(1, 1, 2, 3, 3, 5); + + /** + * @var Rampup period depending on the selected size. + */ + protected static $rampups = array(1, 6, 40, 100, 500, 800); + + /** + * Gets a list of size choices supported by this backend. + * + * @return array List of size (int) => text description for display + */ + public static function get_size_choices() { + + $options = array(); + for ($size = self::MIN_SIZE; $size <= self::MAX_SIZE; $size++) { + $a = new stdClass(); + $a->users = self::$users[$size]; + $a->loops = self::$loops[$size]; + $a->rampup = self::$rampups[$size]; + $options[$size] = get_string('testplansize_' . $size, 'tool_generator', $a); + } + return $options; + } + + /** + * Gets the list of courses that can be used used to generate a test. + * + * @return array The list of options as courseid => name + */ + public static function get_course_options() { + $courses = get_courses('all', 'c.sortorder ASC', 'c.id, c.shortname, c.fullname'); + if (!$courses) { + print_error('error_nocourses', 'tool_generator'); + } + + $options = array(); + unset($courses[1]); + foreach ($courses as $course) { + $options[$course->id] = $course->fullname . '(' . $course->shortname . ')'; + } + return $options; + } + + /** + * Creates the test plan file. + * + * @param int $courseid The target course id + * @param int $size The test plan size + * @return stored_file + */ + public static function create_testplan_file($courseid, $size) { + $jmxcontents = self::generate_test_plan($courseid, $size); + + $fs = get_file_storage(); + $filerecord = self::get_file_record('testplan', 'jmx'); + return $fs->create_file_from_string($filerecord, $jmxcontents); + } + + /** + * Creates the users data file. + * + * @param int $courseid The target course id + * @param bool $updateuserspassword Updates the course users password to $CFG->tool_generator_users_password + * @return stored_file + */ + public static function create_users_file($courseid, $updateuserspassword) { + $csvcontents = self::generate_users_file($courseid, $updateuserspassword); + + $fs = get_file_storage(); + $filerecord = self::get_file_record('users', 'csv'); + return $fs->create_file_from_string($filerecord, $csvcontents); + } + + /** + * Generates the test plan according to the target course contents. + * + * @param int $targetcourseid The target course id + * @param int $size The test plan size + * @return string The test plan as a string + */ + protected static function generate_test_plan($targetcourseid, $size) { + global $CFG; + + // Getting the template. + $template = file_get_contents(__DIR__ . '/../testplan.template.jmx'); + + // Getting the course modules data. + $coursedata = self::get_course_test_data($targetcourseid); + + // Host and path to the site. + $urlcomponents = parse_url($CFG->wwwroot); + if (empty($urlcomponents['path'])) { + $urlcomponents['path'] = ''; + } + + $replacements = array( + self::$users[$size], + self::$loops[$size], + self::$rampups[$size], + $urlcomponents['host'], + $urlcomponents['path'], + get_string('shortsize_' . $size, 'tool_generator'), + $targetcourseid, + $coursedata->pageid, + $coursedata->forumid, + $coursedata->forumdiscussionid, + $coursedata->forumreplyid + ); + + $placeholders = array( + '{{USERS_PLACEHOLDER}}', + '{{LOOPS_PLACEHOLDER}}', + '{{RAMPUP_PLACEHOLDER}}', + '{{HOST_PLACEHOLDER}}', + '{{SITEPATH_PLACEHOLDER}}', + '{{SIZE_PLACEHOLDER}}', + '{{COURSEID_PLACEHOLDER}}', + '{{PAGEACTIVITYID_PLACEHOLDER}}', + '{{FORUMACTIVITYID_PLACEHOLDER}}', + '{{FORUMDISCUSSIONID_PLACEHOLDER}}', + '{{FORUMREPLYID_PLACEHOLDER}}' + ); + + // Fill the template with the target course values. + return str_replace($placeholders, $replacements, $template); + } + + /** + * Generates the user's credentials file with all the course's users + * + * @param int $targetcourseid + * @param bool $updateuserspassword Updates the course users password to $CFG->tool_generator_users_password + * @return string The users csv file contents. + */ + protected static function generate_users_file($targetcourseid, $updateuserspassword) { + global $CFG; + + $coursecontext = context_course::instance($targetcourseid); + + $users = get_enrolled_users($coursecontext, '', 0, 'u.id, u.username, u.auth', 'u.username ASC'); + if (!$users) { + print_error('coursewithoutusers', 'tool_generator'); + } + + $lines = array(); + foreach ($users as $user) { + + // Updating password to the one set in config.php. + if ($updateuserspassword) { + $userauth = get_auth_plugin($user->auth); + if (!$userauth->user_update_password($user, $CFG->tool_generator_users_password)) { + print_error('errorpasswordupdate', 'auth'); + } + } + + // Here we already checked that $CFG->tool_generator_users_password is not null. + $lines[] = $user->username . ',' . $CFG->tool_generator_users_password; + } + + return implode(PHP_EOL, $lines); + } + + /** + * Returns a tool_generator file record + * + * @param string $filearea testplan or users + * @param string $filetype The file extension jmx or csv + * @return stdClass The file record to use when creating tool_generator files + */ + protected static function get_file_record($filearea, $filetype) { + + $systemcontext = context_system::instance(); + + $filerecord = new stdClass(); + $filerecord->contextid = $systemcontext->id; + $filerecord->component = 'tool_generator'; + $filerecord->filearea = $filearea; + $filerecord->itemid = 0; + $filerecord->filepath = '/'; + + // Random generated number to avoid concurrent execution problems. + $filerecord->filename = $filearea . '_' . date('YmdHi', time()) . '_' . rand(1000, 9999) . '.' . $filetype; + + return $filerecord; + } + + /** + * Gets the data required to fill the test plan template with the database contents. + * + * @param int $targetcourseid The target course id + * @return stdClass The ids required by the test plan + */ + protected static function get_course_test_data($targetcourseid) { + global $DB, $USER; + + $data = new stdClass(); + + // Getting course contents info as the current user (will be an admin). + $course = new stdClass(); + $course->id = $targetcourseid; + $courseinfo = new course_modinfo($course, $USER->id); + + // Getting the first page module instance. + if (!$pages = $courseinfo->get_instances_of('page')) { + print_error('error_nopageinstances', 'tool_generator'); + } + $data->pageid = reset($pages)->id; + + // Getting the first forum module instance and it's first discussion and reply as well. + if (!$forums = $courseinfo->get_instances_of('forum')) { + print_error('error_noforuminstances', 'tool_generator'); + } + $forum = reset($forums); + + // Getting the first discussion (and reply). + if (!$discussions = forum_get_discussions($forum, 'd.timemodified ASC', false, -1, 1)) { + print_error('error_noforumdiscussions', 'tool_generator'); + } + $discussion = reset($discussions); + + $data->forumid = $forum->id; + $data->forumdiscussionid = $discussion->discussion; + $data->forumreplyid = $discussion->id; + + // According to the current test plan. + return $data; + } + +} diff --git a/admin/tool/generator/lang/en/tool_generator.php b/admin/tool/generator/lang/en/tool_generator.php index a204ce8aed7..71d3741efaa 100644 --- a/admin/tool/generator/lang/en/tool_generator.php +++ b/admin/tool/generator/lang/en/tool_generator.php @@ -23,16 +23,7 @@ */ $string['bigfile'] = 'Big file {$a}'; -$string['coursesize_0'] = 'XS (~10KB; create in ~1 second)'; -$string['coursesize_1'] = 'S (~10MB; create in ~30 seconds)'; -$string['coursesize_2'] = 'M (~100MB; create in ~5 minutes)'; -$string['coursesize_3'] = 'L (~1GB; create in ~1 hour)'; -$string['coursesize_4'] = 'XL (~10GB; create in ~4 hours)'; -$string['coursesize_5'] = 'XXL (~20GB; create in ~8 hours)'; -$string['createcourse'] = 'Create course'; -$string['creating'] = 'Creating course'; -$string['done'] = 'done ({$a}s)'; -$string['explanation'] = 'This tool creates standard test courses that include many +$string['courseexplanation'] = 'This tool creates standard test courses that include many sections, activities, and files. This is intended to provide a standardised measure for checking the reliability @@ -50,16 +41,38 @@ filesystem space (tens of gigabytes). You will need to delete the courses (To avoid accidental use, this feature is disabled unless you have also selected DEVELOPER debugging level.)'; +$string['coursesize_0'] = 'XS (~10KB; create in ~1 second)'; +$string['coursesize_1'] = 'S (~10MB; create in ~30 seconds)'; +$string['coursesize_2'] = 'M (~100MB; create in ~5 minutes)'; +$string['coursesize_3'] = 'L (~1GB; create in ~1 hour)'; +$string['coursesize_4'] = 'XL (~10GB; create in ~4 hours)'; +$string['coursesize_5'] = 'XXL (~20GB; create in ~8 hours)'; +$string['coursewithoutusers'] = 'The selected course has no users'; +$string['createcourse'] = 'Create course'; +$string['createtestplan'] = 'Create test plan'; +$string['creating'] = 'Creating course'; +$string['done'] = 'done ({$a}s)'; +$string['downloadtestplan'] = 'Download test plan'; +$string['downloadusersfile'] = 'Download users file'; +$string['error_nocourses'] = 'There are no courses to generate the test plan'; +$string['error_noforumdiscussions'] = 'The selected course does not contain forum discussions'; +$string['error_noforuminstances'] = 'The selected course does not contain forum module instances'; +$string['error_noforumreplies'] = 'The selected course does not contain forum replies'; +$string['error_nonexistingcourse'] = 'The specified course does not exist'; +$string['error_nopageinstances'] = 'The selected course does not contain page module instances'; $string['error_notdebugging'] = 'Not available on this server because debugging is not set to DEVELOPER'; +$string['error_nouserspassword'] = 'You need to set $CFG->tool_generator_users_password in config.php to generate the test plan'; $string['firstname'] = 'Test course user'; $string['fullname'] = 'Test course: {$a->size}'; $string['maketestcourse'] = 'Make test course'; +$string['maketestplan'] = 'Make JMeter test plan'; +$string['notenoughusers'] = 'The selected course does not have enough users'; $string['pluginname'] = 'Development data generator'; -$string['progress_createcourse'] = 'Creating course {$a}'; $string['progress_checkaccounts'] = 'Checking user accounts ({$a})'; $string['progress_coursecompleted'] = 'Course completed ({$a}s)'; $string['progress_createaccounts'] = 'Creating user accounts ({$a->from} - {$a->to})'; $string['progress_createbigfiles'] = 'Creating big files ({$a})'; +$string['progress_createcourse'] = 'Creating course {$a}'; $string['progress_createforum'] = 'Creating forum ({$a} posts)'; $string['progress_createpages'] = 'Creating pages ({$a})'; $string['progress_createsmallfiles'] = 'Creating small files ({$a})'; @@ -79,3 +92,38 @@ $string['sitesize_4'] = 'XL (~10GB; 1065 courses, created in ~5 hours)'; $string['sitesize_5'] = 'XXL (~20GB; 4177 courses, created in ~10 hours)'; $string['size'] = 'Size of course'; $string['smallfiles'] = 'Small files'; +$string['targetcourse'] = 'Test target course'; +$string['testplanexplanation'] = 'This tool creates a JMeter test plan file along with the user credentials file. + +This test plan is designed to work along with {$a}, which makes easier to run the test plan in a specific Moodle environment, gathers information about the runs and compares the results, so you will need to download it and use it\'s test_runner.sh script or follow the installation and usage instructions. + +You need to set a password for the course users in config.php (p.e. $CFG->tool_generator_users_password = \'moodle\';) there +is no default value for this password to prevent unintended usages of the tool. + +It is part of tool_generator so it works well with the courses generated by the courses and the site generators, it can +also be used with any course that contains, at least: + +* Enough enrolled users (depends on the test plan size you select) with the password reset to \'moodle\' +* A page module instance +* A forum module instance with at least one discussion and one reply + +You might want to consider your servers capacity when running large test plans as the amount to load generated by JMeter +can be specially big. The ramp up period has been adjusted according to the number of threads (users) to reduce this kind +of issues but the load is still huge. + +**Do not run the test plan on a live system**. This feature only creates the files to feed JMeter so is not dangerous by +itself, but you should **NEVER** run this test plan in a production site as: + +* It changes the database contents +* Logins lots of users at the same time so there is risk that your server can not handle the load and dies +* It can update the course users passwords + +'; +$string['testplansize_0'] = 'XS ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; +$string['testplansize_1'] = 'S ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; +$string['testplansize_2'] = 'M ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; +$string['testplansize_3'] = 'L ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; +$string['testplansize_4'] = 'XL ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; +$string['testplansize_5'] = 'XXL ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; +$string['updateuserspassword'] = 'Update course users password'; +$string['updateuserspassword_help'] = 'JMeter needs to login as the course users, you can set the users password using $CFG->tool_generator_users_password in config.php; this setting updates the course user\'s password according to $CFG->tool_generator_users_password. It can be useful in case you are using a course not generated by tool_generator or $CFG->tool_generator_users_password was not set when you created the test courses.'; diff --git a/admin/tool/generator/lib.php b/admin/tool/generator/lib.php new file mode 100644 index 00000000000..b9b5efbe818 --- /dev/null +++ b/admin/tool/generator/lib.php @@ -0,0 +1,59 @@ +. + +/** + * Generator tool functions. + * + * @package tool_generator + * @copyright David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Files support. + * + * Exits if the required permissions are not satisfied. + * + * @param stdClass $course course object + * @param stdClass $cm + * @param stdClass $context context object + * @param string $filearea file area + * @param array $args extra arguments + * @param bool $forcedownload whether or not force download + * @param array $options additional options affecting the file serving + * @return void The file is sent along with it's headers + */ +function tool_generator_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { + + // Only for admins. + if (!is_siteadmin()) { + die; + } + + if ($context->contextlevel != CONTEXT_SYSTEM) { + send_file_not_found(); + } + + $fs = get_file_storage(); + $file = $fs->get_file($context->id, 'tool_generator', $filearea, $args[0], '/', $args[1]); + + // Send the file, always forcing download, we don't want options. + session_get_instance()->write_close(); + send_stored_file($file, 0, 0, true); +} + diff --git a/admin/tool/generator/maketestcourse.php b/admin/tool/generator/maketestcourse.php index c5f9c82ab10..a7b760bd63d 100644 --- a/admin/tool/generator/maketestcourse.php +++ b/admin/tool/generator/maketestcourse.php @@ -15,8 +15,7 @@ // along with Moodle. If not, see . /** - * Script creates a standardised large course for testing reliability and - * performance. + * Script creates a standardised large course for testing reliability and performance. * * @package tool_generator * @copyright 2013 The Open University diff --git a/admin/tool/generator/maketestplan.php b/admin/tool/generator/maketestplan.php new file mode 100644 index 00000000000..5adef0c7178 --- /dev/null +++ b/admin/tool/generator/maketestplan.php @@ -0,0 +1,88 @@ +. + +/** + * Generates a JMeter test plan to performance comparison. + * + * @package tool_generator + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require(__DIR__ . '/../../../config.php'); +require_once($CFG->libdir . '/adminlib.php'); + +// Initialise page and check permissions. +admin_externalpage_setup('toolgeneratortestplan'); + +// Start page. +echo $OUTPUT->header(); +echo $OUTPUT->heading(get_string('maketestplan', 'tool_generator')); + +// Information message. +$context = context_system::instance(); +$repourl = 'https://github.com/moodlehq/moodle-performance-comparison'; +$markdownlink = '[' . $repourl . '](' . $repourl . ')'; +echo $OUTPUT->box(format_text(get_string('testplanexplanation', 'tool_generator', $markdownlink), + FORMAT_MARKDOWN, array('context' => $context))); + +// Check debugging is set to DEVELOPER. +if (!$CFG->debugdeveloper) { + echo $OUTPUT->notification(get_string('error_notdebugging', 'tool_generator')); + echo $OUTPUT->footer(); + exit; +} + +// Set up the form. +$mform = new tool_generator_make_testplan_form('maketestplan.php'); +if ($data = $mform->get_data()) { + + // Creating both test plan and users files. + $testplanfile = tool_generator_testplan_backend::create_testplan_file($data->courseid, $data->size); + $usersfile = tool_generator_testplan_backend::create_users_file($data->courseid, $data->updateuserspassword); + + // Test plan link. + $testplanurl = moodle_url::make_pluginfile_url( + $testplanfile->get_contextid(), + $testplanfile->get_component(), + $testplanfile->get_filearea(), + $testplanfile->get_itemid(), + $testplanfile->get_filepath(), + $testplanfile->get_filename() + ); + echo html_writer::div( + html_writer::link($testplanurl, get_string('downloadtestplan', 'tool_generator')) + ); + + // Users file link. + $usersfileurl = moodle_url::make_pluginfile_url( + $usersfile->get_contextid(), + $usersfile->get_component(), + $usersfile->get_filearea(), + $usersfile->get_itemid(), + $usersfile->get_filepath(), + $usersfile->get_filename() + ); + echo html_writer::div( + html_writer::link($usersfileurl, get_string('downloadusersfile', 'tool_generator')) + ); + +} else { + // Display form. + $mform->display(); +} + +echo $OUTPUT->footer(); diff --git a/admin/tool/generator/settings.php b/admin/tool/generator/settings.php index 39a40aeced8..f1f2350fe3a 100644 --- a/admin/tool/generator/settings.php +++ b/admin/tool/generator/settings.php @@ -25,8 +25,12 @@ defined('MOODLE_INTERNAL') || die; if ($hassiteconfig) { - $ADMIN->add('development', new admin_externalpage('toolgenerator', + $ADMIN->add('development', new admin_externalpage('toolgeneratorcourse', get_string('maketestcourse', 'tool_generator'), $CFG->wwwroot . '/' . $CFG->admin . '/tool/generator/maketestcourse.php')); + + $ADMIN->add('development', new admin_externalpage('toolgeneratortestplan', + get_string('maketestplan', 'tool_generator'), + $CFG->wwwroot . '/' . $CFG->admin . '/tool/generator/maketestplan.php')); } diff --git a/admin/tool/generator/testplan.template.jmx b/admin/tool/generator/testplan.template.jmx index d08a9b50f56..2bfdaf45530 100644 --- a/admin/tool/generator/testplan.template.jmx +++ b/admin/tool/generator/testplan.template.jmx @@ -12,19 +12,9 @@ ${__time()} = - - users - {{USERS_PLACEHOLDER}} - = - - - loops - {{LOOPS_PLACEHOLDER}} - = - - - rampup - {{RAMPUP_PLACEHOLDER}} + + size + {{SIZE_PLACEHOLDER}} = @@ -62,7 +52,6 @@ {{FORUMREPLYID_PLACEHOLDER}} = - @@ -70,11 +59,7 @@ all active threads (shared) - - throughput - 120.0 - 0.0 - + ${__property(throughput,throughput,120.0)} @@ -84,8 +69,8 @@ false 1 - ${users} - ${rampup} + ${__P(users,{{USERS_PLACEHOLDER}})} + ${__P(rampup,{{RAMPUP_PLACEHOLDER}})} 1378187955000 1378187955000 false @@ -278,10 +263,10 @@ continue false - ${loops} + ${__property(loops,loops,{{LOOPS_PLACEHOLDER}})} - ${users} - ${rampup} + ${__property(users,users,{{USERS_PLACEHOLDER}})} + ${__property(rampup,rampup,{{RAMPUP_PLACEHOLDER}})} 1376636813000 1376636813000 false diff --git a/config-dist.php b/config-dist.php index 0b2a9b1e7b9..87fa3278f93 100644 --- a/config-dist.php +++ b/config-dist.php @@ -620,6 +620,20 @@ $CFG->admin = 'admin'; // used to expand the default white list with an array of extra settings. // Example: // $CFG->behat_extraallowedsettings = array('logsql', 'dblogerror'); +// +//========================================================================= +// 12. DEVELOPER DATA GENERATOR +//========================================================================= +// +// The developer data generator tool is intended to be used only in development or testing sites and +// it's usage in production environments is not recommended; if it is used to create JMeter test plans +// is even less recommended as JMeter needs to log in as site course users. JMeter needs to know the +// users passwords but would be dangerous to have a default password as everybody would know it, which would +// be specially dangerouse if somebody uses this tool in a production site, so in order to prevent unintended +// uses of the tool and undesired accesses as well, is compulsory to set a password for the users +// generated by this tool, but only in case you want to generate a JMeter test. The value should be a string. +// Example: +// $CFG->tool_generator_users_password = 'examplepassword'; //========================================================================= // ALL DONE! To continue installation, visit your main page with a browser From 35aa01820881182b56a4c702fc8540989c839007 Mon Sep 17 00:00:00 2001 From: David Monllao Date: Thu, 5 Sep 2013 13:38:43 +0800 Subject: [PATCH 4/4] MDL-41421 tool_generator: Adding a CLI tool to generate the test plan --- .../generator/classes/make_testplan_form.php | 14 +- .../generator/classes/testplan_backend.php | 55 ++++++++ admin/tool/generator/cli/maketestplan.php | 122 ++++++++++++++++++ .../tool/generator/lang/en/tool_generator.php | 9 +- admin/tool/generator/lib.php | 4 +- admin/tool/generator/maketestplan.php | 3 +- admin/tool/generator/version.php | 4 +- 7 files changed, 187 insertions(+), 24 deletions(-) create mode 100644 admin/tool/generator/cli/maketestplan.php diff --git a/admin/tool/generator/classes/make_testplan_form.php b/admin/tool/generator/classes/make_testplan_form.php index b4c05e0731e..15552d5775a 100644 --- a/admin/tool/generator/classes/make_testplan_form.php +++ b/admin/tool/generator/classes/make_testplan_form.php @@ -64,24 +64,16 @@ class tool_generator_make_testplan_form extends moodleform { * @return array An array of errors */ public function validation($data, $files) { - global $CFG, $DB; + global $CFG; $errors = array(); if (empty($CFG->tool_generator_users_password) || is_bool($CFG->tool_generator_users_password)) { $errors['updateuserspassword'] = get_string('error_nouserspassword', 'tool_generator'); } - // Check the course has users. // Better to repeat here the query than to do it afterwards and end up with an exception. - $coursecontext = context_course::instance($data['courseid']); - if (!$users = get_enrolled_users($coursecontext, '', 0, 'u.id')) { - $errors['courseid'] = get_string('coursewithoutusers', 'tool_generator'); - } - - // Checks that the selected course has enough users. - $coursesizes = tool_generator_course_backend::get_users_per_size(); - if (count($users) < $coursesizes[$data['size']]) { - $errors['size'] = get_string('notenoughusers', 'tool_generator'); + if ($courseerrors = tool_generator_testplan_backend::has_selected_course_any_problem($data['courseid'], $data['size'])) { + $errors = array_merge($errors, $courseerrors); } return $errors; diff --git a/admin/tool/generator/classes/testplan_backend.php b/admin/tool/generator/classes/testplan_backend.php index af1b7439ecf..6f70dad3ed9 100644 --- a/admin/tool/generator/classes/testplan_backend.php +++ b/admin/tool/generator/classes/testplan_backend.php @@ -33,6 +33,11 @@ defined('MOODLE_INTERNAL') || die(); */ class tool_generator_testplan_backend extends tool_generator_backend { + /** + * @var The URL to the repository of the external project. + */ + protected static $repourl = 'https://github.com/moodlehq/moodle-performance-comparison'; + /** * @var Number of users depending on the selected size. */ @@ -85,6 +90,15 @@ class tool_generator_testplan_backend extends tool_generator_backend { return $options; } + /** + * Getter for moodle-performance-comparison project URL. + * + * @return string + */ + public static function get_repourl() { + return self::$repourl; + } + /** * Creates the test plan file. * @@ -270,4 +284,45 @@ class tool_generator_testplan_backend extends tool_generator_backend { return $data; } + /** + * Checks if the selected target course is ok. + * + * @param int|string $course + * @param int $size + * @return array Errors array or false if everything is ok + */ + public static function has_selected_course_any_problem($course, $size) { + global $DB; + + $errors = array(); + + if (!is_numeric($course)) { + if (!$course = $DB->get_field('course', 'id', array('shortname' => $course))) { + $errors['courseid'] = get_string('error_nonexistingcourse', 'tool_generator'); + return $errors; + } + } + + $coursecontext = context_course::instance($course, IGNORE_MISSING); + if (!$coursecontext) { + $errors['courseid'] = get_string('error_nonexistingcourse', 'tool_generator'); + return $errors; + } + + if (!$users = get_enrolled_users($coursecontext, '', 0, 'u.id')) { + $errors['courseid'] = get_string('coursewithoutusers', 'tool_generator'); + } + + // Checks that the selected course has enough users. + $coursesizes = tool_generator_course_backend::get_users_per_size(); + if (count($users) < $coursesizes[$size]) { + $errors['size'] = get_string('notenoughusers', 'tool_generator'); + } + + if (empty($errors)) { + return false; + } + + return $errors; + } } diff --git a/admin/tool/generator/cli/maketestplan.php b/admin/tool/generator/cli/maketestplan.php new file mode 100644 index 00000000000..456393d81a9 --- /dev/null +++ b/admin/tool/generator/cli/maketestplan.php @@ -0,0 +1,122 @@ +. + +/** + * CLI interface for creating a test plan + * + * @package tool_generator + * @copyright 2013 David Monllaó + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +define('CLI_SCRIPT', true); +define('NO_OUTPUT_BUFFERING', true); + +require(dirname(__FILE__) . '/../../../../config.php'); +require_once($CFG->libdir. '/clilib.php'); + +// CLI options. +list($options, $unrecognized) = cli_get_params( + array( + 'help' => false, + 'shortname' => false, + 'size' => false, + 'bypasscheck' => false, + 'updateuserspassword' => false + ), + array( + 'h' => 'help' + ) +); + +$testplansizes = '* ' . implode(PHP_EOL . '* ', tool_generator_testplan_backend::get_size_choices()); + +// Display help. +if (!empty($options['help']) || empty($options['shortname']) || empty($options['size'])) { + + echo get_string('testplanexplanation', 'tool_generator', tool_generator_testplan_backend::get_repourl()) . +"Options: +-h, --help Print out this help +--shortname Shortname of the test plan's target course (required) +--size Size of the test plan to create XS, S, M, L, XL, or XXL (required) +--bypasscheck Bypasses the developer-mode check (be careful!) +--updateuserspassword Updates the target course users password according to \$CFG->tool_generator_users_password + +$testplansizes + +Consider that, the server resources you will need to run the test plan will be higher as the test plan size is higher. + +Example from Moodle root directory: +\$ sudo -u www-data /usr/bin/php admin/tool/generator/cli/maketestplan.php --shortname=\"testcourse_12\" --size=S +"; + // Exit with error unless we're showing this because they asked for it. + exit(empty($options['help']) ? 1 : 0); +} + +// Check debugging is set to developer level. +if (empty($options['bypasscheck']) && !$CFG->debugdeveloper) { + cli_error(get_string('error_notdebugging', 'tool_generator')); +} + +// Get options. +$shortname = $options['shortname']; +$sizename = $options['size']; + +// Check size. +try { + $size = tool_generator_testplan_backend::size_for_name($sizename); +} catch (coding_exception $e) { + cli_error("Error: Invalid size ($sizename). Use --help for help."); +} + +// Check selected course. +if ($errors = tool_generator_testplan_backend::has_selected_course_any_problem($shortname, $size)) { + // Showing the first reported problem. + cli_error("Error: " . reset($errors)); +} + +// Checking if test users password is set. +if (empty($CFG->tool_generator_users_password) || is_bool($CFG->tool_generator_users_password)) { + cli_error("Error: " . get_string('error_nouserspassword', 'tool_generator')); +} + +// Switch to admin user account. +session_set_user(get_admin()); + +// Create files. +$courseid = $DB->get_field('course', 'id', array('shortname' => $shortname)); +$usersfile = tool_generator_testplan_backend::create_users_file($courseid, !empty($options['updateuserspassword'])); +$testplanfile = tool_generator_testplan_backend::create_testplan_file($courseid, $size); + +// One file path per line so other CLI scripts can easily parse the output. +echo moodle_url::make_pluginfile_url( + $testplanfile->get_contextid(), + $testplanfile->get_component(), + $testplanfile->get_filearea(), + $testplanfile->get_itemid(), + $testplanfile->get_filepath(), + $testplanfile->get_filename() + ) . + PHP_EOL . + moodle_url::make_pluginfile_url( + $usersfile->get_contextid(), + $usersfile->get_component(), + $usersfile->get_filearea(), + $usersfile->get_itemid(), + $usersfile->get_filepath(), + $usersfile->get_filename() + ) . + PHP_EOL; diff --git a/admin/tool/generator/lang/en/tool_generator.php b/admin/tool/generator/lang/en/tool_generator.php index 71d3741efaa..9aab6287435 100644 --- a/admin/tool/generator/lang/en/tool_generator.php +++ b/admin/tool/generator/lang/en/tool_generator.php @@ -98,11 +98,10 @@ $string['testplanexplanation'] = 'This tool creates a JMeter test plan file alon This test plan is designed to work along with {$a}, which makes easier to run the test plan in a specific Moodle environment, gathers information about the runs and compares the results, so you will need to download it and use it\'s test_runner.sh script or follow the installation and usage instructions. You need to set a password for the course users in config.php (p.e. $CFG->tool_generator_users_password = \'moodle\';) there -is no default value for this password to prevent unintended usages of the tool. +is no default value for this password to prevent unintended usages of the tool. You need to use the update passwords option in case your course users have other passwords or they were generated by tool_generator but without setting a $CFG->tool_generator_users_password value. It is part of tool_generator so it works well with the courses generated by the courses and the site generators, it can also be used with any course that contains, at least: - * Enough enrolled users (depends on the test plan size you select) with the password reset to \'moodle\' * A page module instance * A forum module instance with at least one discussion and one reply @@ -112,11 +111,7 @@ can be specially big. The ramp up period has been adjusted according to the numb of issues but the load is still huge. **Do not run the test plan on a live system**. This feature only creates the files to feed JMeter so is not dangerous by -itself, but you should **NEVER** run this test plan in a production site as: - -* It changes the database contents -* Logins lots of users at the same time so there is risk that your server can not handle the load and dies -* It can update the course users passwords +itself, but you should **NEVER** run this test plan in a production site. '; $string['testplansize_0'] = 'XS ({$a->users} users, {$a->loops} loops and {$a->rampup} rampup period)'; diff --git a/admin/tool/generator/lib.php b/admin/tool/generator/lib.php index b9b5efbe818..18e8a0905fe 100644 --- a/admin/tool/generator/lib.php +++ b/admin/tool/generator/lib.php @@ -40,8 +40,8 @@ defined('MOODLE_INTERNAL') || die(); */ function tool_generator_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { - // Only for admins. - if (!is_siteadmin()) { + // Only for admins or CLI. + if (!defined('CLI_SCRIPT') && !is_siteadmin()) { die; } diff --git a/admin/tool/generator/maketestplan.php b/admin/tool/generator/maketestplan.php index 5adef0c7178..fe2965ae225 100644 --- a/admin/tool/generator/maketestplan.php +++ b/admin/tool/generator/maketestplan.php @@ -34,8 +34,7 @@ echo $OUTPUT->heading(get_string('maketestplan', 'tool_generator')); // Information message. $context = context_system::instance(); -$repourl = 'https://github.com/moodlehq/moodle-performance-comparison'; -$markdownlink = '[' . $repourl . '](' . $repourl . ')'; +$markdownlink = '[' . tool_generator_testplan_backend::get_repourl() . '](' . tool_generator_testplan_backend::get_repourl() . ')'; echo $OUTPUT->box(format_text(get_string('testplanexplanation', 'tool_generator', $markdownlink), FORMAT_MARKDOWN, array('context' => $context))); diff --git a/admin/tool/generator/version.php b/admin/tool/generator/version.php index 3733d984b92..fcbb49d4ac9 100644 --- a/admin/tool/generator/version.php +++ b/admin/tool/generator/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2013090200; -$plugin->requires = 2013090200; +$plugin->version = 2013090500; +$plugin->requires = 2013090500; $plugin->component = 'tool_generator';