diff mbox series

[blktests,v4,05/17] common/rc: introduce _set_combined_conditions

Message ID 20240504081448.1107562-6-shinichiro.kawasaki@wdc.com (mailing list archive)
State New, archived
Headers show
Series support test case repeat by different conditions | expand

Commit Message

Shinichiro Kawasaki May 4, 2024, 8:14 a.m. UTC
When the test case has the "set_conditions" hook, blktests repeats the
test case multiple times. This allows repeating the test changing one
condition parameter. However, it is often desired to run the test for
multiple condition parameters. For example, some test cases in the nvme
test group are required to run for different "transport types" as well
as different "backend block device types". In this case, it is required
to iterate over all combinations of the two condition parameters
"transport types" and "backend block device types".

To cover such iteration for the multiple condition parameters, introduce
the helper function _set_combined_conditions. It takes multiple
_set_conditions hooks as its arguments, combines them and works as the
set_conditions() hook. When the hook x iterates x1 and x2, and the other
hook y iterates y1 and y2, the function iterates (x1, y1), (x2, y1),
(x1, y2) and (x2, y2). In other words, it iterates over the Cartesian
product of the given condition sets.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
---
 common/rc | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

Comments

Daniel Wagner May 6, 2024, 2:48 p.m. UTC | #1
On Sat, May 04, 2024 at 05:14:36PM GMT, Shin'ichiro Kawasaki wrote:
> When the test case has the "set_conditions" hook, blktests repeats the
> test case multiple times. This allows repeating the test changing one
> condition parameter. However, it is often desired to run the test for
> multiple condition parameters. For example, some test cases in the nvme
> test group are required to run for different "transport types" as well
> as different "backend block device types". In this case, it is required
> to iterate over all combinations of the two condition parameters
> "transport types" and "backend block device types".
> 
> To cover such iteration for the multiple condition parameters, introduce
> the helper function _set_combined_conditions. It takes multiple
> _set_conditions hooks as its arguments, combines them and works as the
> set_conditions() hook. When the hook x iterates x1 and x2, and the other
> hook y iterates y1 and y2, the function iterates (x1, y1), (x2, y1),
> (x1, y2) and (x2, y2). In other words, it iterates over the Cartesian
> product of the given condition sets.
> 
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>

I learned a bit on bash variable expansion today :)

Looks good.

Reviewed-by: Daniel Wagner <dwagner@suse.de>
diff mbox series

Patch

diff --git a/common/rc b/common/rc
index c3680f5..fa61cc6 100644
--- a/common/rc
+++ b/common/rc
@@ -470,3 +470,48 @@  convert_to_mb()
 		echo "$((res * 1024))"
 	fi
 }
+
+# Combine multiple _set_conditions() hooks to iterate all combinations of them.
+# When one hook x has conditions x1 and x2, and the other hook y has y1 and y2,
+# iterate (x1, y1), (x2, y1), (x1, y2) and (x2, y2). In other words, it iterates
+# the Cartesian product of the given condiition sets.
+_set_combined_conditions()
+{
+	local -i index
+	local -a hooks
+	local -a nr_conds
+	local total_nr_conds=1
+	local i nr_cond _cond_desc
+	local -a last_arg
+
+	last_arg=("${@: -1}")
+	if [[ ${last_arg[*]} =~ ^[0-9]+$ ]]; then
+		index=$((${last_arg[*]}))
+	fi
+	read -r -a hooks <<< "${@/$index}"
+
+	nr_hooks=${#hooks[@]}
+
+	# Check how many conditions each hook has. Multiply them all to get
+	# the total number of the combined conditions.
+	for ((i = 0; i < nr_hooks; i++)); do
+		nr_cond=$(eval "${hooks[i]}")
+		nr_conds+=("$nr_cond")
+		total_nr_conds=$((total_nr_conds * nr_cond))
+	done
+
+	if [[ -z $index ]]; then
+		echo $((total_nr_conds))
+		return
+	fi
+
+	# Calculate the index of the each hook and call them. Concatenate the
+	# COND_DESC of the all hooks return.
+	for ((i = 0; i < nr_hooks; i++)); do
+		eval "${hooks[i]}" $((index % nr_conds[i]))
+		index=$((index / nr_conds[i]))
+		[[ -n $_cond_desc ]] && _cond_desc="${_cond_desc} "
+		_cond_desc="${_cond_desc}${COND_DESC}"
+	done
+	COND_DESC="$_cond_desc"
+}