From 9726144ef34972b90ed1851723197bea2bf0d232 Mon Sep 17 00:00:00 2001 From: John Okely Date: Thu, 13 Jul 2017 13:42:07 +0800 Subject: [PATCH] MDL-57698 sqlsrv: Unit test NOLOCK --- .../sqlsrv_native_moodle_database_test.php | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 lib/dml/tests/sqlsrv_native_moodle_database_test.php diff --git a/lib/dml/tests/sqlsrv_native_moodle_database_test.php b/lib/dml/tests/sqlsrv_native_moodle_database_test.php new file mode 100644 index 00000000000..65cd4706e7a --- /dev/null +++ b/lib/dml/tests/sqlsrv_native_moodle_database_test.php @@ -0,0 +1,168 @@ +. + +/** + * Test sqlsrv dml support. + * + * @package core + * @category dml + * @copyright 2017 John Okely + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +global $CFG; +require_once($CFG->dirroot.'/lib/dml/sqlsrv_native_moodle_database.php'); + +/** + * Test case for sqlsrv dml support. + * + * @package core + * @category dml + * @copyright 2017 John Okely + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class sqlsrv_native_moodle_database_testcase extends advanced_testcase { + + public function setUp() { + parent::setUp(); + $this->resetAfterTest(); + } + + /** + * Dataprovider for test_add_no_lock_to_temp_tables + * @return array Data for test_add_no_lock_to_temp_tables + */ + public function add_no_lock_to_temp_tables_provider() { + return [ + "Basic temp table, nothing following" => [ + 'input' => 'SELECT * FROM {table_temp}', + 'expected' => 'SELECT * FROM {table_temp} WITH (NOLOCK)' + ], + "Basic temp table, with capitalised alias" => [ + 'input' => 'SELECT * FROM {table_temp} MYTABLE', + 'expected' => 'SELECT * FROM {table_temp} MYTABLE WITH (NOLOCK)' + ], + "Temp table with alias, and another non-temp table" => [ + 'input' => 'SELECT * FROM {table_temp} x WHERE y in (SELECT y from {table2})', + 'expected' => 'SELECT * FROM {table_temp} x WITH (NOLOCK) WHERE y in (SELECT y from {table2})' + ], + "Temp table with reserve word following, no alias" => [ + 'input' => 'SELECT DISTINCT * FROM {table_temp} WHERE y in (SELECT y from {table2} nottemp)', + 'expected' => 'SELECT DISTINCT * FROM {table_temp} WITH (NOLOCK) WHERE y in (SELECT y from {table2} nottemp)' + ], + "Temp table with reserve word, lower case" => [ + 'input' => 'SELECT DISTINCT * FROM {table_temp} where y in (SELECT y from {table2} nottemp)', + 'expected' => 'SELECT DISTINCT * FROM {table_temp} WITH (NOLOCK) where y in (SELECT y from {table2} nottemp)' + ], + "Another reserve word test" => [ + 'input' => 'SELECT DISTINCT * FROM {table_temp} PIVOT y in (SELECT y from {table2} nottemp)', + 'expected' => 'SELECT DISTINCT * FROM {table_temp} WITH (NOLOCK) PIVOT y in (SELECT y from {table2} nottemp)' + ], + "Another reserve word test should fail" => [ + 'input' => 'SELECT DISTINCT * FROM {table_temp} PIVOT y in (SELECT y from {table2} nottemp)', + 'expected' => 'SELECT DISTINCT * FROM {table_temp} WITH (NOLOCK) PIVOT y in (SELECT y from {table2} nottemp)' + ], + "Temp table with an alias starting with a keyword" => [ + 'input' => 'SELECT * FROM {table_temp} asx', + 'expected' => 'SELECT * FROM {table_temp} asx WITH (NOLOCK)' + ], + "Keep alias with underscore" => [ + 'input' => 'SELECT * FROM {table_temp} alias_for_table', + 'expected' => 'SELECT * FROM {table_temp} alias_for_table WITH (NOLOCK)' + ], + "Alias with number" => [ + 'input' => 'SELECT * FROM {table_temp} a5 WHERE y', + 'expected' => 'SELECT * FROM {table_temp} a5 WITH (NOLOCK) WHERE y' + ], + "Alias with number and underscore" => [ + 'input' => 'SELECT * FROM {table_temp} a_5 WHERE y', + 'expected' => 'SELECT * FROM {table_temp} a_5 WITH (NOLOCK) WHERE y' + ], + "Temp table in subquery" => [ + 'input' => 'select * FROM (SELECT DISTINCT * FROM {table_temp})', + 'expected' => 'select * FROM (SELECT DISTINCT * FROM {table_temp} WITH (NOLOCK))' + ], + "Temp table in subquery, with following commands" => [ + 'input' => 'select * FROM (SELECT DISTINCT * FROM {table_temp} ) WHERE y', + 'expected' => 'select * FROM (SELECT DISTINCT * FROM {table_temp} WITH (NOLOCK) ) WHERE y' + ], + "Temp table in subquery, with alias" => [ + 'input' => 'select * FROM (SELECT DISTINCT * FROM {table_temp} x) WHERE y', + 'expected' => 'select * FROM (SELECT DISTINCT * FROM {table_temp} x WITH (NOLOCK)) WHERE y' + ], + ]; + } + + /** + * Test add_no_lock_to_temp_tables + * + * @param string $input The input SQL query + * @param string $expected The expected resultant query + * @dataProvider add_no_lock_to_temp_tables_provider + */ + public function test_add_no_lock_to_temp_tables($input, $expected) { + $sqlsrv = new sqlsrv_native_moodle_database(); + + $reflector = new ReflectionObject($sqlsrv); + + $method = $reflector->getMethod('add_no_lock_to_temp_tables'); + $method->setAccessible(true); + + $temptablesproperty = $reflector->getProperty('temptables'); + $temptablesproperty->setAccessible(true); + $temptables = new temptables_tester(); + + $temptablesproperty->setValue($sqlsrv, $temptables); + + $result = $method->invoke($sqlsrv, $input); + + $temptablesproperty->setValue($sqlsrv, null); + $this->assertEquals($expected, $result); + } +} + +/** + * Test class for testing temptables + * + * @copyright 2017 John Okely + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class temptables_tester { + /** + * Returns if one table, based in the information present in the store, is a temp table + * + * For easy testing, anything with the word 'temp' in it is considered temporary. + * + * @param string $tablename name without prefix of the table we are asking about + * @return bool true if the table is a temp table (based in the store info), false if not + */ + public function is_temptable($tablename) { + if (strpos($tablename, 'temp') === false) { + return false; + } else { + return true; + } + } + /** + * Dispose the temptables + * + * @return void + */ + public function dispose() { + } +}