Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 defined('MOODLE_INTERNAL') || die(); 20 21 global $CFG; 22 require_once($CFG->libdir . '/adminlib.php'); 23 require_once($CFG->libdir . '/statslib.php'); 24 require_once (__DIR__ . '/fixtures/stats_events.php'); 25 26 /** 27 * Test functions that affect daily stats. 28 * 29 * @package core 30 * @category test 31 * @copyright 2012 Tyler Bannister 32 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 33 */ 34 class statslib_test extends \advanced_testcase { 35 /** The day to use for testing **/ 36 const DAY = 1272672000; 37 38 /** The timezone to use for testing **/ 39 const TIMEZONE = 0; 40 41 /** @var array The list of temporary tables created for the statistic calculations **/ 42 protected $tables = array('temp_log1', 'temp_log2', 'temp_stats_daily', 'temp_stats_user_daily'); 43 44 /** @var array The replacements to be used when loading XML files **/ 45 protected $replacements = null; 46 47 48 /** 49 * Setup function 50 * - Allow changes to CFG->debug for testing purposes. 51 */ 52 protected function setUp(): void { 53 global $CFG, $DB; 54 parent::setUp(); 55 56 // Settings to force statistic to run during testing. 57 $this->setTimezone(self::TIMEZONE); 58 \core_date::set_default_server_timezone(); 59 $CFG->statsfirstrun = 'all'; 60 $CFG->statslastdaily = 0; 61 62 // Figure out the broken day start so I can figure out when to the start time should be. 63 $time = time(); 64 // This nonsense needs to be rewritten. 65 $date = new \DateTime('now', \core_date::get_server_timezone_object()); 66 $offset = $date->getOffset(); 67 $stime = $time + $offset; 68 $stime = intval($stime / (60*60*24)) * 60*60*24; 69 $stime -= $offset; 70 71 $shour = intval(($time - $stime) / (60*60)); 72 73 if ($DB->record_exists('user', array('username' => 'user1'))) { 74 return; 75 } 76 77 // Set up the database. 78 $datagen = self::getDataGenerator(); 79 80 $user1 = $datagen->create_user(array('username'=>'user1')); 81 $user2 = $datagen->create_user(array('username'=>'user2')); 82 83 $course1 = $datagen->create_course(array('shortname'=>'course1')); 84 $datagen->enrol_user($user1->id, $course1->id); 85 86 $this->generate_replacement_list(); 87 88 // Reset between tests. 89 $this->resetAfterTest(); 90 } 91 92 /** 93 * Function to setup database. 94 * 95 * @param phpunit_dataset $dataset Containing all the information loaded from fixtures. 96 * @param array $filter Tables to be sent to database. 97 */ 98 protected function prepare_db($dataset, $tables) { 99 global $DB; 100 101 foreach ($tables as $tablename) { 102 $DB->delete_records($tablename); 103 $dataset->to_database([$tablename]); 104 } 105 } 106 107 /** 108 * Load dataset from XML file. 109 */ 110 protected function generate_replacement_list() { 111 global $CFG, $DB; 112 113 if ($this->replacements !== null) { 114 return; 115 } 116 117 $this->setTimezone(self::TIMEZONE); 118 119 $guest = $DB->get_record('user', array('id' => $CFG->siteguest)); 120 $user1 = $DB->get_record('user', array('username' => 'user1')); 121 $user2 = $DB->get_record('user', array('username' => 'user2')); 122 123 if (($guest === false) || ($user1 === false) || ($user2 === false)) { 124 trigger_error('User setup incomplete', E_USER_ERROR); 125 } 126 127 $site = $DB->get_record('course', array('id' => SITEID)); 128 $course1 = $DB->get_record('course', array('shortname' => 'course1')); 129 130 if (($site === false) || ($course1 === false)) { 131 trigger_error('Course setup incomplete', E_USER_ERROR); 132 } 133 134 $start = stats_get_base_daily(self::DAY + 3600); 135 $startnolog = stats_get_base_daily(stats_get_start_from('daily')); 136 $gr = get_guest_role(); 137 $studentrole = $DB->get_record('role', array('shortname' => 'student')); 138 139 $this->replacements = array( 140 // Start and end times. 141 '[start_0]' => $start - 14410, // 4 hours before. 142 '[start_1]' => $start + 14410, // 4 hours after. 143 '[start_2]' => $start + 14420, 144 '[start_3]' => $start + 14430, 145 '[start_4]' => $start + 100800, // 28 hours after. 146 '[end]' => stats_get_next_day_start($start), 147 '[end_no_logs]' => stats_get_next_day_start($startnolog), 148 149 // User ids. 150 '[guest_id]' => $guest->id, 151 '[user1_id]' => $user1->id, 152 '[user2_id]' => $user2->id, 153 154 // Course ids. 155 '[course1_id]' => $course1->id, 156 '[site_id]' => SITEID, 157 158 // Role ids. 159 '[frontpage_roleid]' => (int) $CFG->defaultfrontpageroleid, 160 '[guest_roleid]' => $gr->id, 161 '[student_roleid]' => $studentrole->id, 162 ); 163 } 164 165 /** 166 * Load dataset from XML file. 167 * 168 * @param string $file The name of the file to load 169 * @return phpunit_dataset 170 */ 171 protected function load_xml_data_file($file) { 172 173 $xml = file_get_contents($file); 174 175 // Apply all the replacements straight in xml. 176 foreach ($this->replacements as $placeholder => $value) { 177 $placeholder = preg_quote($placeholder, '/'); 178 $xml = preg_replace('/' . $placeholder . '/', $value, $xml); 179 } 180 181 return $this->dataset_from_string($xml, 'xml'); 182 } 183 184 /** 185 * Provides the log data for test_statslib_cron_daily. 186 * 187 * @return array of fixture XML log file names. 188 */ 189 public function daily_log_provider() { 190 $logfiles = array(); 191 $fileno = array('00', '01', '02', '03', '04', '05', '06', '07', '08'); 192 193 foreach ($fileno as $no) { 194 $logfiles[] = array("statslib-test{$no}.xml"); 195 } 196 197 return $logfiles; 198 } 199 200 /** 201 * Set of data for test_statlibs_get_base_weekly 202 * 203 * @return array Dates and timezones for which the first day of the week will be calculated 204 */ 205 public function get_base_weekly_provider() { 206 return [ 207 [ 208 "startwday" => 0, 209 "timezone" => 'America/Chicago', 210 "timestart" => '18-03-2017 22:00', 211 "expected" => '12-03-2017 00:00:00' 212 ], 213 [ 214 "startwday" => 0, 215 "timezone" => 'America/Chicago', 216 "date" => '25-03-2017 22:00', 217 "expected" => '19-03-2017 00:00:00' 218 ], 219 [ 220 "startwday" => 1, 221 "timezone" => 'Atlantic/Canary', 222 "date" => '06-08-2018 22:00', 223 "expected" => '06-08-2018 00:00:00' 224 ], 225 ]; 226 } 227 228 /** 229 * Compare the expected stats to those in the database. 230 * 231 * @param array $expected 232 * @param string $output 233 */ 234 protected function verify_stats($expected, $output = '') { 235 global $DB; 236 237 // Note: We can not use $this->assertDataSetEqual($expected, $actual) because there's no 238 // $this->getConnection() in advanced_testcase. 239 240 foreach ($expected as $type => $table) { 241 $records = $DB->get_records($type); 242 243 $rows = count($table); 244 245 $message = 'Incorrect number of results returned for '. $type; 246 247 if ($output != '') { 248 $message .= "\nCron output:\n$output"; 249 } 250 251 $this->assertCount($rows, $records, $message); 252 253 for ($i = 0; $i < $rows; $i++) { 254 $row = $table[$i]; 255 $found = 0; 256 257 foreach ($records as $key => $record) { 258 $record = (array) $record; 259 unset($record['id']); 260 $diff = array_merge(array_diff_assoc($row, $record), 261 array_diff_assoc($record, $row)); 262 263 if (empty($diff)) { 264 $found = $key; 265 break; 266 } 267 } 268 269 $this->assertGreaterThan(0, $found, 'Expected log '. var_export($row, true) 270 ." was not found in $type ". var_export($records, true)); 271 unset($records[$found]); 272 } 273 } 274 } 275 276 /** 277 * Test progress output when debug is on. 278 */ 279 public function test_statslib_progress_debug() { 280 set_debugging(DEBUG_ALL); 281 $this->expectOutputString('1:0 '); 282 stats_progress('init'); 283 stats_progress('1'); 284 $this->resetDebugging(); 285 } 286 287 /** 288 * Test progress output when debug is off. 289 */ 290 public function test_statslib_progress_no_debug() { 291 set_debugging(DEBUG_NONE); 292 $this->expectOutputString('.'); 293 stats_progress('init'); 294 stats_progress('1'); 295 $this->resetDebugging(); 296 } 297 298 /** 299 * Test the function that gets the start date from the config. 300 */ 301 public function test_statslib_get_start_from() { 302 global $CFG, $DB; 303 304 $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test01.xml"); 305 $DB->delete_records('log'); 306 307 $date = new \DateTime('now', \core_date::get_server_timezone_object()); 308 $day = self::DAY - $date->getOffset(); 309 310 $CFG->statsfirstrun = 'all'; 311 // Allow 1 second difference in case we cross a second boundary. 312 // Note: within 3 days of a DST change - -3 days != 3 * 24 hours (it may be more or less). 313 $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - strtotime('-3 days', time()), 'All start time'); 314 315 $this->prepare_db($dataset, array('log')); 316 $records = $DB->get_records('log'); 317 318 $this->assertEquals($day + 14410, stats_get_start_from('daily'), 'Log entry start'); 319 320 $CFG->statsfirstrun = 'none'; 321 $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - strtotime('-3 days', time()), 'None start time'); 322 323 $CFG->statsfirstrun = 14515200; 324 $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - (time() - (14515200)), 'Specified start time'); 325 326 $this->prepare_db($dataset, array('stats_daily')); 327 $this->assertEquals($day + DAYSECS, stats_get_start_from('daily'), 'Daily stats start time'); 328 329 // New log stores. 330 $this->preventResetByRollback(); 331 332 $this->assertFileExists("$CFG->dirroot/$CFG->admin/tool/log/store/standard/version.php"); 333 set_config('enabled_stores', 'logstore_standard', 'tool_log'); 334 set_config('buffersize', 0, 'logstore_standard'); 335 set_config('logguests', 1, 'logstore_standard'); 336 get_log_manager(true); 337 338 $this->assertEquals(0, $DB->count_records('logstore_standard_log')); 339 340 $DB->delete_records('stats_daily'); 341 $CFG->statsfirstrun = 'all'; 342 $firstoldtime = $DB->get_field_sql('SELECT MIN(time) FROM {log}'); 343 344 $this->assertEquals($firstoldtime, stats_get_start_from('daily')); 345 346 $time = time() - 5; 347 \core_tests\event\create_executed::create(array('context' => \context_system::instance()))->trigger(); 348 $DB->set_field('logstore_standard_log', 'timecreated', $time++, [ 349 'eventname' => '\\core_tests\\event\\create_executed', 350 ]); 351 352 \core_tests\event\read_executed::create(array('context' => \context_system::instance()))->trigger(); 353 $DB->set_field('logstore_standard_log', 'timecreated', $time++, [ 354 'eventname' => '\\core_tests\\event\\read_executed', 355 ]); 356 357 \core_tests\event\update_executed::create(array('context' => \context_system::instance()))->trigger(); 358 $DB->set_field('logstore_standard_log', 'timecreated', $time++, [ 359 'eventname' => '\\core_tests\\event\\update_executed', 360 ]); 361 362 \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger(); 363 $DB->set_field('logstore_standard_log', 'timecreated', $time++, [ 364 'eventname' => '\\core_tests\\event\\delete_executed', 365 ]); 366 367 $DB->set_field('logstore_standard_log', 'origin', 'web', array()); 368 $logs = $DB->get_records('logstore_standard_log', null, 'timecreated ASC'); 369 $this->assertCount(4, $logs); 370 371 $firstnew = reset($logs); 372 $this->assertGreaterThan($firstoldtime, $firstnew->timecreated); 373 $DB->set_field('logstore_standard_log', 'timecreated', 10, array('id' => $firstnew->id)); 374 $this->assertEquals(10, stats_get_start_from('daily')); 375 376 $DB->set_field('logstore_standard_log', 'timecreated', $firstnew->timecreated, array('id' => $firstnew->id)); 377 $DB->delete_records('log'); 378 $this->assertEquals($firstnew->timecreated, stats_get_start_from('daily')); 379 380 set_config('enabled_stores', '', 'tool_log'); 381 get_log_manager(true); 382 } 383 384 /** 385 * Test the function that calculates the start of the day. 386 * 387 * NOTE: I don't think this is the way this function should work. 388 * This test documents the current functionality. 389 */ 390 public function test_statslib_get_base_daily() { 391 global $CFG; 392 393 for ($x = 0; $x < 13; $x += 1) { 394 $this->setTimezone($x); 395 396 $start = 1272672000 - ($x * 3600); 397 if ($x >= 20) { 398 $start += (24 * 3600); 399 } 400 401 $this->assertEquals($start, stats_get_base_daily(1272686410), "Timezone $x check"); 402 } 403 } 404 405 /** 406 * Test the function that gets the start of the next day. 407 */ 408 public function test_statslib_get_next_day_start() { 409 $this->setTimezone(0); 410 $this->assertEquals(1272758400, stats_get_next_day_start(1272686410)); 411 412 // Try setting timezone to some place in the US. 413 $this->setTimezone('America/New_York', 'America/New_York'); 414 // Then set the time for midnight before daylight savings. 415 // 1425790800 is midnight in New York (2015-03-08) Daylight saving will occur in 2 hours time. 416 // 1425873600 is midnight the next day. 417 $this->assertEquals(1425873600, stats_get_next_day_start(1425790800)); 418 $this->assertEquals(23, ((1425873600 - 1425790800) / 60 ) / 60); 419 // Then set the time for midnight before daylight savings ends. 420 // 1446350400 is midnight in New York (2015-11-01) Daylight saving will finish in 2 hours time. 421 // 1446440400 is midnight the next day. 422 $this->assertEquals(1446440400, stats_get_next_day_start(1446350400)); 423 $this->assertEquals(25, ((1446440400 - 1446350400) / 60 ) / 60); 424 // The next day should be normal. 425 $this->assertEquals(1446526800, stats_get_next_day_start(1446440400)); 426 $this->assertEquals(24, ((1446526800 - 1446440400) / 60 ) / 60); 427 } 428 429 /** 430 * Test the function that calculates the start of the week. 431 * 432 * @dataProvider get_base_weekly_provider 433 * @param int $startwday Day in which the week starts (Sunday = 0) 434 * @param string $timezone Default timezone 435 * @param string $timestart Date and time for which the first day of the week will be obtained 436 * @param string $expected Expected date of the first day of the week 437 */ 438 public function test_statslib_get_base_weekly($startwday, $timezone, $timestart, $expected) { 439 $this->setTimezone($timezone); 440 $time = strtotime($timestart); 441 $expected = strtotime($expected); 442 set_config('calendar_startwday', $startwday); 443 set_config('statslastweekly', $time); 444 445 $weekstarttime = stats_get_base_weekly($time); 446 447 $this->assertEquals($expected, $weekstarttime); 448 } 449 450 /** 451 * Test the function that gets the action names. 452 * 453 * Note: The function results depend on installed modules. The hard coded lists are the 454 * defaults for a new Moodle 2.3 install. 455 */ 456 public function test_statslib_get_action_names() { 457 $basepostactions = array ( 458 0 => 'add', 459 1 => 'delete', 460 2 => 'edit', 461 3 => 'add mod', 462 4 => 'delete mod', 463 5 => 'edit sectionenrol', 464 6 => 'loginas', 465 7 => 'new', 466 8 => 'unenrol', 467 9 => 'update', 468 10 => 'update mod', 469 11 => 'upload', 470 12 => 'submit', 471 13 => 'submit for grading', 472 14 => 'talk', 473 15 => 'choose', 474 16 => 'choose again', 475 17 => 'record delete', 476 18 => 'add discussion', 477 19 => 'add post', 478 20 => 'delete discussion', 479 21 => 'delete post', 480 22 => 'move discussion', 481 23 => 'prune post', 482 24 => 'update post', 483 25 => 'add category', 484 26 => 'add entry', 485 27 => 'approve entry', 486 28 => 'delete category', 487 29 => 'delete entry', 488 30 => 'edit category', 489 31 => 'update entry', 490 32 => 'end', 491 33 => 'start', 492 34 => 'attempt', 493 35 => 'close attempt', 494 36 => 'preview', 495 37 => 'editquestions', 496 38 => 'delete attempt', 497 39 => 'manualgrade', 498 ); 499 500 $baseviewactions = array ( 501 0 => 'view', 502 1 => 'view all', 503 2 => 'history', 504 3 => 'view submission', 505 4 => 'view feedback', 506 5 => 'print', 507 6 => 'report', 508 7 => 'view discussion', 509 8 => 'search', 510 9 => 'forum', 511 10 => 'forums', 512 11 => 'subscribers', 513 12 => 'view forum', 514 13 => 'view entry', 515 14 => 'review', 516 15 => 'pre-view', 517 16 => 'download', 518 17 => 'view form', 519 18 => 'view graph', 520 19 => 'view report', 521 ); 522 523 $postactions = stats_get_action_names('post'); 524 525 foreach ($basepostactions as $action) { 526 $this->assertContains($action, $postactions); 527 } 528 529 $viewactions = stats_get_action_names('view'); 530 531 foreach ($baseviewactions as $action) { 532 $this->assertContains($action, $viewactions); 533 } 534 } 535 536 /** 537 * Test the temporary table creation and deletion. 538 */ 539 public function test_statslib_temp_table_create_and_drop() { 540 global $DB; 541 542 foreach ($this->tables as $table) { 543 $this->assertFalse($DB->get_manager()->table_exists($table)); 544 } 545 546 stats_temp_table_create(); 547 548 foreach ($this->tables as $table) { 549 $this->assertTrue($DB->get_manager()->table_exists($table)); 550 } 551 552 stats_temp_table_drop(); 553 554 foreach ($this->tables as $table) { 555 $this->assertFalse($DB->get_manager()->table_exists($table)); 556 } 557 } 558 559 /** 560 * Test the temporary table creation and deletion. 561 * 562 * @depends test_statslib_temp_table_create_and_drop 563 */ 564 public function test_statslib_temp_table_fill() { 565 global $CFG, $DB, $USER; 566 567 $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test09.xml"); 568 $this->prepare_db($dataset, array('log')); 569 570 // This nonsense needs to be rewritten. 571 $date = new \DateTime('now', \core_date::get_server_timezone_object()); 572 $start = self::DAY - $date->getOffset(); 573 $end = $start + (24 * 3600); 574 575 stats_temp_table_create(); 576 stats_temp_table_fill($start, $end); 577 578 $this->assertEquals(1, $DB->count_records('temp_log1')); 579 $this->assertEquals(1, $DB->count_records('temp_log2')); 580 581 stats_temp_table_drop(); 582 583 // New log stores. 584 $this->preventResetByRollback(); 585 stats_temp_table_create(); 586 587 $course = $this->getDataGenerator()->create_course(); 588 $context = \context_course::instance($course->id); 589 $fcontext = \context_course::instance(SITEID); 590 $user = $this->getDataGenerator()->create_user(); 591 $this->setUser($user); 592 593 $this->assertFileExists("$CFG->dirroot/$CFG->admin/tool/log/store/standard/version.php"); 594 set_config('enabled_stores', 'logstore_standard', 'tool_log'); 595 set_config('buffersize', 0, 'logstore_standard'); 596 set_config('logguests', 1, 'logstore_standard'); 597 get_log_manager(true); 598 599 $DB->delete_records('logstore_standard_log'); 600 601 \core_tests\event\create_executed::create(array('context' => $fcontext, 'courseid' => SITEID))->trigger(); 602 \core_tests\event\read_executed::create(array('context' => $context, 'courseid' => $course->id))->trigger(); 603 \core_tests\event\update_executed::create(array('context' => \context_system::instance()))->trigger(); 604 \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger(); 605 606 \core\event\user_loggedin::create( 607 array( 608 'userid' => $USER->id, 609 'objectid' => $USER->id, 610 'other' => array('username' => $USER->username), 611 ) 612 )->trigger(); 613 614 $DB->set_field('logstore_standard_log', 'timecreated', 10); 615 616 $this->assertEquals(5, $DB->count_records('logstore_standard_log')); 617 618 \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger(); 619 \core_tests\event\delete_executed::create(array('context' => \context_system::instance()))->trigger(); 620 621 // Fake the origin of events. 622 $DB->set_field('logstore_standard_log', 'origin', 'web', array()); 623 624 $this->assertEquals(7, $DB->count_records('logstore_standard_log')); 625 626 stats_temp_table_fill(9, 11); 627 628 $logs1 = $DB->get_records('temp_log1'); 629 $logs2 = $DB->get_records('temp_log2'); 630 $this->assertCount(5, $logs1); 631 $this->assertCount(5, $logs2); 632 // The order of records in the temp tables is not guaranteed... 633 634 $viewcount = 0; 635 $updatecount = 0; 636 $logincount = 0; 637 foreach ($logs1 as $log) { 638 if ($log->course == $course->id) { 639 $this->assertEquals('view', $log->action); 640 $viewcount++; 641 } else { 642 $this->assertTrue(in_array($log->action, array('update', 'login'))); 643 if ($log->action === 'update') { 644 $updatecount++; 645 } else { 646 $logincount++; 647 } 648 $this->assertEquals(SITEID, $log->course); 649 } 650 $this->assertEquals($user->id, $log->userid); 651 } 652 $this->assertEquals(1, $viewcount); 653 $this->assertEquals(3, $updatecount); 654 $this->assertEquals(1, $logincount); 655 656 set_config('enabled_stores', '', 'tool_log'); 657 get_log_manager(true); 658 stats_temp_table_drop(); 659 } 660 661 /** 662 * Test the temporary table creation and deletion. 663 * 664 * @depends test_statslib_temp_table_create_and_drop 665 */ 666 public function test_statslib_temp_table_setup() { 667 global $DB; 668 669 $DB->delete_records('log'); 670 671 stats_temp_table_create(); 672 stats_temp_table_setup(); 673 674 $this->assertEquals(1, $DB->count_records('temp_enroled')); 675 676 stats_temp_table_drop(); 677 } 678 679 /** 680 * Test the function that clean out the temporary tables. 681 * 682 * @depends test_statslib_temp_table_create_and_drop 683 */ 684 public function test_statslib_temp_table_clean() { 685 global $DB; 686 687 $rows = array( 688 'temp_log1' => array('id' => 1, 'course' => 1), 689 'temp_log2' => array('id' => 1, 'course' => 1), 690 'temp_stats_daily' => array('id' => 1, 'courseid' => 1), 691 'temp_stats_user_daily' => array('id' => 1, 'courseid' => 1), 692 ); 693 694 stats_temp_table_create(); 695 696 foreach ($rows as $table => $row) { 697 $DB->insert_record_raw($table, $row); 698 $this->assertEquals(1, $DB->count_records($table)); 699 } 700 701 stats_temp_table_clean(); 702 703 foreach ($rows as $table => $row) { 704 $this->assertEquals(0, $DB->count_records($table)); 705 } 706 707 $this->assertEquals(1, $DB->count_records('stats_daily')); 708 $this->assertEquals(1, $DB->count_records('stats_user_daily')); 709 710 stats_temp_table_drop(); 711 } 712 713 /** 714 * Test the daily stats function. 715 * 716 * @depends test_statslib_get_base_daily 717 * @depends test_statslib_get_next_day_start 718 * @depends test_statslib_get_start_from 719 * @depends test_statslib_temp_table_create_and_drop 720 * @depends test_statslib_temp_table_setup 721 * @depends test_statslib_temp_table_fill 722 * @dataProvider daily_log_provider 723 */ 724 public function test_statslib_cron_daily($xmlfile) { 725 global $CFG, $DB; 726 727 $dataset = $this->load_xml_data_file(__DIR__."/fixtures/{$xmlfile}"); 728 $stats = $this->prepare_db($dataset, array('log')); 729 $stats = $dataset->get_rows(['stats_daily', 'stats_user_daily']); 730 731 // Stats cron daily uses mtrace, turn on buffering to silence output. 732 ob_start(); 733 stats_cron_daily(1); 734 $output = ob_get_contents(); 735 ob_end_clean(); 736 737 $this->verify_stats($stats, $output); 738 } 739 740 /** 741 * Test the daily stats function. 742 * 743 * @depends test_statslib_get_base_daily 744 * @depends test_statslib_get_next_day_start 745 */ 746 public function test_statslib_cron_daily_no_default_profile_id() { 747 global $CFG, $DB; 748 $CFG->defaultfrontpageroleid = 0; 749 750 $course1 = $DB->get_record('course', array('shortname' => 'course1')); 751 $guestid = $CFG->siteguest; 752 $start = stats_get_base_daily(1272758400); 753 $end = stats_get_next_day_start($start); 754 $fpid = (int) $CFG->defaultfrontpageroleid; 755 $gr = get_guest_role(); 756 757 $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test10.xml"); 758 $this->prepare_db($dataset, array('log')); 759 $stats = $dataset->get_rows(['stats_user_daily']); 760 761 // Stats cron daily uses mtrace, turn on buffering to silence output. 762 ob_start(); 763 stats_cron_daily($maxdays=1); 764 $output = ob_get_contents(); 765 ob_end_clean(); 766 767 $this->verify_stats($dataset, $output); 768 } 769 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body