#!/usr/bin/env python3
# group: rw quick
#
# Test for additional information emitted by qemu-img info on qcow2
# images
#
# Copyright (C) 2013 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/>.
#

import os
import re
import json
import iotests
from iotests import qemu_img, qemu_img_pipe
import unittest

test_img = os.path.join(iotests.test_dir, 'test.img')

class TestImageInfoSpecific(iotests.QMPTestCase):
    '''Abstract base class for ImageInfoSpecific tests'''

    def setUp(self):
        if self.img_options is None:
            self.skipTest('Skipping abstract test class')
        qemu_img('create', '-f', iotests.imgfmt, '-o', self.img_options,
                 test_img, '128K')

    def tearDown(self):
        os.remove(test_img)

class TestQemuImgInfo(TestImageInfoSpecific):
    '''Abstract base class for qemu-img info tests'''

    img_options = None
    json_compare = None
    human_compare = None

    def test_json(self):
        data = json.loads(qemu_img_pipe('info', '--output=json', test_img))
        data = data['format-specific']
        self.assertEqual(data['type'], iotests.imgfmt)
        self.assertEqual(data['data'], self.json_compare)

    def test_human(self):
        data = qemu_img_pipe('info', '--output=human', test_img).split('\n')
        data = data[(data.index('Format specific information:') + 1)
                    :data.index('')]
        for field in data:
            self.assertTrue(re.match('^ {4}[^ ]', field) is not None)
        data = [line.strip() for line in data]
        self.assertEqual(data, self.human_compare)

class TestQMP(TestImageInfoSpecific):
    '''Abstract base class for qemu QMP tests'''

    img_options = None
    qemu_options = ''
    TestImageInfoSpecific = TestImageInfoSpecific

    def setUp(self):
        self.TestImageInfoSpecific.setUp(self)
        self.vm = iotests.VM().add_drive(test_img, self.qemu_options)
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()
        self.TestImageInfoSpecific.tearDown(self)

    def test_qmp(self):
        result = self.vm.qmp('query-block')['return']
        drive = next(drive for drive in result if drive['device'] == 'drive0')
        data = drive['inserted']['image']['format-specific']
        self.assertEqual(data['type'], iotests.imgfmt)
        self.assertEqual(data['data'], self.compare)

class TestQCow2(TestQemuImgInfo):
    '''Testing a qcow2 version 2 image'''
    img_options = 'compat=0.10'
    json_compare = { 'compat': '0.10', 'refcount-bits': 16,
                     'compression-type': 'zlib' }
    human_compare = [ 'compat: 0.10', 'compression type: zlib',
                      'refcount bits: 16' ]

class TestQCow3NotLazy(TestQemuImgInfo):
    '''Testing a qcow2 version 3 image with lazy refcounts disabled'''
    img_options = 'compat=1.1,lazy_refcounts=off'
    json_compare = { 'compat': '1.1', 'lazy-refcounts': False,
                     'refcount-bits': 16, 'corrupt': False,
                     'compression-type': 'zlib', 'extended-l2': False }
    human_compare = [ 'compat: 1.1', 'compression type: zlib',
                      'lazy refcounts: false', 'refcount bits: 16',
                      'corrupt: false', 'extended l2: false' ]

class TestQCow3Lazy(TestQemuImgInfo):
    '''Testing a qcow2 version 3 image with lazy refcounts enabled'''
    img_options = 'compat=1.1,lazy_refcounts=on'
    json_compare = { 'compat': '1.1', 'lazy-refcounts': True,
                     'refcount-bits': 16, 'corrupt': False,
                     'compression-type': 'zlib', 'extended-l2': False }
    human_compare = [ 'compat: 1.1', 'compression type: zlib',
                      'lazy refcounts: true', 'refcount bits: 16',
                      'corrupt: false', 'extended l2: false' ]

class TestQCow3NotLazyQMP(TestQMP):
    '''Testing a qcow2 version 3 image with lazy refcounts disabled, opening
       with lazy refcounts enabled'''
    img_options = 'compat=1.1,lazy_refcounts=off'
    qemu_options = 'lazy-refcounts=on'
    compare = { 'compat': '1.1', 'lazy-refcounts': False,
                'refcount-bits': 16, 'corrupt': False,
                'compression-type': 'zlib', 'extended-l2': False }


class TestQCow3LazyQMP(TestQMP):
    '''Testing a qcow2 version 3 image with lazy refcounts enabled, opening
       with lazy refcounts disabled'''
    img_options = 'compat=1.1,lazy_refcounts=on'
    qemu_options = 'lazy-refcounts=off'
    compare = { 'compat': '1.1', 'lazy-refcounts': True,
                'refcount-bits': 16, 'corrupt': False,
                'compression-type': 'zlib', 'extended-l2': False }

TestImageInfoSpecific = None
TestQemuImgInfo = None
TestQMP = None

if __name__ == '__main__':
    iotests.main(supported_fmts=['qcow2'],
                 supported_protocols=['file'])
