mirror of
https://github.com/moodle/moodle.git
synced 2025-04-15 21:45:37 +02:00
MDL-41421 tool_generator: Adding a test plan generator to feed JMeter
Also changing course_backend.php coding style according to codechecker.
This commit is contained in:
parent
8520de1ee4
commit
1325d493cd
@ -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);
|
||||
|
@ -14,6 +14,14 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
90
admin/tool/generator/classes/make_testplan_form.php
Normal file
90
admin/tool/generator/classes/make_testplan_form.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
273
admin/tool/generator/classes/testplan_backend.php
Normal file
273
admin/tool/generator/classes/testplan_backend.php
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
@ -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.';
|
||||
|
59
admin/tool/generator/lib.php
Normal file
59
admin/tool/generator/lib.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
88
admin/tool/generator/maketestplan.php
Normal file
88
admin/tool/generator/maketestplan.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* 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();
|
@ -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'));
|
||||
}
|
||||
|
||||
|
@ -12,19 +12,9 @@
|
||||
<stringProp name="Argument.value">${__time()}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="users" elementType="Argument">
|
||||
<stringProp name="Argument.name">users</stringProp>
|
||||
<stringProp name="Argument.value">{{USERS_PLACEHOLDER}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="loops" elementType="Argument">
|
||||
<stringProp name="Argument.name">loops</stringProp>
|
||||
<stringProp name="Argument.value">{{LOOPS_PLACEHOLDER}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="rampup" elementType="Argument">
|
||||
<stringProp name="Argument.name">rampup</stringProp>
|
||||
<stringProp name="Argument.value">{{RAMPUP_PLACEHOLDER}}</stringProp>
|
||||
<elementProp name="size" elementType="Argument">
|
||||
<stringProp name="Argument.name">size</stringProp>
|
||||
<stringProp name="Argument.value">{{SIZE_PLACEHOLDER}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
<elementProp name="host" elementType="Argument">
|
||||
@ -62,7 +52,6 @@
|
||||
<stringProp name="Argument.value">{{FORUMREPLYID_PLACEHOLDER}}</stringProp>
|
||||
<stringProp name="Argument.metadata">=</stringProp>
|
||||
</elementProp>
|
||||
|
||||
</collectionProp>
|
||||
</elementProp>
|
||||
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||
@ -70,11 +59,7 @@
|
||||
<hashTree>
|
||||
<ConstantThroughputTimer guiclass="TestBeanGUI" testclass="ConstantThroughputTimer" testname="Samples per minute" enabled="true">
|
||||
<stringProp name="calcMode">all active threads (shared)</stringProp>
|
||||
<doubleProp>
|
||||
<name>throughput</name>
|
||||
<value>120.0</value>
|
||||
<savedValue>0.0</savedValue>
|
||||
</doubleProp>
|
||||
<stringProp name="throughput">${__property(throughput,throughput,120.0)}</stringProp>
|
||||
</ConstantThroughputTimer>
|
||||
<hashTree/>
|
||||
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Warm-up site" enabled="true">
|
||||
@ -84,8 +69,8 @@
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">1</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">${users}</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">${rampup}</stringProp>
|
||||
<stringProp name="ThreadGroup.num_threads">${__P(users,{{USERS_PLACEHOLDER}})}</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">${__P(rampup,{{RAMPUP_PLACEHOLDER}})}</stringProp>
|
||||
<longProp name="ThreadGroup.start_time">1378187955000</longProp>
|
||||
<longProp name="ThreadGroup.end_time">1378187955000</longProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
@ -278,10 +263,10 @@
|
||||
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||
<stringProp name="LoopController.loops">${loops}</stringProp>
|
||||
<stringProp name="LoopController.loops">${__property(loops,loops,{{LOOPS_PLACEHOLDER}})}</stringProp>
|
||||
</elementProp>
|
||||
<stringProp name="ThreadGroup.num_threads">${users}</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">${rampup}</stringProp>
|
||||
<stringProp name="ThreadGroup.num_threads">${__property(users,users,{{USERS_PLACEHOLDER}})}</stringProp>
|
||||
<stringProp name="ThreadGroup.ramp_time">${__property(rampup,rampup,{{RAMPUP_PLACEHOLDER}})}</stringProp>
|
||||
<longProp name="ThreadGroup.start_time">1376636813000</longProp>
|
||||
<longProp name="ThreadGroup.end_time">1376636813000</longProp>
|
||||
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user