From c0f00c5fbae6156640b95dba2bbcc1a41e1d5857 Mon Sep 17 00:00:00 2001
From: Tyler Bannister <tyler.bannister@remote-learner.net>
Date: Fri, 3 Aug 2012 15:53:27 -0400
Subject: [PATCH] MDL-30643 - Added statslib test file.           - Tests daily
 stats and daily stats related functions.

---
 lib/statslib.php                       |  15 +-
 lib/tests/fixtures/statslib-test00.xml |  35 ++
 lib/tests/fixtures/statslib-test01.xml | 116 +++++
 lib/tests/fixtures/statslib-test02.xml | 117 +++++
 lib/tests/fixtures/statslib-test03.xml | 151 +++++++
 lib/tests/fixtures/statslib-test04.xml | 157 +++++++
 lib/tests/fixtures/statslib-test05.xml | 151 +++++++
 lib/tests/fixtures/statslib-test06.xml | 157 +++++++
 lib/tests/fixtures/statslib-test07.xml | 166 +++++++
 lib/tests/fixtures/statslib-test08.xml | 132 ++++++
 lib/tests/fixtures/statslib-test09.xml | 129 ++++++
 lib/tests/fixtures/statslib-test10.xml | 107 +++++
 lib/tests/statslib_test.php            | 581 +++++++++++++++++++++++++
 13 files changed, 2009 insertions(+), 5 deletions(-)
 create mode 100644 lib/tests/fixtures/statslib-test00.xml
 create mode 100644 lib/tests/fixtures/statslib-test01.xml
 create mode 100644 lib/tests/fixtures/statslib-test02.xml
 create mode 100644 lib/tests/fixtures/statslib-test03.xml
 create mode 100644 lib/tests/fixtures/statslib-test04.xml
 create mode 100644 lib/tests/fixtures/statslib-test05.xml
 create mode 100644 lib/tests/fixtures/statslib-test06.xml
 create mode 100644 lib/tests/fixtures/statslib-test07.xml
 create mode 100644 lib/tests/fixtures/statslib-test08.xml
 create mode 100644 lib/tests/fixtures/statslib-test09.xml
 create mode 100644 lib/tests/fixtures/statslib-test10.xml
 create mode 100644 lib/tests/statslib_test.php

diff --git a/lib/statslib.php b/lib/statslib.php
index 67a446d7399..eee36ec741f 100644
--- a/lib/statslib.php
+++ b/lib/statslib.php
@@ -217,12 +217,16 @@ function stats_cron_daily($maxdays=1) {
             break;
         }
 
-        stats_progress('0');
-
         // Find out if any logs available for this day
         $sql = "SELECT 'x' FROM {temp_log1} l";
         $logspresent = $DB->get_records_sql($sql, null, 0, 1);
 
+        if ($logspresent) {
+            // Insert blank record to force Query 10 to generate additional row when no logs for
+            // the site with userid 0 exist.  Added for backwards compatibility.
+            $DB->insert_record('temp_log1', array('userid' => 0, 'course' => SITEID, 'action' => ''));
+        }
+
         // Calculate the number of active users today
         $sql = 'SELECT COUNT(DISTINCT u.id)
                   FROM {user} u
@@ -230,6 +234,8 @@ function stats_cron_daily($maxdays=1) {
                  WHERE u.deleted = 0';
         $dailyactiveusers = $DB->count_records_sql($sql);
 
+        stats_progress('0');
+
         // Process login info first
         // Note: PostgreSQL doesn't like aliases in HAVING clauses
         $sql = "INSERT INTO {temp_stats_user_daily}
@@ -427,7 +433,6 @@ function stats_cron_daily($maxdays=1) {
                        SUM(CASE WHEN action $viewactionssql THEN 1 ELSE 0 END) AS statsreads,
                        SUM(CASE WHEN action $postactionssql THEN 1 ELSE 0 END) AS statswrites
                   FROM {temp_log1} l
-                 WHERE !(course = 0 AND userid = 0)
               GROUP BY userid, courseid";
 
         if ($logspresent && !stats_run_query($sql, array_merge($params1, $params2))) {
@@ -1640,10 +1645,10 @@ function stats_temp_table_drop() {
 function stats_temp_table_fill($timestart, $timeend) {
     global $DB;
 
-    $sql = "INSERT INTO {temp_log1} (userid, course, action)
+    $sql = 'INSERT INTO {temp_log1} (userid, course, action)
 
             SELECT userid, course, action FROM {log}
-             WHERE time >= ? AND time < ?";
+             WHERE time >= ? AND time < ?';
 
     $DB->execute($sql, array($timestart, $timeend));
 
diff --git a/lib/tests/fixtures/statslib-test00.xml b/lib/tests/fixtures/statslib-test00.xml
new file mode 100644
index 00000000000..f41e8f34d62
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test00.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- Tests no logs - Only query 3 should be processed -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <row>
+            <value>[course1_id]</value>
+            <value>[end_no_logs]</value>
+            <value>5</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test01.xml b/lib/tests/fixtures/statslib-test01.xml
new file mode 100644
index 00000000000..bcfc903a56a
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test01.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- No login test - Tests queries 2, 3, 5, 7, 9 (and 8), 10 (read) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[guest_id]</value>
+            <value>[site_id]</value>
+            <value>view</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 16 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[guest_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 10 - read -->
+        <row>
+            <value>[site_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test02.xml b/lib/tests/fixtures/statslib-test02.xml
new file mode 100644
index 00000000000..1b1cd351751
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test02.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- Single login - Tests queries 1, 2 (with logins), 4 -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 - read -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test03.xml b/lib/tests/fixtures/statslib-test03.xml
new file mode 100644
index 00000000000..db0c2a0344e
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test03.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- Guest login and view course - Tests queries 11 (read), 13 (guest) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[guest_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_2]</value>
+            <value>[guest_id]</value>
+            <value>[course1_id]</value>
+            <value>view</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 13 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[guest_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test04.xml b/lib/tests/fixtures/statslib-test04.xml
new file mode 100644
index 00000000000..efe9e2ace0d
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test04.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- Guest login, view course, and upload assignment - Tests queries 10+11 (write) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[guest_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_2]</value>
+            <value>[guest_id]</value>
+            <value>[course1_id]</value>
+            <value>view</value>
+        </row>
+        <row>
+            <value>[start_3]</value>
+            <value>[guest_id]</value>
+            <value>[course1_id]</value>
+            <value>add post</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 13 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[guest_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>1</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test05.xml b/lib/tests/fixtures/statslib-test05.xml
new file mode 100644
index 00000000000..b839f74f78b
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test05.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- User login and view course - Tests queries 4, 6, 10, 12, 14 (read) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_2]</value>
+            <value>[user1_id]</value>
+            <value>[course1_id]</value>
+            <value>view</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Queris 3 (stat1) and 4 (stat2) -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Queries 5 (stat1) and 6 (stat2) -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 12 (read) -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test06.xml b/lib/tests/fixtures/statslib-test06.xml
new file mode 100644
index 00000000000..04017102ee5
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test06.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- User login, view course and post - Tests queries 10, 12, 14 (write) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_2]</value>
+            <value>[user1_id]</value>
+            <value>[course1_id]</value>
+            <value>view</value>
+        </row>
+        <row>
+            <value>[start_3]</value>
+            <value>[user1_id]</value>
+            <value>[course1_id]</value>
+            <value>add post</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Queris 3 (stat1) and 4 (stat2) -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Queries 5 (stat1) and 6 (stat2) -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 12 (read) -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>1</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test07.xml b/lib/tests/fixtures/statslib-test07.xml
new file mode 100644
index 00000000000..86379b8b91d
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test07.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- User login and view course (not enrolled) - Tests queries 13 (not enroled), 14 (not default) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[user2_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_2]</value>
+            <value>[user2_id]</value>
+            <value>[site_id]</value>
+            <value>view</value>
+        </row>
+        <row>
+            <value>[start_3]</value>
+            <value>[user2_id]</value>
+            <value>[course1_id]</value>
+            <value>view</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 13 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[guest_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 14 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user2_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[user2_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user2_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test08.xml b/lib/tests/fixtures/statslib-test08.xml
new file mode 100644
index 00000000000..62a90c91bf1
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test08.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- User login and view site - Tests query 15 (front page views) -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_2]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>view</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 15 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test09.xml b/lib/tests/fixtures/statslib-test09.xml
new file mode 100644
index 00000000000..efe77b691d5
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test09.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- Multiple logins on different days -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_0]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_1]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+        <row>
+            <value>[start_4]</value>
+            <value>[user1_id]</value>
+            <value>[site_id]</value>
+            <value>login</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>1</value>
+            <value>1</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 9 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[frontpage_roleid]</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 1 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>logins</value>
+        </row>
+        <!-- Query 10 - read -->
+        <row>
+            <value>[site_id]</value>
+            <value>[user1_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/fixtures/statslib-test10.xml b/lib/tests/fixtures/statslib-test10.xml
new file mode 100644
index 00000000000..83d7fcc2c1f
--- /dev/null
+++ b/lib/tests/fixtures/statslib-test10.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- No default profile id test -->
+<dataset>
+    <table name="log">
+        <column>time</column>
+        <column>userid</column>
+        <column>course</column>
+        <column>action</column>
+        <row>
+            <value>[start_1]</value>
+            <value>[guest_id]</value>
+            <value>[site_id]</value>
+            <value>view</value>
+        </row>
+    </table>
+    <table name="stats_daily">
+        <column>courseid</column>
+        <column>timeend</column>
+        <column>roleid</column>
+        <column>stattype</column>
+        <column>stat1</column>
+        <column>stat2</column>
+        <!-- Query 2 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>logins</value>
+            <value>0</value>
+            <value>0</value>
+        </row>
+        <!-- Query 3 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>[student_roleid]</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 5 -->
+        <row>
+            <value>[course1_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 7 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>enrolments</value>
+            <value>4</value>
+            <value>1</value>
+        </row>
+        <!-- Query 11 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+        <!-- Query 16 -->
+        <row>
+            <value>[site_id]</value>
+            <value>[end]</value>
+            <value>[guest_roleid]</value>
+            <value>activity</value>
+            <value>1</value>
+            <value>0</value>
+        </row>
+    </table>
+    <table name="stats_user_daily">
+        <column>courseid</column>
+        <column>userid</column>
+        <column>roleid</column>
+        <column>timeend</column>
+        <column>statsreads</column>
+        <column>statswrites</column>
+        <column>stattype</column>
+        <!-- Query 10 - read -->
+        <row>
+            <value>[site_id]</value>
+            <value>[guest_id]</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>1</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+        <!-- Query 10 - default record -->
+        <row>
+            <value>[site_id]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>[end]</value>
+            <value>0</value>
+            <value>0</value>
+            <value>activity</value>
+        </row>
+    </table>
+</dataset>
diff --git a/lib/tests/statslib_test.php b/lib/tests/statslib_test.php
new file mode 100644
index 00000000000..6c02d25999d
--- /dev/null
+++ b/lib/tests/statslib_test.php
@@ -0,0 +1,581 @@
+<?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/>.
+
+/**
+ * Tests for ../statslib.php
+ *
+ * @package    core
+ * @subpackage stats
+ * @copyright  2012 Tyler Bannister
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->libdir . '/adminlib.php');
+require_once($CFG->libdir . '/statslib.php');
+
+/**
+ * Test functions that affect daily stats
+ */
+class statslib_daily_testcase extends advanced_testcase {
+    /** The student role ID **/
+    const STID = 5;
+
+    /** The day to use for testing **/
+    const DAY = 1272700810;  // 1272758400
+
+    /** @var array The list of temporary tables created for the statistic calculations **/
+    protected $tables = array('temp_log1', 'temp_log2', 'temp_stats_daily', 'temp_stats_user_daily');
+
+    /** @var array The replacements to be used when loading XML files **/
+    protected $replacements = null;
+
+    /**
+     * Set up the database for tests
+     *
+     * This function is needed so that daily_log_provider has the before-test set up from setUp()
+     */
+    public function setUpDB() {
+        global $DB;
+
+        if ($DB->record_exists('user', array('username' => 'user1'))) {
+            return;
+        }
+
+        $datagen = self::getDataGenerator();
+
+        $user1   = $datagen->create_user(array('username'=>'user1'));
+        $user2   = $datagen->create_user(array('username'=>'user2'));
+
+        $course1 = $datagen->create_course(array('shortname'=>'course1'));
+
+        $success = enrol_try_internal_enrol($course1->id, $user1->id, 5);
+
+        if (! $success) {
+            trigger_error('User enrollment failed', E_USER_ERROR);
+        }
+
+        $context = context_system::instance();
+        role_assign(self::STID, $user2->id, $context->id);
+
+        $this->generate_replacement_list();
+    }
+
+    /**
+     * Setup function
+     *   - Allow changes to CFG->debug for testing purposes.
+     */
+    protected function setUp() {
+        global $CFG;
+        parent::setUp();
+
+        // Settings to force statistic to run during testing
+        $CFG->timezone                = 99;
+        $CFG->statsfirstrun           = 'all';
+        $CFG->statslastdaily          = 0;
+        $CFG->statslastexecution      = 0;
+        $CFG->statsruntimestarthour   = date('H');
+        $CFG->statsruntimestartminute = 0;
+
+        $this->setUpDB();
+
+        $this->resetAfterTest(true);
+    }
+
+    /**
+     * Function to setup database.
+     *
+     * @param array $dataset An array of tables including the log table.
+     */
+    protected function prepare_db($dataset, $tables) {
+        global $DB;
+
+        foreach ($tables as $tablename) {
+            $DB->delete_records($tablename);
+
+            foreach ($dataset as $name => $table) {
+
+                if ($tablename == $name) {
+
+                    $rows = $table->getRowCount();
+
+                    for ($i = 0; $i < $rows; $i++) {
+                        $row = $table->getRow($i);
+
+                        $DB->insert_record($tablename, $row, false, true);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Load dataset from XML file
+     *
+     * @param string $file The name of the file to load
+     */
+    protected function generate_replacement_list() {
+        global $CFG, $DB;
+
+        if ($this->replacements !== null) {
+            return;
+        }
+
+        $guest = $DB->get_record('user', array('id' => $CFG->siteguest));
+        $user1 = $DB->get_record('user', array('username' => 'user1'));
+        $user2 = $DB->get_record('user', array('username' => 'user2'));
+
+        if (($guest === false) || ($user1 === false) || ($user2 === false)) {
+            trigger_error('User setup incomplete', E_USER_ERROR);
+        }
+
+        $site    = $DB->get_record('course', array('id' => SITEID));
+        $course1 = $DB->get_record('course', array('shortname' => 'course1'));
+
+        if (($site === false) || ($course1 === false)) {
+            trigger_error('Course setup incomplete', E_USER_ERROR);
+        }
+
+        $start      = stats_get_base_daily(self::DAY + 3600);
+        $startnolog = stats_get_base_daily(stats_get_start_from('daily'));
+        $gr         = get_guest_role();
+
+        $this->replacements = array(
+            // Start and end times
+            '[start_0]'          => $start -  14410,  // 4 hours before
+            '[start_1]'          => $start +  14410,  // 4 hours after
+            '[start_2]'          => $start +  14420,
+            '[start_3]'          => $start +  14430,
+            '[start_4]'          => $start + 100800, // 28 hours after
+            '[end]'              => stats_get_next_day_start($start),
+            '[end_no_logs]'      => stats_get_next_day_start($startnolog),
+
+            // User ids
+            '[guest_id]'         => $guest->id,
+            '[user1_id]'         => $user1->id,
+            '[user2_id]'         => $user2->id,
+
+            // Course ids
+            '[course1_id]'       => $course1->id,
+            '[site_id]'          => SITEID,
+
+            // Role ids
+            '[frontpage_roleid]' => (int) $CFG->defaultfrontpageroleid,
+            '[guest_roleid]'     => $gr->id,
+            '[student_roleid]'   => self::STID,
+        );
+    }
+
+    /**
+     * Load dataset from XML file
+     *
+     * @param string $file The name of the file to load
+     */
+    protected function load_xml_data_file($file) {
+        static $replacements = null;
+
+        $raw   = $this->createXMLDataSet($file);
+        $clean = new PHPUnit_Extensions_Database_DataSet_ReplacementDataSet($raw);
+
+        foreach ($this->replacements as $placeholder => $value) {
+            $clean->addFullReplacement($placeholder, $value);
+        }
+
+        $logs = new PHPUnit_Extensions_Database_DataSet_DataSetFilter($clean);
+        $logs->addIncludeTables(array('log'));
+
+        $stats = new PHPUnit_Extensions_Database_DataSet_DataSetFilter($clean);
+        $stats->addIncludeTables(array('stats_daily', 'stats_user_daily'));
+
+        return array($logs, $stats);
+    }
+
+    /**
+     * Provides the log data for test_statslib_cron_daily
+     */
+    public function daily_log_provider() {
+        global $CFG, $DB;
+
+        $this->setUpDB();
+
+        $tests = array('00', '01', '02', '03', '04', '05', '06', '07', '08');
+
+        $dataset = array();
+
+        foreach ($tests as $test) {
+            $dataset[] = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test{$test}.xml");
+        }
+
+        return $dataset;
+    }
+
+    /**
+     * Compare the expected stats to those in the database.
+     *
+     * @param array $stats An array of arrays of arrays of both types of stats
+     */
+    protected function verify_stats($expected) {
+        global $DB;
+
+        // Note: We can not use $this->assertDataSetEqual($expected, $actual) because there's no
+        //       $this->getConnection() in advanced_testcase.
+
+        foreach ($expected as $type => $table) {
+            $records = $DB->get_records($type);
+
+            $rows = $table->getRowCount();
+
+            $this->assertEquals($rows, sizeof($records),
+                    'Incorrect number of results returned for '. $type);
+
+            for ($i = 0; $i < $rows; $i++) {
+                $row   = $table->getRow($i);
+                $found = 0;
+
+                foreach ($records as $key => $record) {
+                    $record = (array) $record;
+                    unset($record['id']);
+                    $diff = array_merge(array_diff_assoc($row, $record),
+                            array_diff_assoc($record, $row));
+
+                    if (empty($diff)) {
+                        $found = $key;
+                        break;
+                    }
+                }
+                $this->assertGreaterThan(0, $found, 'Expected log '. var_export($row, true)
+                                        ." was not found in $type ". var_export($records, true));
+                unset($records[$found]);
+            }
+        }
+    }
+
+    /**
+     * Test progress output when debug is on
+     */
+    public function test_statslib_progress_debug() {
+        global $CFG;
+
+        $CFG->debug = DEBUG_ALL;
+        $this->expectOutputString('1:0 ');
+        stats_progress('init');
+        stats_progress('1');
+    }
+
+    /**
+     * Test progress output when debug is off
+     */
+    public function test_statslib_progress_no_debug() {
+        global $CFG;
+
+        $CFG->debug = DEBUG_NONE;
+        $this->expectOutputString('.');
+        stats_progress('init');
+        stats_progress('1');
+    }
+
+    /**
+     * Test the function that gets the start date from the config
+     */
+    public function test_statslib_get_start_from() {
+        global $CFG, $DB;
+
+        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test01.xml");
+
+        $time = time();
+        $DB->delete_records('log');
+
+        $CFG->statsfirstrun = 'all';
+        // Allow 1 second difference in case we cross a second boundary.
+        $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - ($time - (3 * 24 * 3600)), 'All start time');
+
+        $this->prepare_db($dataset[0], array('log'));
+        $records = $DB->get_records('log');
+
+        $this->assertEquals(self::DAY, stats_get_start_from('daily'), 'Log entry start');
+
+        $CFG->statsfirstrun = 'none';
+        $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - ($time - (3 * 24 * 3600)), 'None start time');
+
+        $CFG->statsfirstrun = 14515200;
+        $this->assertLessThanOrEqual(1, stats_get_start_from('daily') - ($time - (14515200)), 'Specified start time');
+
+        $this->prepare_db($dataset[1], array('stats_daily'));
+        $this->assertEquals(self::DAY - 14410 + (24 * 3600), stats_get_start_from('daily'), 'Daily stats start time');
+    }
+
+    /**
+     * Test the function that calculates the start of the day
+     */
+    public function test_statslib_get_base_daily() {
+        global $CFG;
+
+        $CFG->timezone = 0;
+        $this->assertEquals(1272672000, stats_get_base_daily(1272686410));
+        $CFG->timezone = 5;
+        $this->assertEquals(1272654000, stats_get_base_daily(1272686410));
+    }
+
+    /**
+     * Test the function that gets the start of the next day
+     */
+    public function test_statslib_get_next_day_start() {
+        global $CFG;
+
+        $CFG->timezone = 0;
+        $this->assertEquals(1272758400, stats_get_next_day_start(1272686410));
+    }
+
+    /**
+     * Test the function that gets the action names
+     *
+     * Note: The function results depend on installed modules.  The hard coded lists are the
+     *       defaults for a new Moodle 2.3 install.
+     */
+    public function test_statslib_get_action_names() {
+        $basepostactions = array (
+            0 => 'add',
+            1 => 'delete',
+            2 => 'edit',
+            3 => 'add mod',
+            4 => 'delete mod',
+            5 => 'edit sectionenrol',
+            6 => 'loginas',
+            7 => 'new',
+            8 => 'unenrol',
+            9 => 'update',
+            10 => 'update mod',
+            11 => 'upload',
+            12 => 'submit',
+            13 => 'submit for grading',
+            14 => 'talk',
+            15 => 'choose',
+            16 => 'choose again',
+            17 => 'record delete',
+            18 => 'add discussion',
+            19 => 'add post',
+            20 => 'delete discussion',
+            21 => 'delete post',
+            22 => 'move discussion',
+            23 => 'prune post',
+            24 => 'update post',
+            25 => 'add category',
+            26 => 'add entry',
+            27 => 'approve entry',
+            28 => 'delete category',
+            29 => 'delete entry',
+            30 => 'edit category',
+            31 => 'update entry',
+            32 => 'end',
+            33 => 'start',
+            34 => 'attempt',
+            35 => 'close attempt',
+            36 => 'preview',
+            37 => 'editquestions',
+            38 => 'delete attempt',
+            39 => 'manualgrade',
+        );
+
+         $baseviewactions = array (
+            0 => 'view',
+            1 => 'view all',
+            2 => 'history',
+            3 => 'view submission',
+            4 => 'view feedback',
+            5 => 'print',
+            6 => 'report',
+            7 => 'view discussion',
+            8 => 'search',
+            9 => 'forum',
+            10 => 'forums',
+            11 => 'subscribers',
+            12 => 'view forum',
+            13 => 'view entry',
+            14 => 'review',
+            15 => 'pre-view',
+            16 => 'download',
+            17 => 'view form',
+            18 => 'view graph',
+            19 => 'view report',
+        );
+
+        $postactions = stats_get_action_names('post');
+
+        foreach ($basepostactions as $action) {
+            $this->assertContains($action, $postactions);
+        }
+
+        $viewactions = stats_get_action_names('view');
+
+        foreach ($baseviewactions as $action) {
+            $this->assertContains($action, $viewactions);
+        }
+    }
+
+    /**
+     * Test the temporary table creation and deletion.
+     */
+    public function test_statslib_temp_table_create_and_drop() {
+        global $DB;
+
+        foreach ($this->tables as $table) {
+            $this->assertFalse($DB->get_manager()->table_exists($table));
+        }
+
+        stats_temp_table_create();
+
+        foreach ($this->tables as $table) {
+            $this->assertTrue($DB->get_manager()->table_exists($table));
+        }
+
+        stats_temp_table_drop();
+
+        foreach ($this->tables as $table) {
+            $this->assertFalse($DB->get_manager()->table_exists($table));
+        }
+    }
+
+    /**
+     * Test the temporary table creation and deletion.
+     *
+     * @depends test_statslib_temp_table_create_and_drop
+     */
+    public function test_statslib_temp_table_fill() {
+        global $DB;
+
+        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test09.xml");
+
+        $this->prepare_db($dataset[0], array('log'));
+
+        stats_temp_table_create();
+        stats_temp_table_fill(1272686410, 1272758400);
+
+        $this->assertEquals(1, $DB->count_records('temp_log1'));
+        $this->assertEquals(1, $DB->count_records('temp_log2'));
+
+        stats_temp_table_drop();
+    }
+
+    /**
+     * Test the temporary table creation and deletion.
+     *
+     * @depends test_statslib_temp_table_create_and_drop
+     */
+    public function test_statslib_temp_table_setup() {
+        global $DB;
+
+        $logs = array();
+        $this->prepare_db($logs, array('log'));
+
+        stats_temp_table_create();
+        stats_temp_table_setup();
+
+        $this->assertEquals(1, $DB->count_records('temp_enroled'));
+
+        stats_temp_table_drop();
+    }
+
+    /**
+     * Test the function that clean out the temporary tables.
+     *
+     * @depends test_statslib_temp_table_create_and_drop
+     */
+    public function test_statslib_temp_table_clean() {
+        global $DB;
+
+        $rows = array(
+            'temp_log1'             => array('id' => 1, 'course' => 1),
+            'temp_log2'             => array('id' => 1, 'course' => 1),
+            'temp_stats_daily'      => array('id' => 1, 'courseid' => 1),
+            'temp_stats_user_daily' => array('id' => 1, 'courseid' => 1),
+        );
+
+        stats_temp_table_create();
+
+        foreach ($rows as $table => $row) {
+            $DB->insert_record_raw($table, $row);
+            $this->assertEquals(1, $DB->count_records($table));
+        }
+
+        stats_temp_table_clean();
+
+        foreach ($rows as $table => $row) {
+            $this->assertEquals(0, $DB->count_records($table));
+        }
+
+        $this->assertEquals(1, $DB->count_records('stats_daily'));
+        $this->assertEquals(1, $DB->count_records('stats_user_daily'));
+
+        stats_temp_table_drop();
+    }
+
+    /**
+     * Test the daily stats function
+     *
+     * @depends test_statslib_get_base_daily
+     * @depends test_statslib_get_next_day_start
+     * @depends test_statslib_temp_table_create_and_drop
+     * @depends test_statslib_temp_table_setup
+     * @depends test_statslib_temp_table_fill
+     * @dataProvider daily_log_provider
+     */
+    public function test_statslib_cron_daily($logs, $stats) {
+        global $CFG;
+
+        $CFG->debug = DEBUG_NONE;
+
+        $this->prepare_db($logs, array('log'));
+
+        // Stats cron daily uses mtrace, turn on buffering to silence output.
+        ob_start();
+        stats_cron_daily(1);
+        ob_end_clean();
+
+        $this->verify_stats($stats);
+    }
+
+    /**
+     * Test the daily stats function
+     * @depends test_statslib_get_base_daily
+     * @depends test_statslib_get_next_day_start
+     */
+    public function test_statslib_cron_daily_no_default_profile_id() {
+        global $CFG, $DB;
+        $CFG->defaultfrontpageroleid = 0;
+
+        $course1  = $DB->get_record('course', array('shortname' => 'course1'));
+        $guestid  = $CFG->siteguest;
+        $start    = stats_get_base_daily(1272758400);
+        $end      = stats_get_next_day_start($start);
+        $fpid     = (int) $CFG->defaultfrontpageroleid;
+        $gr       = get_guest_role();
+
+        $dataset = $this->load_xml_data_file(__DIR__."/fixtures/statslib-test10.xml");
+
+        $CFG->debug = DEBUG_NONE;
+
+        $this->prepare_db($dataset[0], array('log'));
+
+        // Stats cron daily uses mtrace, turn on buffering to silence output.
+        ob_start();
+        stats_cron_daily($maxdays=1);
+        ob_end_clean();
+
+        $this->verify_stats($dataset[1]);
+    }
+}