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
namespace core;
18
 
19
use ReflectionClass;
20
use mysqli;
21
use moodle_database, mysqli_native_moodle_database;
22
use moodle_exception;
23
 
24
/**
25
 * Test specific features of the MySql dml.
26
 *
27
 * @package core
28
 * @category test
29
 * @copyright 2023 Catalyst IT
30
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31
 * @covers  \mysqli_native_moodle_database
32
 */
33
class mysqli_native_moodle_database_test extends \advanced_testcase {
34
 
35
    /**
36
     * Set up.
37
     */
38
    public function setUp(): void {
39
        global $DB;
40
        parent::setUp();
41
        // Skip tests if not using Postgres.
42
        if (!($DB instanceof mysqli_native_moodle_database)) {
43
            $this->markTestSkipped('MySql-only test');
44
        }
45
    }
46
 
47
    /**
48
     * SSL connection helper.
49
     *
50
     * @param bool|null $compress
51
     * @param string|null $ssl
52
     * @return mysqli
53
     * @throws moodle_exception
54
     */
55
    public function new_connection(?bool $compress = false, ?string $ssl = null): mysqli {
56
        global $DB;
57
 
58
        // Open new connection.
59
        $cfg = $DB->export_dbconfig();
60
        if (!isset($cfg->dboptions)) {
61
            $cfg->dboptions = [];
62
        }
63
 
64
        $cfg->dboptions['clientcompress'] = $compress;
65
        $cfg->dboptions['ssl'] = $ssl;
66
 
67
        // Get a separate disposable db connection handle with guaranteed 'readonly' config.
68
        $db2 = moodle_database::get_driver_instance($cfg->dbtype, $cfg->dblibrary);
69
        $db2->raw_connect($cfg->dbhost, $cfg->dbuser, $cfg->dbpass, $cfg->dbname, $cfg->prefix, $cfg->dboptions);
70
 
71
        $reflector = new ReflectionClass($db2);
72
        $rp = $reflector->getProperty('mysqli');
73
        return $rp->getValue($db2);
74
    }
75
 
76
    /**
77
     * Test client compression helper.
78
     *
79
     * @param mysqli $mysqli
80
     * @return array
81
     */
82
    public function connection_status($mysqli): array {
83
        $mysqli->query("SELECT * FROM INFORMATION_SCHEMA.TABLES");
84
 
85
        $stats = [];
86
        foreach ($mysqli->query('SHOW SESSION STATUS')->fetch_all(MYSQLI_ASSOC) as $r) {
87
            $stats[$r['Variable_name']] = $r['Value'];
88
        }
89
        return $stats;
90
    }
91
 
92
    /**
93
     * Test client compression.
94
     *
95
     * @return void
96
     */
97
    public function test_client_compression(): void {
98
        $mysqli = $this->new_connection();
99
        $stats = $this->connection_status($mysqli);
100
        $this->assertEquals('OFF', $stats['Compression']);
101
        $sent = $stats['Bytes_sent'];
102
 
103
        $mysqlic = $this->new_connection(true);
104
        $stats = $this->connection_status($mysqlic);
105
        $this->assertEquals('ON', $stats['Compression']);
106
        $sentc = $stats['Bytes_sent'];
107
 
108
        $this->assertLessThan($sent, $sentc);
109
    }
110
 
111
    /**
112
     * Test SSL connection.
113
     *
114
     * Well as much as we can, mysqli does not reliably report connect errors.
115
     * @return void
116
     */
117
    public function test_ssl_connection(): void {
118
        try {
119
            $mysqli = $this->new_connection(false, 'require');
120
            // Either connect ...
121
            $this->assertNotNull($mysqli);
122
        } catch (moodle_exception $e) {
123
            // ... or fail.
124
            // Unfortunately we cannot be sure with the error string.
125
            $this->markTestSkipped('MySQL server does not support SSL. Unable to complete the test.');
126
            return;
127
        }
128
 
129
        try {
130
            $mysqli = $this->new_connection(false, 'verify-full');
131
            // Either connect ...
132
            $this->assertNotNull($mysqli);
133
        } catch (moodle_exception $e) {
134
            // ... or fail with invalid cert.
135
            // Same as above, but we cannot really expect properly signed cert, so ignore.
136
        }
137
 
138
        $this->expectException(moodle_exception::class);
139
        $this->new_connection(false, 'invalid-mode');
140
    }
141
}