iotests: Make _filter_img_create more active

Right now, _filter_img_create just filters out everything that looks
format-dependent, and applies some filename filters.  That means that we
have to add another filter line every time some format gets a new
creation option.  This can be avoided by instead discarding everything
and just keeping what we know is format-independent (format, size,
backing file, encryption information[1], preallocation) or just
interesting to have in the reference output (external data file path).

Furthermore, we probably want to sort these options.  Format drivers are
not required to define them in any specific order, so the output is
effectively random (although this has never bothered us until now).  We
need a specific order for our reference outputs, though.  Unfortunately,
just using a plain "sort" would change a lot of existing reference
outputs, so we have to pre-filter the option keys to keep our existing
order (fmt, size, backing*, data, encryption info, preallocation).

Finally, this makes it difficult for _filter_img_create to automagically
work for QMP output.  Thus, this patch adds a separate
_filter_img_create_for_qmp function that echos every line verbatim that
does not start with "Formatting", and pipes those "Formatting" lines to
_filter_img_create.

[1] Actually, the only thing that is really important is whether
    encryption is enabled or not.  A patch by Maxim thus removes all
    other "encrypt.*" options from the output:
    https://lists.nongnu.org/archive/html/qemu-block/2020-06/msg00339.html
    But that patch needs to come later so we can get away with changing
    as few reference outputs in this patch here as possible.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200625125548.870061-2-mreitz@redhat.com>
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
This commit is contained in:
Max Reitz 2020-06-25 14:55:30 +02:00
parent a5675f3901
commit 57ee95ed4e
4 changed files with 91 additions and 31 deletions

View File

@ -5,7 +5,7 @@ QA output created by 112
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 refcount_bits=-1
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: TEST_DIR/t.IMGFMT: Refcount width must be a power of two and may not exceed 64 bits

View File

@ -68,7 +68,7 @@ test_blockjob()
_send_qemu_cmd $QEMU_HANDLE \
"$1" \
"$2" \
| _filter_img_create | _filter_qmp_empty_return
| _filter_img_create_in_qmp | _filter_qmp_empty_return
# We want this to return an error because the block job is still running
_send_qemu_cmd $QEMU_HANDLE \

View File

@ -167,11 +167,10 @@ done
echo
echo "== Creating ${TEST_IMG}.[abc] ==" | _filter_testdir
(
$QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}"
$QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}"
$QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b"
) | _filter_img_create
$QEMU_IMG create -f qcow2 "${TEST_IMG}.a" -b "${TEST_IMG}" | _filter_img_create
$QEMU_IMG create -f qcow2 "${TEST_IMG}.b" -b "${TEST_IMG}" | _filter_img_create
$QEMU_IMG create -f qcow2 "${TEST_IMG}.c" -b "${TEST_IMG}.b" \
| _filter_img_create
echo
echo "== Two devices sharing the same file in backing chain =="

View File

@ -122,38 +122,99 @@ _filter_actual_image_size()
# replace driver-specific options in the "Formatting..." line
_filter_img_create()
{
data_file_filter=()
if data_file=$(_get_data_file "$TEST_IMG"); then
data_file_filter=(-e "s# data_file=$data_file##")
# Split the line into the pre-options part ($filename_part, which
# precedes ", fmt=") and the options part ($options, which starts
# with "fmt=")
# (And just echo everything before the first "^Formatting")
readarray formatting_line < <($SED -e 's/, fmt=/\n/')
filename_part=''
options=''
lines=${#formatting_line[@]}
for ((i = 0; i < $lines; i++)); do
line=${formatting_line[i]}
unset formatting_line[i]
filename_part="$filename_part$line"
if echo "$line" | grep -q '^Formatting'; then
next_i=$((i + 1))
if [ -n "${formatting_line[next_i]}" ]; then
options="fmt=${formatting_line[@]}"
fi
break
fi
done
# Set grep_data_file to '\|data_file' to keep it; make it empty
# to drop it.
# We want to drop it if it is part of the global $IMGOPTS, and we
# want to keep it otherwise (if the test specifically wants to
# test data files).
grep_data_file=(-e data_file)
if _get_data_file "$TEST_IMG" > /dev/null; then
grep_data_file=()
fi
$SED "${data_file_filter[@]}" \
filename_filters=(
-e "s#$REMOTE_TEST_DIR#TEST_DIR#g" \
-e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
-e "s#$TEST_DIR#TEST_DIR#g" \
-e "s#$SOCK_DIR#SOCK_DIR#g" \
-e "s#$IMGFMT#IMGFMT#g" \
-e 's#nbd:127.0.0.1:[0-9]\\+#TEST_DIR/t.IMGFMT#g' \
-e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g' \
-e "s# encryption=off##g" \
-e "s# cluster_size=[0-9]\\+##g" \
-e "s# table_size=[0-9]\\+##g" \
-e "s# compat=[^ ]*##g" \
-e "s# compat6=\\(on\\|off\\)##g" \
-e "s# static=\\(on\\|off\\)##g" \
-e "s# zeroed_grain=\\(on\\|off\\)##g" \
-e "s# subformat=[^ ]*##g" \
-e "s# adapter_type=[^ ]*##g" \
-e "s# hwversion=[^ ]*##g" \
-e "s# lazy_refcounts=\\(on\\|off\\)##g" \
-e "s# block_size=[0-9]\\+##g" \
-e "s# block_state_zero=\\(on\\|off\\)##g" \
-e "s# log_size=[0-9]\\+##g" \
-e "s# refcount_bits=[0-9]\\+##g" \
-e "s# key-secret=[a-zA-Z0-9]\\+##g" \
-e "s# iter-time=[0-9]\\+##g" \
-e "s# force_size=\\(on\\|off\\)##g" \
-e "s# compression_type=[a-zA-Z0-9]\\+##g"
-e 's#nbd+unix:///\??socket=SOCK_DIR/nbd#TEST_DIR/t.IMGFMT#g'
)
filename_part=$(echo "$filename_part" | $SED "${filename_filters[@]}")
# Break the option line before each option (preserving pre-existing
# line breaks by replacing them by \0 and restoring them at the end),
# then filter out the options we want to keep and sort them according
# to some order that all block drivers used at the time of writing
# this function.
options=$(
echo "$options" \
| tr '\n' '\0' \
| $SED -e 's/ \([a-z0-9_.-]*\)=/\n\1=/g' \
| grep -a -e '^fmt' -e '^size' -e '^backing' -e '^preallocation' \
-e '^encrypt' "${grep_data_file[@]}" \
| $SED "${filename_filters[@]}" \
-e 's/^\(fmt\)/0-\1/' \
-e 's/^\(size\)/1-\1/' \
-e 's/^\(backing\)/2-\1/' \
-e 's/^\(data_file\)/3-\1/' \
-e 's/^\(encryption\)/4-\1/' \
-e 's/^\(encrypt\.format\)/5-\1/' \
-e 's/^\(encrypt\.key-secret\)/6-\1/' \
-e 's/^\(encrypt\.iter-time\)/7-\1/' \
-e 's/^\(preallocation\)/8-\1/' \
| sort \
| $SED -e 's/^[0-9]-//' \
| tr '\n\0' ' \n' \
| $SED -e 's/^ *$//' -e 's/ *$//'
)
if [ -n "$options" ]; then
echo "$filename_part, $options"
elif [ -n "$filename_part" ]; then
echo "$filename_part"
fi
}
# Filter the "Formatting..." line in QMP output (leaving the QMP output
# untouched)
# (In contrast to _filter_img_create(), this function does not support
# multi-line Formatting output)
_filter_img_create_in_qmp()
{
while read -r line; do
if echo "$line" | grep -q '^Formatting'; then
echo "$line" | _filter_img_create
else
echo "$line"
fi
done
}
_filter_img_create_size()