See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core; 18 19 /** 20 * Unit tests for the xhprof class. 21 * 22 * @package core 23 * @category test 24 * @copyright 2019 Brendan Heywood <brendan@catalyst-au.net> 25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 26 */ 27 class xhprof_test extends \advanced_testcase { 28 29 public static function setUpBeforeClass(): void { 30 global $CFG; 31 require_once($CFG->libdir . '/xhprof/xhprof_moodle.php'); 32 } 33 34 /** 35 * Data provider for string matches 36 * 37 * @return array 38 */ 39 public static function profiling_string_matches_provider(): array { 40 return [ 41 ['/index.php', '/index.php', true], 42 ['/some/dir/index.php', '/index.php', false], 43 ['/course/view.php', '/course/view.php', true], 44 ['/view.php', '/course/view.php', false], 45 ['/mod/forum', '/mod/forum/*', false], 46 ['/mod/forum/', '/mod/forum/*', true], 47 ['/mod/forum/index.php', '/mod/forum/*', true], 48 ['/mod/forum/foo.php', '/mod/forum/*', true], 49 ['/mod/forum/view.php', '/mod/*/view.php', true], 50 ['/mod/one/two/view.php', '/mod/*/view.php', true], 51 ['/view.php', '*/view.php', true], 52 ['/mod/one/two/view.php', '*/view.php', true], 53 ['/foo.php', '/foo.php,/bar.php', true], 54 ['/bar.php', '/foo.php,/bar.php', true], 55 ['/foo/bar.php', "/foo.php,/bar.php", false], 56 ['/foo/bar.php', "/foo.php,*/bar.php", true], 57 ['/foo/bar.php', "/foo*.php,/bar.php", true], 58 ['/foo.php', "/foo.php\n/bar.php", true], 59 ['/bar.php', "/foo.php\n/bar.php", true], 60 ['/foo/bar.php', "/foo.php\n/bar.php", false], 61 ['/foo/bar.php', "/foo.php\n*/bar.php", true], 62 ['/foo/bar.php', "/foo*.php\n/bar.php", true], 63 ]; 64 } 65 66 /** 67 * Test the matching syntax 68 * 69 * @covers ::profiling_string_matches 70 * @dataProvider profiling_string_matches_provider 71 * @param string $string 72 * @param string $patterns 73 * @param bool $expected 74 */ 75 public function test_profiling_string_matches($string, $patterns, $expected) { 76 $result = profiling_string_matches($string, $patterns); 77 $this->assertSame($result, $expected); 78 } 79 80 /** 81 * Data provider for both the topological sort and the data reduction tests. 82 * 83 * @return array 84 */ 85 public static function run_data_provider(): array { 86 // This data corresponds to the runs used as example @ MDL-79285. 87 return [ 88 'sorted_case' => [ 89 'rundata' => array_flip([ 90 'A', 91 'A==>B', 92 'A==>C', 93 'A==>__Mustache4', 94 'B==>__Mustache1', 95 '__Mustache1==>__Mustache2', 96 '__Mustache4==>__Mustache2', 97 '__Mustache4==>E', 98 'E==>F', 99 'C==>F', 100 '__Mustache2==>F', 101 '__Mustache2==>D', 102 'D==>__Mustache3', 103 '__Mustache3==>F', 104 ]), 105 'expectations' => [ 106 'topofirst' => 'A', 107 'topolast' => '__Mustache3==>F', 108 'topocount' => 14, 109 'topoorder' => [ 110 // Before and after pairs to verify they are ordered. 111 ['before' => 'A==>C', 'after' => 'C==>F'], 112 ['before' => 'D==>__Mustache3', 'after' => '__Mustache3==>F'], 113 ], 114 'reducecount' => 8, 115 'reduceremoved' => [ 116 // Elements that will be removed by the reduction. 117 '__Mustache1==>__Mustache2', 118 '__Mustache4==>__Mustache2', 119 '__Mustache2==>F', 120 '__Mustache2==>D', 121 '__Mustache2==>D', 122 '__Mustache3==>F', 123 ], 124 ], 125 ], 126 'unsorted_case' => [ 127 'rundata' => array_flip([ 128 'A==>__Mustache4', 129 '__Mustache3==>F', 130 'A==>B', 131 'A==>C', 132 'B==>__Mustache1', 133 '__Mustache1==>__Mustache2', 134 '__Mustache4==>__Mustache2', 135 '__Mustache4==>E', 136 'E==>F', 137 'C==>F', 138 '__Mustache2==>F', 139 '__Mustache2==>D', 140 'D==>__Mustache3', 141 'A', 142 ]), 143 'expectations' => [ 144 'topofirst' => 'A', 145 'topolast' => '__Mustache3==>F', 146 'topocount' => 14, 147 'topoorder' => [ 148 // Before and after pairs to verify they are ordered. 149 ['before' => 'A==>C', 'after' => 'C==>F'], 150 ['before' => 'D==>__Mustache3', 'after' => '__Mustache3==>F'], 151 ], 152 'reducecount' => 8, 153 'reduceremoved' => [ 154 // Elements that will be removed by the reduction. 155 '__Mustache1==>__Mustache2', 156 '__Mustache4==>__Mustache2', 157 '__Mustache2==>F', 158 '__Mustache2==>D', 159 '__Mustache2==>D', 160 '__Mustache3==>F', 161 ], 162 ], 163 ], 164 ]; 165 } 166 167 /** 168 * Test that topologically sorting the run data works as expected 169 * 170 * @covers \moodle_xhprofrun::xhprof_topo_sort 171 * @dataProvider run_data_provider 172 * 173 * @param array $rundata The run data to be sorted. 174 * @param array $expectations The expected results. 175 */ 176 public function test_xhprof_topo_sort(array $rundata, array $expectations) { 177 // Make sure all the examples in the provider are the same size. 178 $this->assertSame($expectations['topocount'], count($rundata)); 179 180 // Make moodle_xhprofrun::xhprof_topo_sort() accessible. 181 $reflection = new \ReflectionClass('\moodle_xhprofrun'); 182 $method = $reflection->getMethod('xhprof_topo_sort'); 183 $method->setAccessible(true); 184 // Sort the data. 185 $result = $method->invokeArgs(new \moodle_xhprofrun(), [$rundata]); 186 $this->assertIsArray($result); 187 $this->assertSame($expectations['topocount'], count($result)); 188 // Convert the array to a list of keys, so we can assert values by position. 189 $resultkeys = array_keys($result); 190 191 // This is the elements that should be first. 192 $this->assertSame($expectations['topofirst'], $resultkeys[0]); 193 // This is the element that should be last. 194 $this->assertSame($expectations['topolast'], $resultkeys[$expectations['topocount'] - 1]); 195 // This relative ordering should be respected. 196 foreach ($expectations['topoorder'] as $order) { 197 // All the elements in the expectations should be present. 198 $this->assertArrayHasKey($order['before'], $result); 199 $this->assertArrayHasKey($order['after'], $result); 200 // And they should be in the correct relative order. 201 $this->assertGreaterThan( 202 array_search($order['before'], $resultkeys), 203 array_search($order['after'], $resultkeys) 204 ); 205 } 206 207 // Final check, if we sort it again, nothing changes (it's already topologically sorted). 208 $result2 = $method->invokeArgs(new \moodle_xhprofrun(), [$result]); 209 $this->assertSame($result, $result2); 210 } 211 212 /** 213 * Test that reducing the data complexity works as expected 214 * 215 * @covers \moodle_xhprofrun::reduce_run_data 216 * @dataProvider run_data_provider 217 * 218 * @param array $rundata The run data to be reduced. 219 * @param array $expectations The expected results. 220 */ 221 public function test_reduce_run_data(array $rundata, array $expectations) { 222 // Make sure that the expected keys that will be removed are present. 223 foreach ($expectations['reduceremoved'] as $key) { 224 $this->assertArrayHasKey($key, $rundata); 225 } 226 227 // Make moodle_xhprofrun::reduce_run_data() accessible. 228 $reflection = new \ReflectionClass('\moodle_xhprofrun'); 229 $method = $reflection->getMethod('reduce_run_data'); 230 $method->setAccessible(true); 231 // Reduce the data. 232 $result = $method->invokeArgs(new \moodle_xhprofrun(), [$rundata]); 233 $this->assertIsArray($result); 234 $this->assertSame($expectations['reducecount'], count($result)); 235 // These have been the removed elements. 236 foreach ($expectations['reduceremoved'] as $key) { 237 $this->assertArrayNotHasKey($key, $result); 238 } 239 240 // Final check, if we reduce it again, nothing changes (it's already reduced). 241 $result2 = $method->invokeArgs(new \moodle_xhprofrun(), [$result]); 242 $this->assertSame($result, $result2); 243 } 244 } 245
title
Description
Body
title
Description
Body
title
Description
Body
title
Body