Skip to content

Commit 315fcfd

Browse files
author
Sven Sandberg
committed
BUG#37037967: Race conditions in tests for replication_applier_metrics component
* Problem Generally, tests for the replication_applier_metrics component introduced in WL#15620 were assuming that, just because one metric had been updated, metrics that account for the same event were updated too. For example, just because the number of committed transactions has been incremented, it assumed that also the size of committed transactions has been incremented too. That is generally not true; each metric is updated by a single atomic counter increment; two such increments are not atomic together. * Fix Introduce new test utility assert_eventually.inc. Use this whenever needed. Change-Id: I71cad35496d15898c1ab87487836c1c31b8f2f8d
1 parent ab9b884 commit 315fcfd

File tree

2 files changed

+134
-11
lines changed

2 files changed

+134
-11
lines changed

mysql-test/include/assert.inc

+18-11
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
# See include/rpl/debug/show_debug_info.inc
5151

5252

53-
--let $include_filename= assert.inc [$assert_text]
53+
--let $include_filename = assert.inc [$assert_text]
5454
--source include/begin_include_file.inc
5555

5656
if ($rpl_debug)
@@ -64,10 +64,11 @@ if (!$assert_text)
6464
--die ERROR IN TEST: the mysqltest variable assert_text must be set
6565
}
6666

67-
--let $_assert_old_eval_expr= $eval_expr
68-
--let $_assert_old_eval_result= $eval_result
69-
--let $_assert_old_eval_no_result= $eval_no_result
70-
--let $eval_expr= $assert_cond
67+
--let $_assert_old_eval_expr = $eval_expr
68+
--let $_assert_old_eval_result = $eval_result
69+
--let $_assert_old_eval_no_result = $eval_no_result
70+
--let $_assert_old_rpl_debug = $rpl_debug
71+
--let $eval_expr = $assert_cond
7172
--let $eval_escape = $assert_escape
7273
--source include/eval.inc
7374

@@ -81,6 +82,11 @@ if (!$eval_result)
8182
if ($show_rpl_debug_info)
8283
{
8384
--source include/rpl/debug/show_debug_info.inc
85+
# Print results of sub-statements.
86+
--echo # Re-executing the condition to print intermediate results.
87+
--let $rpl_debug = 1
88+
--source include/eval.inc
89+
--echo # End re-executing the condition to print intermediate results.
8490
}
8591
if ($assert_no_stop) {
8692
if (!$show_rpl_debug_info) {
@@ -97,11 +103,12 @@ if (!$eval_result)
97103
}
98104
}
99105

100-
--let $include_filename= assert.inc [$assert_text]
106+
--let $include_filename = assert.inc [$assert_text]
101107
--source include/end_include_file.inc
102108

103-
--let $assert_text=
104-
--let $assert_cond=
105-
--let $eval_expr= $_assert_old_eval_expr
106-
--let $eval_result= $_assert_old_eval_result
107-
--let $eval_no_result= $_assert_old_eval_no_result
109+
--let $assert_text =
110+
--let $assert_cond =
111+
--let $rpl_debug = $_assert_old_rpl_debug
112+
--let $eval_expr = $_assert_old_eval_expr
113+
--let $eval_result = $_assert_old_eval_result
114+
--let $eval_no_result = $_assert_old_eval_no_result
+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# ==== Purpose ====
2+
#
3+
# Wait until a condition holds, fail with debug info if it does not become
4+
# true within defined timeout period (defaulting to 5 minutes).
5+
#
6+
# The condition has the same form as expressions evaluated by include/eval.inc
7+
#
8+
# This is similar to wait_condition.inc, with the following differences:
9+
#
10+
# - This file is meant to be used to verify a test requirement, whereas
11+
# wait_contion.inc is meant to be used to prepare a test scenario.
12+
# So, both scripts wait for the server to reach a given state;
13+
# wait_condition.inc should be used when that state is just needed to avoid
14+
# a race condition in the test; assert_eventually.inc should be used when
15+
# it is the purpose of the test to verify that the state is reached.
16+
#
17+
# - This file prints to the result file; wait_condition.inc does not.
18+
#
19+
# - This file uses eval.inc to evaluate compound expressions; wait_condition.inc
20+
# does not.
21+
#
22+
# ==== Usage ====
23+
#
24+
# --let $assert_text = Relay_Log_Pos must be between min_pos and max_pos
25+
# --let $assert_cond = [SHOW REPLICA STATUS, Relay_Log_Pos, 1] >= $min_pos AND <1> <= $max_pos
26+
# [--let $assert_timeout = N]
27+
# [--let $extra_debug_info = some text]
28+
# [--let $extra_debug_eval = expression parsable by include/eval.inc]
29+
# [--let $rpl_debug = 1]
30+
# --source include/assert_eventually.inc
31+
#
32+
# Parameters:
33+
#
34+
# $assert_text, $assert_cond, $rpl_debug, $assert_no_stop,
35+
# $extra_debug_info, $extra_debug_eval
36+
# See assert.inc.
37+
# Note: contrary to assert.inc, this script does not have an $assert_escape
38+
# parameter. This script always escapes properly.
39+
#
40+
# $assert_timeout
41+
# If the condition does not hold within this number of seconds, fail the test.
42+
# If this variable is not set, the timeout defaults to 5 minutes.
43+
44+
45+
--let $include_filename = assert_eventually.inc [$assert_text]
46+
--source include/begin_include_file.inc
47+
48+
if ($rpl_debug)
49+
{
50+
--echo # debug: assert_text='$assert_text' assert_cond='$assert_cond'
51+
}
52+
53+
# Sanity-check input
54+
if (!$assert_text)
55+
{
56+
--die ERROR IN TEST: the mysqltest variable assert_text must be set
57+
}
58+
59+
--let $_assert_eventually_timeout_tenths = 3000
60+
if ($assert_timeout != '') {
61+
--let $ten = 10
62+
--expr $_assert_eventually_timeout_tenths = $assert_timeout * $ten
63+
}
64+
--let $_assert_eventually_waited_tenths = 0
65+
--let $_assert_eventually_sleep_tenths = 1
66+
--let $_assert_eventually_sleep_seconds = 0.1
67+
68+
--let $_assert_eventually_old_eval_result = $eval_result
69+
70+
--let $_assert_eventually_old_eval_expr = $eval_expr
71+
--let $_assert_eventually_old_eval_no_result = $eval_no_result
72+
--let $_assert_eventually_old_eval_escape = $eval_escape
73+
74+
--let $eval_expr = $assert_cond
75+
--let $eval_escape = 1
76+
--let $eval_result = 0
77+
78+
--let $done = 0
79+
while (!$done)
80+
{
81+
# Check.
82+
--source include/eval.inc
83+
84+
if ($eval_result) {
85+
--let $done = 1
86+
}
87+
--expr $_assert_eventually_waited_tenths = $_assert_eventually_waited_tenths + $_assert_eventually_sleep_tenths
88+
# After 10 seconds, just check once per second instead of 10 times per second.
89+
if ($_assert_eventually_waited_tenths == 100) {
90+
--let $_assert_eventually_sleep_tenths = 10
91+
--let $_assert_eventually_sleep_seconds = 1
92+
}
93+
if ($_assert_eventually_waited_tenths >= $_assert_eventually_timeout_tenths) {
94+
--let $done = 1
95+
}
96+
if (!$done) {
97+
--sleep $_assert_eventually_sleep_seconds
98+
}
99+
}
100+
101+
--let $eval_escape = $_assert_eventually_old_eval_escape
102+
--let $eval_expr = $_assert_eventually_old_eval_expr
103+
--let $eval_no_result = $_assert_eventually_old_eval_no_result
104+
105+
if (!$eval_result) {
106+
# We reached here after the timeout, without eval.inc returning success.
107+
# Do a normal assertion which will (likely) fail and print debug info.
108+
--source include/assert.inc
109+
}
110+
111+
--let $include_filename = assert_eventually.inc [$assert_text]
112+
--source include/end_include_file.inc
113+
114+
--let $eval_result = $_assert_eventually_old_eval_result
115+
--let $assert_text =
116+
--let $assert_cond =

0 commit comments

Comments
 (0)