Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
<?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/>.

namespace core;

/**
 * Unit tests for the xhprof class.
 *
 * @package   core
 * @category  test
 * @copyright 2019 Brendan Heywood <brendan@catalyst-au.net>
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class xhprof_test extends \advanced_testcase {

> public static function setUpBeforeClass(): void { /** > global $CFG; * Data provider for string matches > require_once($CFG->libdir . '/xhprof/xhprof_moodle.php'); * > } * @return array >
*/
< public function profiling_string_matches_provider() {
> public static function profiling_string_matches_provider(): array {
return [ ['/index.php', '/index.php', true], ['/some/dir/index.php', '/index.php', false], ['/course/view.php', '/course/view.php', true], ['/view.php', '/course/view.php', false], ['/mod/forum', '/mod/forum/*', false], ['/mod/forum/', '/mod/forum/*', true], ['/mod/forum/index.php', '/mod/forum/*', true], ['/mod/forum/foo.php', '/mod/forum/*', true], ['/mod/forum/view.php', '/mod/*/view.php', true], ['/mod/one/two/view.php', '/mod/*/view.php', true], ['/view.php', '*/view.php', true], ['/mod/one/two/view.php', '*/view.php', true], ['/foo.php', '/foo.php,/bar.php', true], ['/bar.php', '/foo.php,/bar.php', true], ['/foo/bar.php', "/foo.php,/bar.php", false], ['/foo/bar.php', "/foo.php,*/bar.php", true], ['/foo/bar.php', "/foo*.php,/bar.php", true], ['/foo.php', "/foo.php\n/bar.php", true], ['/bar.php', "/foo.php\n/bar.php", true], ['/foo/bar.php', "/foo.php\n/bar.php", false], ['/foo/bar.php', "/foo.php\n*/bar.php", true], ['/foo/bar.php', "/foo*.php\n/bar.php", true], ]; } /** * Test the matching syntax *
> * @covers ::profiling_string_matches
* @dataProvider profiling_string_matches_provider * @param string $string * @param string $patterns * @param bool $expected */ public function test_profiling_string_matches($string, $patterns, $expected) {
< < global $CFG; < require_once($CFG->libdir . '/xhprof/xhprof_moodle.php'); <
$result = profiling_string_matches($string, $patterns); $this->assertSame($result, $expected); }
> /** } > * Data provider for both the topological sort and the data reduction tests. > * > * @return array > */ > public static function run_data_provider(): array { > // This data corresponds to the runs used as example @ MDL-79285. > return [ > 'sorted_case' => [ > 'rundata' => array_flip([ > 'A', > 'A==>B', > 'A==>C', > 'A==>__Mustache4', > 'B==>__Mustache1', > '__Mustache1==>__Mustache2', > '__Mustache4==>__Mustache2', > '__Mustache4==>E', > 'E==>F', > 'C==>F', > '__Mustache2==>F', > '__Mustache2==>D', > 'D==>__Mustache3', > '__Mustache3==>F', > ]), > 'expectations' => [ > 'topofirst' => 'A', > 'topolast' => '__Mustache3==>F', > 'topocount' => 14, > 'topoorder' => [ > // Before and after pairs to verify they are ordered. > ['before' => 'A==>C', 'after' => 'C==>F'], > ['before' => 'D==>__Mustache3', 'after' => '__Mustache3==>F'], > ], > 'reducecount' => 8, > 'reduceremoved' => [ > // Elements that will be removed by the reduction. > '__Mustache1==>__Mustache2', > '__Mustache4==>__Mustache2', > '__Mustache2==>F', > '__Mustache2==>D', > '__Mustache2==>D', > '__Mustache3==>F', > ], > ], > ], > 'unsorted_case' => [ > 'rundata' => array_flip([ > 'A==>__Mustache4', > '__Mustache3==>F', > 'A==>B', > 'A==>C', > 'B==>__Mustache1', > '__Mustache1==>__Mustache2', > '__Mustache4==>__Mustache2', > '__Mustache4==>E', > 'E==>F', > 'C==>F', > '__Mustache2==>F', > '__Mustache2==>D', > 'D==>__Mustache3', > 'A', > ]), > 'expectations' => [ > 'topofirst' => 'A', > 'topolast' => '__Mustache3==>F', > 'topocount' => 14, > 'topoorder' => [ > // Before and after pairs to verify they are ordered. > ['before' => 'A==>C', 'after' => 'C==>F'], > ['before' => 'D==>__Mustache3', 'after' => '__Mustache3==>F'], > ], > 'reducecount' => 8, > 'reduceremoved' => [ > // Elements that will be removed by the reduction. > '__Mustache1==>__Mustache2', > '__Mustache4==>__Mustache2', > '__Mustache2==>F', > '__Mustache2==>D', > '__Mustache2==>D', > '__Mustache3==>F', > ], > ], > ], > ]; > } > > /** > * Test that topologically sorting the run data works as expected > * > * @covers \moodle_xhprofrun::xhprof_topo_sort > * @dataProvider run_data_provider > * > * @param array $rundata The run data to be sorted. > * @param array $expectations The expected results. > */ > public function test_xhprof_topo_sort(array $rundata, array $expectations) { > // Make sure all the examples in the provider are the same size. > $this->assertSame($expectations['topocount'], count($rundata)); > > // Make moodle_xhprofrun::xhprof_topo_sort() accessible. > $reflection = new \ReflectionClass('\moodle_xhprofrun'); > $method = $reflection->getMethod('xhprof_topo_sort'); > $method->setAccessible(true); > // Sort the data. > $result = $method->invokeArgs(new \moodle_xhprofrun(), [$rundata]); > $this->assertIsArray($result); > $this->assertSame($expectations['topocount'], count($result)); > // Convert the array to a list of keys, so we can assert values by position. > $resultkeys = array_keys($result); > > // This is the elements that should be first. > $this->assertSame($expectations['topofirst'], $resultkeys[0]); > // This is the element that should be last. > $this->assertSame($expectations['topolast'], $resultkeys[$expectations['topocount'] - 1]); > // This relative ordering should be respected. > foreach ($expectations['topoorder'] as $order) { > // All the elements in the expectations should be present. > $this->assertArrayHasKey($order['before'], $result); > $this->assertArrayHasKey($order['after'], $result); > // And they should be in the correct relative order. > $this->assertGreaterThan( > array_search($order['before'], $resultkeys), > array_search($order['after'], $resultkeys) > ); > } > > // Final check, if we sort it again, nothing changes (it's already topologically sorted). > $result2 = $method->invokeArgs(new \moodle_xhprofrun(), [$result]); > $this->assertSame($result, $result2); > } > > /** > * Test that reducing the data complexity works as expected > * > * @covers \moodle_xhprofrun::reduce_run_data > * @dataProvider run_data_provider > * > * @param array $rundata The run data to be reduced. > * @param array $expectations The expected results. > */ > public function test_reduce_run_data(array $rundata, array $expectations) { > // Make sure that the expected keys that will be removed are present. > foreach ($expectations['reduceremoved'] as $key) { > $this->assertArrayHasKey($key, $rundata); > } > > // Make moodle_xhprofrun::reduce_run_data() accessible. > $reflection = new \ReflectionClass('\moodle_xhprofrun'); > $method = $reflection->getMethod('reduce_run_data'); > $method->setAccessible(true); > // Reduce the data. > $result = $method->invokeArgs(new \moodle_xhprofrun(), [$rundata]); > $this->assertIsArray($result); > $this->assertSame($expectations['reducecount'], count($result)); > // These have been the removed elements. > foreach ($expectations['reduceremoved'] as $key) { > $this->assertArrayNotHasKey($key, $result); > } > > // Final check, if we reduce it again, nothing changes (it's already reduced). > $result2 = $method->invokeArgs(new \moodle_xhprofrun(), [$result]); > $this->assertSame($result, $result2); > }