#!/bin/bash
#
# Test preallocated growth of qcow2 images
#
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# creator
owner=mreitz@redhat.com

seq=$(basename $0)
echo "QA output created by $seq"

status=1	# failure is the default!

_cleanup()
{
	_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15

get_image_size_on_host()
{
    $QEMU_IMG info -f "$IMGFMT" "$TEST_IMG" | grep "disk size" \
        | sed -e 's/^[^0-9]*\([0-9]\+\).*$/\1/'
}

# get standard environment and filters
. ./common.rc
. ./common.filter

_supported_fmt qcow2
_supported_proto file
_supported_os Linux

if [ -z "$TEST_IMG_FILE" ]; then
    TEST_IMG_FILE=$TEST_IMG
fi

# Generally, we create some image with or without existing preallocation and
# then resize it. Then we write some data into the image and verify that its
# size does not change if we have used preallocation.

# With a cluster size of 512 B, one L2 table covers 64 * 512 B = 32 kB.
# One cluster of the L1 table covers 64 * 32 kB = 2 MB.
# There are multiple cases we want to test:
# (1) Grow an image without having to allocate a new L2 table.
# (2) Grow an image, having to allocate a new L2 table.
# (3) Grow an image, having to grow the L1 table.
# Therefore, we create an image that is 48 kB below 2 MB. Then:
# (1) We resize it to 2 MB - 32 kB. (+ 16 kB)
# (2) We resize it to 2 MB.         (+ 48 kB)
# (3) We resize it to 2 MB + 32 kB. (+ 80 kB)

# in B
CREATION_SIZE=$((2 * 1024 * 1024 - 48 * 1024))

# 512 is the actual test -- but it's good to test 64k as well, just to be sure.
for cluster_size in 512 64k; do
# in kB
for GROWTH_SIZE in 16 48 80; do
    for create_mode in off metadata falloc full; do
        for growth_mode in off metadata falloc full; do
            echo "--- cluster_size=$cluster_size growth_size=$GROWTH_SIZE create_mode=$create_mode growth_mode=$growth_mode ---"

            IMGOPTS="preallocation=$create_mode,cluster_size=$cluster_size" _make_test_img ${CREATION_SIZE}
            $QEMU_IMG resize -f "$IMGFMT" --preallocation=$growth_mode "$TEST_IMG" +${GROWTH_SIZE}K

            host_size_0=$(get_image_size_on_host)
            file_length_0=$(stat -c '%s' "$TEST_IMG_FILE")

            $QEMU_IO -c "write 0 $CREATION_SIZE" "$TEST_IMG" | _filter_qemu_io

            host_size_1=$(get_image_size_on_host)
            file_length_1=$(stat -c '%s' "$TEST_IMG_FILE")

            $QEMU_IO -c "write $CREATION_SIZE ${GROWTH_SIZE}K" "$TEST_IMG" | _filter_qemu_io

            host_size_2=$(get_image_size_on_host)
            file_length_2=$(stat -c '%s' "$TEST_IMG_FILE")

            # Test creation preallocation: Compare #0 against #1
            if [ $create_mode != off ]; then
                # The image length should not have grown
                if [ $file_length_1 -gt $file_length_0 ]; then
                    echo "ERROR (create): Image length has grown from $file_length_0 to $file_length_1"
                fi
                if [ $create_mode != metadata ]; then
                    # The host size should not have grown either
                    if [ $host_size_1 -gt $host_size_0 ]; then
                        echo "ERROR (create): Host size has grown from $host_size_0 to $host_size_1"
                    fi
                fi
            fi

            # Test resize preallocation: Compare #2 against #1
            if [ $growth_mode != off ]; then
                # The image length should not have grown
                if [ $file_length_2 -gt $file_length_1 ]; then
                    echo "ERROR (grow): Image length has grown from $file_length_1 to $file_length_2"
                fi
                if [ $create_mode != metadata ]; then
                    # The host size should not have grown either
                    if [ $host_size_2 -gt $host_size_1 ]; then
                        echo "ERROR (grow): Host size has grown from $host_size_1 to $host_size_2"
                    fi
                fi
            fi

            echo
        done
    done
done
done

# success, all done
echo '*** done'
rm -f $seq.full
status=0
