Skip to content

Commit

Permalink
MDL-55272 lib: Improve test course create performance
Browse files Browse the repository at this point in the history
Use core functions that are faster for test file creation.
To support large requests for hashes, the core hash function
must support large hashes without recursion.  PHP has a default
recursion depth of 100 and long hashes don't support this.

Remove transactions as they create performance problems for larger
courses and doesn't introduce significant benefit for developers.

Performance changes meant the times were much faster, a reasonable
guess was taken on performance of an average machine.
  • Loading branch information
mr-russ committed Aug 16, 2016
1 parent 7752762 commit 6a3acc8
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 44 deletions.
37 changes: 6 additions & 31 deletions admin/tool/generator/classes/course_backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,19 +216,19 @@ public function make() {

$entirestart = microtime(true);

// Start transaction.
$transaction = $DB->start_delegated_transaction();

// Get generator.
$this->generator = phpunit_util::get_data_generator();

// Make course.
$this->course = $this->create_course();
$this->create_users();

$this->create_assignments();
$this->create_pages();
$this->create_small_files();
$this->create_big_files();

// Create users as late as possible to reduce regarding in the gradebook.
$this->create_users();
$this->create_forum();

// Log total time.
Expand All @@ -238,8 +238,6 @@ public function make() {
echo html_writer::end_tag('ul');
}

// Commit transaction and finish.
$transaction->allow_commit();
return $this->course->id;
}

Expand Down Expand Up @@ -435,7 +433,7 @@ private function create_small_files() {

// Generate random binary data (different for each file so it
// doesn't compress unrealistically).
$data = self::get_random_binary($this->limit_filesize(self::$paramsmallfilesize[$this->size]));
$data = random_bytes_emulate($this->limit_filesize(self::$paramsmallfilesize[$this->size]));

$fs->create_file_from_string($filerecord, $data);
$this->dot($i, $count);
Expand All @@ -444,33 +442,10 @@ private function create_small_files() {
$this->end_log();
}

/**
* Creates a string of random binary data. The start of the string includes
* the current time, in an attempt to avoid large-scale repetition.
*
* @param int $length Number of bytes
* @return Random data
*/
private static function get_random_binary($length) {

$data = microtime(true);
if (strlen($data) > $length) {
// Use last digits of data.
return substr($data, -$length);
}
$length -= strlen($data);
for ($j = 0; $j < $length; $j++) {
$data .= chr(rand(1, 255));
}
return $data;
}

/**
* Creates a number of resource activities with one big file each.
*/
private function create_big_files() {
global $CFG;

// Work out how many files and how many blocks to use (up to 64KB).
$count = self::$parambigfilecount[$this->size];
$filesize = $this->limit_filesize(self::$parambigfilesize[$this->size]);
Expand Down Expand Up @@ -499,7 +474,7 @@ private function create_big_files() {
throw new coding_exception('Failed to open temporary file');
}
for ($j = 0; $j < $blocks; $j++) {
$data = self::get_random_binary($blocksize);
$data = random_bytes_emulate($blocksize);
fwrite($handle, $data);
$this->dot($i * $blocks + $j, $count * $blocks);
}
Expand Down
8 changes: 4 additions & 4 deletions admin/tool/generator/lang/en/tool_generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@

$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['coursesize_2'] = 'M (~100MB; create in ~2 minutes)';
$string['coursesize_3'] = 'L (~1GB; create in ~30 minutes)';
$string['coursesize_4'] = 'XL (~10GB; create in ~2 hours)';
$string['coursesize_5'] = 'XXL (~20GB; create in ~4 hours)';
$string['coursewithoutusers'] = 'The selected course has no users';
$string['createcourse'] = 'Create course';
$string['createtestplan'] = 'Create test plan';
Expand Down
3 changes: 2 additions & 1 deletion lib/classes/event/role_assigned.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ protected function get_legacy_eventdata() {
*/
protected function get_legacy_logdata() {
$roles = get_all_roles();
$rolenames = role_fix_names($roles, $this->get_context(), ROLENAME_ORIGINAL, true);
$neededrole = array($this->objectid => $roles[$this->objectid]);
$rolenames = role_fix_names($neededrole, $this->get_context(), ROLENAME_ORIGINAL, true);
return array($this->courseid, 'role', 'assign', 'admin/roles/assign.php?contextid='.$this->contextid.'&roleid='.$this->objectid,
$rolenames[$this->objectid], '', $this->userid);
}
Expand Down
17 changes: 9 additions & 8 deletions lib/moodlelib.php
Original file line number Diff line number Diff line change
Expand Up @@ -7803,20 +7803,21 @@ function random_bytes_emulate($length) {
}
}
if (function_exists('openssl_random_pseudo_bytes')) {
// For PHP 5.3 and later with openssl extension.
// If you have the openssl extension enabled.
$hash = openssl_random_pseudo_bytes($length);
if ($hash !== false) {
return $hash;
}
}

// Bad luck, there is no reliable random generator, let's just hash some unique stuff that is hard to guess.
$hash = sha1(serialize($CFG) . serialize($_SERVER) . microtime(true) . uniqid('', true), true);
// NOTE: the last param in sha1() is true, this means we are getting 20 bytes, not 40 chars as usual.
if ($length <= 20) {
return substr($hash, 0, $length);
}
return $hash . random_bytes_emulate($length - 20);
// Bad luck, there is no reliable random generator, let's just slowly hash some unique stuff that is hard to guess.
$staticdata = serialize($CFG) . serialize($_SERVER);
$hash = '';
do {
$hash .= sha1($staticdata . microtime(true) . uniqid('', true), true);
} while (strlen($hash) < $length);

return substr($hash, 0, $length);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions lib/tests/moodlelib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -3047,6 +3047,9 @@ public function test_random_bytes_emulate() {
$result = random_bytes_emulate(666);
$this->assertSame(666, strlen($result));

$result = random_bytes_emulate(40);
$this->assertSame(40, strlen($result));

$this->assertDebuggingNotCalled();

$result = random_bytes_emulate(0);
Expand Down

0 comments on commit 6a3acc8

Please sign in to comment.