#!/usr/bin/env python3
#
# 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'],
                 supported_protocols=['file'])
