xref: /qemu/tests/qemu-iotests/224 (revision a976a99a)
1#!/usr/bin/env python3
2# group: rw quick
3#
4# Test json:{} filenames with qemu-internal BDSs
5# (the one of commit, to be precise)
6#
7# Copyright (C) 2018 Red Hat, Inc.
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation; either version 2 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21#
22# Creator/Owner: Hanna Reitz <hreitz@redhat.com>
23
24import iotests
25from iotests import log, qemu_img, qemu_io, filter_qmp_testfiles, \
26                    filter_qmp_imgfmt
27import json
28
29# Need backing file support (for arbitrary backing formats)
30iotests.script_initialize(supported_fmts=['qcow2', 'qcow', 'qed'],
31                          supported_platforms=['linux'])
32
33
34# There are two variations of this test:
35# (1) We do not set filter_node_name.  In that case, the commit_top
36#     driver should not appear anywhere.
37# (2) We do set filter_node_name.  In that case, it should appear.
38#
39# This for loop executes both.
40for filter_node_name in False, True:
41    log('')
42    log('--- filter_node_name: %s ---' % filter_node_name)
43    log('')
44
45    with iotests.FilePath('base.img') as base_img_path, \
46         iotests.FilePath('mid.img') as mid_img_path, \
47         iotests.FilePath('top.img') as top_img_path, \
48         iotests.VM() as vm:
49
50        qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M')
51        qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path,
52                 '-F', iotests.imgfmt, mid_img_path)
53        qemu_img('create', '-f', iotests.imgfmt, '-b', mid_img_path,
54                 '-F', iotests.imgfmt, top_img_path)
55
56        # Something to commit
57        qemu_io(mid_img_path, '-c', 'write -P 1 0 1M')
58
59        vm.launch()
60
61        # Change the bottom-most image's backing file (to null-co://)
62        # to enforce json:{} filenames
63        vm.qmp_log('blockdev-add',
64                    node_name='top',
65                    driver=iotests.imgfmt,
66                    file={
67                        'driver': 'file',
68                        'filename': top_img_path
69                    },
70                    backing={
71                        'node-name': 'mid',
72                        'driver': iotests.imgfmt,
73                        'file': {
74                            'driver': 'file',
75                            'filename': mid_img_path
76                        },
77                        'backing': {
78                            'node-name': 'base',
79                            'driver': iotests.imgfmt,
80                            'file': {
81                                'driver': 'file',
82                                'filename': base_img_path
83                            },
84                            'backing': {
85                                'driver': 'null-co'
86                            }
87                        }
88                    },
89                    filters=[filter_qmp_testfiles, filter_qmp_imgfmt])
90
91        # As long as block-commit does not accept node names, we have to
92        # get our mid/base filenames here
93        mid_name = vm.node_info('mid')['image']['filename']
94        base_name = vm.node_info('base')['image']['filename']
95
96        assert mid_name[:5] == 'json:'
97        assert base_name[:5] == 'json:'
98
99        # Start the block job
100        if filter_node_name:
101            vm.qmp_log('block-commit',
102                        job_id='commit',
103                        device='top',
104                        filter_node_name='filter_node',
105                        top=mid_name,
106                        base=base_name,
107                        speed=1,
108                        filters=[filter_qmp_testfiles, filter_qmp_imgfmt])
109        else:
110            vm.qmp_log('block-commit',
111                        job_id='commit',
112                        device='top',
113                        top=mid_name,
114                        base=base_name,
115                        speed=1,
116                        filters=[filter_qmp_testfiles, filter_qmp_imgfmt])
117
118        vm.qmp_log('job-pause', id='commit')
119
120        # Get and parse top's json:{} filename
121        top_name = vm.node_info('top')['image']['filename']
122
123        vm.shutdown()
124
125        assert top_name[:5] == 'json:'
126        top_options = json.loads(top_name[5:])
127
128        if filter_node_name:
129            # This should be present and set
130            assert top_options['backing']['driver'] == 'commit_top'
131            # And the mid image is commit_top's backing image
132            mid_options = top_options['backing']['backing']
133        else:
134            # The mid image should appear as the immediate backing BDS
135            # of top
136            mid_options = top_options['backing']
137
138        assert mid_options['driver'] == iotests.imgfmt
139        assert mid_options['file']['filename'] == mid_img_path
140