Proyectos de Subversion Moodle

Rev

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