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