#!/usr/bin/env python2
#
# 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 = map(lambda line: line.strip(), 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 = filter(lambda drive: drive['device'] == 'drive0', result)[0]
        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' }
    human_compare = [ 'compat: 0.10' ]

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 }
    human_compare = [ 'compat: 1.1', 'lazy refcounts: 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 }
    human_compare = [ 'compat: 1.1', 'lazy refcounts: true' ]

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 }

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 }

TestImageInfoSpecific = None
TestQemuImgInfo = None
TestQMP = None

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