#!/usr/bin/env python
#
# 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 }
    human_compare = [ 'compat: 0.10', '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 }
    human_compare = [ 'compat: 1.1', 'lazy refcounts: false',
                      'refcount bits: 16', 'corrupt: 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 }
    human_compare = [ 'compat: 1.1', 'lazy refcounts: true',
                      'refcount bits: 16', 'corrupt: 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 }


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 }

TestImageInfoSpecific = None
TestQemuImgInfo = None
TestQMP = None

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