Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
declare(strict_types=1);
18
 
19
namespace core_admin\reportbuilder\datasource;
20
 
21
use core\task\database_logger;
22
use core_reportbuilder_generator;
23
use core_reportbuilder_testcase;
24
use core_reportbuilder\local\filters\{boolean_select, date, duration, number, select, text};
25
use core_reportbuilder\task\send_schedules;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
global $CFG;
30
require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
31
 
32
/**
33
 * Unit tests for task logs datasource
34
 *
35
 * @package     core_admin
36
 * @covers      \core_admin\reportbuilder\datasource\task_logs
37
 * @copyright   2022 Paul Holden <paulh@moodle.com>
38
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class task_logs_test extends core_reportbuilder_testcase {
41
 
42
    /**
43
     * Test default datasource
44
     */
45
    public function test_datasource_default(): void {
46
        $this->resetAfterTest();
47
 
48
        $this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060);
49
        $this->generate_task_log_data(false, 5, 1, 1654556400, 1654556700);
50
 
51
        /** @var core_reportbuilder_generator $generator */
52
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
53
        $report = $generator->create_report(['name' => 'Tasks', 'source' => task_logs::class, 'default' => 1]);
54
 
55
        $content = $this->get_custom_report_content($report->get('id'));
56
        $this->assertCount(2, $content);
57
 
58
        // Default columns are name, start time, duration, result. Sorted by start time descending.
59
        [$name, $timestart, $duration, $result] = array_values($content[0]);
60
        $this->assertStringContainsString(send_schedules::class, $name);
61
        $this->assertEquals('7/06/22, 07:00:00', $timestart);
62
        $this->assertEquals('5 mins', $duration);
63
        $this->assertEquals('Fail', $result);
64
 
65
        [$name, $timestart, $duration, $result] = array_values($content[1]);
66
        $this->assertStringContainsString(send_schedules::class, $name);
67
        $this->assertEquals('1/06/22, 07:00:00', $timestart);
68
        $this->assertEquals('1 min', $duration);
69
        $this->assertEquals('Success', $result);
70
    }
71
 
72
    /**
73
     * Test datasource columns that aren't added by default
74
     */
75
    public function test_datasource_non_default_columns(): void {
76
        $this->resetAfterTest();
77
 
78
        $this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060, 'hi', 'core_reportbuilder', 'test', 43);
79
 
80
        /** @var core_reportbuilder_generator $generator */
81
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
82
        $report = $generator->create_report(['name' => 'Tasks', 'source' => task_logs::class, 'default' => 0]);
83
 
84
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:component']);
85
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:type']);
86
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:endtime']);
87
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:hostname']);
88
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:pid']);
89
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:database']);
90
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:dbreads']);
91
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:dbwrites']);
92
 
93
        $content = $this->get_custom_report_content($report->get('id'));
94
        $this->assertCount(1, $content);
95
 
96
        $this->assertEquals([
97
            'core_reportbuilder',
98
            'Scheduled',
99
            '1/06/22, 07:01:00',
100
            'test',
101
            '43',
102
            '<div>3 reads</div><div>2 writes</div>',
103
            '3',
104
            '2',
105
        ], array_values($content[0]));
106
    }
107
 
108
    /**
109
     * Data provider for {@see test_datasource_filters}
110
     *
111
     * @return array[]
112
     */
113
    public function datasource_filters_provider(): array {
114
        return [
115
            'Filter name' => ['task_log:name', [
116
                'task_log:name_values' => [send_schedules::class],
117
            ], true],
118
            'Filter name (no match)' => ['task_log:name', [
119
                'task_log:name_values' => ['invalid'],
120
            ], false],
121
            'Filter component' => ['task_log:component', [
122
                'task_log:component_operator' => select::EQUAL_TO,
123
                'task_log:component_value' => 'core_reportbuilder',
124
            ], true],
125
            'Filter component (no match)' => ['task_log:component', [
126
                'task_log:component_operator' => select::NOT_EQUAL_TO,
127
                'task_log:component_value' => 'core_reportbuilder',
128
            ], false],
129
            'Filter type' => ['task_log:type', [
130
                'task_log:type_operator' => select::EQUAL_TO,
131
                'task_log:type_value' => database_logger::TYPE_SCHEDULED,
132
            ], true],
133
            'Filter type (no match)' => ['task_log:type', [
134
                'task_log:type_operator' => select::EQUAL_TO,
135
                'task_log:type_value' => database_logger::TYPE_ADHOC,
136
            ], false],
137
            'Filter output' => ['task_log:output', [
138
                'task_log:output_operator' => text::IS_NOT_EMPTY,
139
            ], true],
140
            'Filter output (no match)' => ['task_log:output', [
141
                'task_log:output_operator' => text::IS_EMPTY,
142
            ], false],
143
            'Filter result' => ['task_log:result', [
144
                'task_log:result_operator' => boolean_select::CHECKED,
145
            ], true],
146
            'Filter result (no match)' => ['task_log:result', [
147
                'task_log:result_operator' => boolean_select::NOT_CHECKED,
148
            ], false],
149
            'Filter time start' => ['task_log:timestart', [
150
                'task_log:timestart_operator' => date::DATE_RANGE,
151
                'task_log:timestart_from' => 1622502000,
152
            ], true],
153
            'Filter time start (no match)' => ['task_log:timestart', [
154
                'task_log:timestart_operator' => date::DATE_RANGE,
155
                'task_log:timestart_to' => 1622502000,
156
            ], false],
157
            'Filter time end' => ['task_log:timeend', [
158
                'task_log:timeend_operator' => date::DATE_RANGE,
159
                'task_log:timeend_from' => 1622502000,
160
            ], true],
161
            'Filter time end (no match)' => ['task_log:timeend', [
162
                'task_log:timeend_operator' => date::DATE_RANGE,
163
                'task_log:timeend_to' => 1622502000,
164
            ], false],
165
            'Filter duration' => ['task_log:duration', [
166
                'task_log:duration_operator' => duration::DURATION_MAXIMUM,
167
                'task_log:duration_unit' => MINSECS,
168
                'task_log:duration_value' => 2,
169
            ], true],
170
            'Filter duration (no match)' => ['task_log:duration', [
171
                'task_log:duration_operator' => duration::DURATION_MINIMUM,
172
                'task_log:duration_unit' => MINSECS,
173
                'task_log:duration_value' => 2,
174
            ], false],
175
            'Filter database reads' => ['task_log:dbreads', [
176
                'task_log:dbreads_operator' => number::LESS_THAN,
177
                'task_log:dbreads_value1' => 4,
178
            ], true],
179
            'Filter database reads (no match)' => ['task_log:dbreads', [
180
                'task_log:dbreads_operator' => number::GREATER_THAN,
181
                'task_log:dbreads_value1' => 4,
182
            ], false],
183
            'Filter database writes' => ['task_log:dbwrites', [
184
                'task_log:dbwrites_operator' => number::LESS_THAN,
185
                'task_log:dbwrites_value1' => 4,
186
            ], true],
187
            'Filter database writes (no match)' => ['task_log:dbwrites', [
188
                'task_log:dbwrites_operator' => number::GREATER_THAN,
189
                'task_log:dbwrites_value1' => 4,
190
            ], false],
191
        ];
192
    }
193
 
194
    /**
195
     * Test datasource filters
196
     *
197
     * @param string $filtername
198
     * @param array $filtervalues
199
     * @param bool $expectmatch
200
     *
201
     * @dataProvider datasource_filters_provider
202
     */
203
    public function test_datasource_filters(
204
        string $filtername,
205
        array $filtervalues,
206
        bool $expectmatch
207
    ): void {
208
        $this->resetAfterTest();
209
 
210
        $this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060, 'hi', 'core_reportbuilder', 'test', 43);
211
 
212
        /** @var core_reportbuilder_generator $generator */
213
        $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
214
 
215
        // Create report containing single component column, and given filter.
216
        $report = $generator->create_report(['name' => 'Tasks', 'source' => task_logs::class, 'default' => 0]);
217
        $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'task_log:component']);
218
 
219
        // Add filter, set it's values.
220
        $generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);
221
        $content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues);
222
 
223
        if ($expectmatch) {
224
            $this->assertCount(1, $content);
225
            $this->assertEquals('core_reportbuilder', reset($content[0]));
226
        } else {
227
            $this->assertEmpty($content);
228
        }
229
    }
230
 
231
    /**
232
     * Stress test datasource
233
     *
234
     * In order to execute this test PHPUNIT_LONGTEST should be defined as true in phpunit.xml or directly in config.php
235
     */
236
    public function test_stress_datasource(): void {
237
        if (!PHPUNIT_LONGTEST) {
238
            $this->markTestSkipped('PHPUNIT_LONGTEST is not defined');
239
        }
240
 
241
        $this->resetAfterTest();
242
 
243
        $this->generate_task_log_data(true, 3, 2, 1654038000, 1654038060, 'hi', 'core_reportbuilder', 'test', 43);
244
 
245
        $this->datasource_stress_test_columns(task_logs::class);
246
        $this->datasource_stress_test_columns_aggregation(task_logs::class);
247
        $this->datasource_stress_test_conditions(task_logs::class, 'task_log:name');
248
    }
249
 
250
    /**
251
     * Helper to generate some task logs data
252
     *
253
     * @param bool $success
254
     * @param int $dbreads
255
     * @param int $dbwrites
256
     * @param float $timestart
257
     * @param float $timeend
258
     * @param string $logoutput
259
     * @param string $component
260
     * @param string $hostname
261
     * @param int $pid
262
     */
263
    private function generate_task_log_data(
264
        bool $success,
265
        int $dbreads,
266
        int $dbwrites,
267
        float $timestart,
268
        float $timeend,
269
        string $logoutput = 'hello',
270
        string $component = 'moodle',
271
        string $hostname = 'phpunit',
272
        int $pid = 42
273
    ): void {
274
 
275
        $logpath = make_request_directory() . '/log.txt';
276
        file_put_contents($logpath, $logoutput);
277
 
278
        $task = new send_schedules();
279
        $task->set_component($component);
280
        $task->set_hostname($hostname);
281
        $task->set_pid($pid);
282
 
283
        database_logger::store_log_for_task($task, $logpath, !$success, $dbreads, $dbwrites, $timestart, $timeend);
284
    }
285
}