Merge pull request #3615 from gilles-peskine-arm/ssl-opt-less-grep-development
Speed up ssl-opt.sh when running a small number of test cases
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 6c54900..3de2361 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -114,8 +114,8 @@
echo "Usage: $0 [options]"
printf " -h|--help\tPrint this help.\n"
printf " -m|--memcheck\tCheck memory leaks and errors.\n"
- printf " -f|--filter\tOnly matching tests are executed (BRE)\n"
- printf " -e|--exclude\tMatching tests are excluded (BRE)\n"
+ printf " -f|--filter\tOnly matching tests are executed (substring or BRE)\n"
+ printf " -e|--exclude\tMatching tests are excluded (substring or BRE)\n"
printf " -n|--number\tExecute only numbered test (comma-separated, e.g. '245,256')\n"
printf " -s|--show-numbers\tShow test numbers in front of test names\n"
printf " -p|--preserve-logs\tPreserve logs of successful tests as well\n"
@@ -178,6 +178,14 @@
;;
esac
+# Read boolean configuration options from config.h for easy and quick
+# testing. Skip non-boolean options (with something other than spaces
+# and a comment after "#define SYMBOL"). The variable contains a
+# space-separated list of symbols.
+CONFIGS_ENABLED=" $(<"$CONFIG_H" \
+ sed -n 's!^ *#define *\([A-Za-z][0-9A-Z_a-z]*\) *\(/*\)*!\1!p' |
+ tr '\n' ' ')"
+
# Skip next test; use this macro to skip tests which are legitimate
# in theory and expected to be re-introduced at some point, but
# aren't expected to succeed at the moment due to problems outside
@@ -188,16 +196,17 @@
# skip next test if the flag is not enabled in config.h
requires_config_enabled() {
- if grep "^#define $1" $CONFIG_H > /dev/null; then :; else
- SKIP_NEXT="YES"
- fi
+ case $CONFIGS_ENABLED in
+ *" $1 "*) :;;
+ *) SKIP_NEXT="YES";;
+ esac
}
# skip next test if the flag is enabled in config.h
requires_config_disabled() {
- if grep "^#define $1" $CONFIG_H > /dev/null; then
- SKIP_NEXT="YES"
- fi
+ case $CONFIGS_ENABLED in
+ *" $1 "*) SKIP_NEXT="YES";;
+ esac
}
get_config_value_or_default() {
@@ -233,10 +242,16 @@
fi
}
+# Space-separated list of ciphersuites supported by this build of
+# Mbed TLS.
+P_CIPHERSUITES=" $($P_CLI --help 2>/dev/null |
+ grep TLS- |
+ tr -s ' \n' ' ')"
requires_ciphersuite_enabled() {
- if [ -z "$($P_CLI --help 2>/dev/null | grep $1)" ]; then
- SKIP_NEXT="YES"
- fi
+ case $P_CIPHERSUITES in
+ *" $1 "*) :;;
+ *) SKIP_NEXT="YES";;
+ esac
}
# maybe_requires_ciphersuite_enabled CMD [RUN_TEST_OPTION...]
@@ -462,17 +477,21 @@
# is_polar <cmd_line>
is_polar() {
- echo "$1" | grep 'ssl_server2\|ssl_client2' > /dev/null
+ case "$1" in
+ *ssl_client2*) true;;
+ *ssl_server2*) true;;
+ *) false;;
+ esac
}
# openssl s_server doesn't have -www with DTLS
check_osrv_dtls() {
- if echo "$SRV_CMD" | grep 's_server.*-dtls' >/dev/null; then
- NEEDS_INPUT=1
- SRV_CMD="$( echo $SRV_CMD | sed s/-www// )"
- else
- NEEDS_INPUT=0
- fi
+ case "$SRV_CMD" in
+ *s_server*-dtls*)
+ NEEDS_INPUT=1
+ SRV_CMD="$( echo $SRV_CMD | sed s/-www// )";;
+ *) NEEDS_INPUT=0;;
+ esac
}
# provide input to commands that need it
@@ -627,11 +646,10 @@
# check if the given command uses dtls and sets global variable DTLS
detect_dtls() {
- if echo "$1" | grep 'dtls=1\|-dtls1\|-u' >/dev/null; then
- DTLS=1
- else
- DTLS=0
- fi
+ case "$1" in
+ *dtls=1*|-dtls|-u) DTLS=1;;
+ *) DTLS=0;;
+ esac
}
# check if the given command uses gnutls and sets global variable CMD_IS_GNUTLS
@@ -680,8 +698,7 @@
NAME="$1"
shift 1
- if echo "$NAME" | grep "$FILTER" | grep -v "$EXCLUDE" >/dev/null; then :
- else
+ if is_excluded "$NAME"; then
SKIP_NEXT="NO"
# There was no request to run the test, so don't record its outcome.
return
@@ -690,10 +707,11 @@
print_name "$NAME"
# Do we only run numbered tests?
- if [ "X$RUN_TEST_NUMBER" = "X" ]; then :
- elif echo ",$RUN_TEST_NUMBER," | grep ",$TESTS," >/dev/null; then :
- else
- SKIP_NEXT="YES"
+ if [ -n "$RUN_TEST_NUMBER" ]; then
+ case ",$RUN_TEST_NUMBER," in
+ *",$TESTS,"*) :;;
+ *) SKIP_NEXT="YES";;
+ esac
fi
# does this test use a proxy?
@@ -711,10 +729,10 @@
shift 3
# Check if test uses files
- TEST_USES_FILES=$(echo "$SRV_CMD $CLI_CMD" | grep "\.\(key\|crt\|pem\)" )
- if [ ! -z "$TEST_USES_FILES" ]; then
- requires_config_enabled MBEDTLS_FS_IO
- fi
+ case "$SRV_CMD $CLI_CMD" in
+ *data_files/*)
+ requires_config_enabled MBEDTLS_FS_IO;;
+ esac
# If the client or serve requires a ciphersuite, check that it's enabled.
maybe_requires_ciphersuite_enabled "$SRV_CMD" "$@"
@@ -1017,7 +1035,7 @@
run_test_memory_after_hanshake_with_mfl()
{
# The test passes if the difference is around 2*(16k-MFL)
- local MEMORY_USAGE_LIMIT="$(( $2 - ( 2 * ( 16384 - $1 )) ))"
+ MEMORY_USAGE_LIMIT="$(( $2 - ( 2 * ( 16384 - $1 )) ))"
# Leave some margin for robustness
MEMORY_USAGE_LIMIT="$(( ( MEMORY_USAGE_LIMIT * 110 ) / 100 ))"
@@ -1079,6 +1097,46 @@
get_options "$@"
+# Optimize filters: if $FILTER and $EXCLUDE can be expressed as shell
+# patterns rather than regular expressions, use a case statement instead
+# of calling grep. To keep the optimizer simple, it is incomplete and only
+# detects simple cases: plain substring, everything, nothing.
+#
+# As an exception, the character '.' is treated as an ordinary character
+# if it is the only special character in the string. This is because it's
+# rare to need "any one character", but needing a literal '.' is common
+# (e.g. '-f "DTLS 1.2"').
+need_grep=
+case "$FILTER" in
+ '^$') simple_filter=;;
+ '.*') simple_filter='*';;
+ *[][$+*?\\^{\|}]*) # Regexp special characters (other than .), we need grep
+ need_grep=1;;
+ *) # No regexp or shell-pattern special character
+ simple_filter="*$FILTER*";;
+esac
+case "$EXCLUDE" in
+ '^$') simple_exclude=;;
+ '.*') simple_exclude='*';;
+ *[][$+*?\\^{\|}]*) # Regexp special characters (other than .), we need grep
+ need_grep=1;;
+ *) # No regexp or shell-pattern special character
+ simple_exclude="*$EXCLUDE*";;
+esac
+if [ -n "$need_grep" ]; then
+ is_excluded () {
+ ! echo "$1" | grep "$FILTER" | grep -q -v "$EXCLUDE"
+ }
+else
+ is_excluded () {
+ case "$1" in
+ $simple_exclude) true;;
+ $simple_filter) false;;
+ *) true;;
+ esac
+ }
+fi
+
# sanity checks, avoid an avalanche of errors
P_SRV_BIN="${P_SRV%%[ ]*}"
P_CLI_BIN="${P_CLI%%[ ]*}"