1# ==== Purpose ==== 2# 3# Check if a condition holds, fail with debug info if not. 4# 5# The condition is parsed before executed. The following constructs 6# are supported: 7# 8# [SQL_STATEMENT, COLUMN, ROW] 9# The square bracket is replaced by the result from SQL_STATEMENT, 10# in the given COLUMN and ROW. 11# 12# Optionally, SQL_STATEMENT may have the form: 13# connection:SQL_STATEMENT 14# In this case, SQL_STATEMENT is executed on the named connection. 15# All other queries executed by this script will be executed on 16# the connection that was in use when this script was started. 17# The current connection will also be restored at the end of this 18# script. 19# 20# Nested sub-statements on this form are not allowed. 21# 22# <1> 23# This is a shorthand for the result of the first executed square 24# bracket. <2> is a shorthand for the second executed square 25# bracket, and so on. 26# 27# ==== Usage ==== 28# 29# --let $assert_text= Relay_Log_Pos must be between min_pos and max_pos 30# --let $assert_cond= [SHOW SLAVE STATUS, Relay_Log_Pos, 1] >= $min_pos AND <1> <= $max_pos 31# [--let $assert_quiet= 1] 32# [--let $rpl_debug= 1] 33# --source include/assert.inc 34# 35# Parameters: 36# 37# $assert_text 38# Text that describes what is being checked. This text is written to 39# the query log so it should not contain non-deterministic elements. 40# 41# $assert_cond 42# Condition to check. See above for details about the format. The 43# condition will be executed as `SELECT $assert_cond`. 44# 45# Both $assert_cond and the result from any substatement on the 46# form [SQL_STATEMENT, COLUMN, ROW] will be used in SQL statements, 47# inside single quotes (as in '$assert_text'). So any single quotes 48# in these texts must be escaped or replaced by double quotes. 49# 50# $rpl_debug 51# Print extra debug info. 52 53 54--let $include_filename= assert.inc [$assert_text] 55--source include/begin_include_file.inc 56 57if ($rpl_debug) 58{ 59 --echo # debug: assert_text='$assert_text' assert_cond='$assert_cond' 60} 61 62# Sanity-check input 63if (!$assert_text) 64{ 65 --die ERROR IN TEST: the mysqltest variable rpl_test must be set 66} 67 68--let $_assert_old_connection= $CURRENT_CONNECTION 69 70# Evaluate square brackets in cond. 71--let $_assert_substmt_number= 1 72--let $_assert_cond_interp= '$assert_cond' 73--let $_assert_lbracket= `SELECT LOCATE('[', $_assert_cond_interp)` 74while ($_assert_lbracket) 75{ 76 # Get position of right bracket 77 --let $_assert_rbracket= `SELECT LOCATE(']', $_assert_cond_interp)` 78 if (!$_assert_rbracket) 79 { 80 --echo BUG IN TEST: Mismatching square brackets in assert_cond. 81 --echo Original assert_cond='$assert_cond' 82 --echo Interpolated assert_cond=$_assert_cond_interp 83 --die BUG IN TEST: Mismatching square brackets in $assert_cond 84 } 85 86 # Get sub-statement from statement. Preserve escapes for single quotes. 87 --let $_assert_full_substmt= `SELECT QUOTE(SUBSTRING($_assert_cond_interp, $_assert_lbracket + 1, $_assert_rbracket - $_assert_lbracket - 1))` 88 89 # Get connection from sub-statement 90 --let $_assert_colon= `SELECT IF($_assert_full_substmt REGEXP '^[a-zA-Z_][a-zA-Z_0-9]*:', LOCATE(':', $_assert_full_substmt), 0)` 91 --let $_assert_connection= 92 --let $_assert_substmt= $_assert_full_substmt 93 if ($_assert_colon) 94 { 95 --let $_assert_connection= `SELECT SUBSTRING($_assert_substmt, 1, $_assert_colon - 1)` 96 # Preserve escapes for single quotes. 97 --let $_assert_substmt= `SELECT QUOTE(SUBSTRING($_assert_substmt, $_assert_colon + 1))` 98 } 99 100 # Interpolate escapes before using condition outside string context. 101 --let $_assert_substmt_interp= `SELECT $_assert_substmt` 102 103 # Execute and get result from sub-statement 104 if ($_assert_connection) 105 { 106 if ($rpl_debug) 107 { 108 --echo # debug: connection='$_assert_connection' sub-statement=$_assert_substmt 109 } 110 --let $rpl_connection_name= $_assert_connection 111 --source include/rpl_connection.inc 112 --let $_assert_substmt_result= query_get_value($_assert_substmt_interp) 113 --let $rpl_connection_name= $_assert_old_connection 114 --source include/rpl_connection.inc 115 } 116 if (!$_assert_connection) 117 { 118 if ($rpl_debug) 119 { 120 --echo # debug: old connection, sub-statement=$_assert_substmt 121 } 122 --let $_assert_substmt_result= query_get_value($_assert_substmt_interp) 123 } 124 if ($rpl_debug) 125 { 126 --echo # debug: result of sub-statement='$_assert_substmt_result' 127 } 128 129 # Replace sub-statement by its result 130 --let $_assert_cond_interp= `SELECT QUOTE(REPLACE($_assert_cond_interp, CONCAT('[', $_assert_full_substmt, ']'), '$_assert_substmt_result'))` 131 # Replace result references by result 132 --let $_assert_cond_interp= `SELECT QUOTE(REPLACE($_assert_cond_interp, '<$_assert_substmt_number>', '$_assert_substmt_result'))` 133 134 --let $_assert_lbracket= `SELECT LOCATE('[', $_assert_cond_interp)` 135 136 --inc $_assert_substmt_number 137} 138 139# Interpolate escapes before using condition outside string context. 140--let $_assert_cond_interp= `SELECT $_assert_cond_interp` 141 142if ($rpl_debug) 143{ 144 --echo # debug: interpolated_cond='$_assert_cond_interp' 145} 146 147# Execute. 148--let $_assert_result= `SELECT $_assert_cond_interp` 149 150if ($rpl_debug) 151{ 152 --echo # debug: result='$_assert_result' 153} 154 155# Check. 156if (!$_assert_result) 157{ 158 --echo ######## Test assertion failed: $assert_text ######## 159 --echo Dumping debug info: 160 if ($rpl_inited) 161 { 162 --source include/show_rpl_debug_info.inc 163 } 164 --echo Assertion text: '$assert_text' 165 --echo Assertion condition: '$assert_cond' 166 --echo Assertion condition, interpolated: '$_assert_cond_interp' 167 --echo Assertion result: '$_assert_result' 168 --die Test assertion failed in assertion.inc 169} 170 171--let $include_filename= assert.inc [$assert_text] 172--source include/end_include_file.inc 173 174--let $assert_text= 175--let $assert_cond= 176