 72cfb937b8
			
		
	
	
		72cfb937b8
		
	
	
	
	
		
			
			Like qemu-img, qemu-io returning 0 should be the norm and not the exception. Remove all calls to qemu_io_silent that just assert the return code is zero (That's every last call, as it turns out), and replace them with a normal qemu_io() call. qemu_io_silent_check() appeared to have been unused already. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Hanna Reitz <hreitz@redhat.com> Message-Id: <20220418211504.943969-12-jsnow@redhat.com> Signed-off-by: Hanna Reitz <hreitz@redhat.com>
		
			
				
	
	
		
			162 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python3
 | |
| # group: rw quick
 | |
| #
 | |
| # Very specific tests for adjacent commit/stream block jobs
 | |
| #
 | |
| # Copyright (C) 2019 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/>.
 | |
| #
 | |
| # Creator/Owner: Hanna Reitz <hreitz@redhat.com>
 | |
| 
 | |
| import iotests
 | |
| from iotests import log, qemu_img, qemu_io, \
 | |
|         filter_qmp_testfiles, filter_qmp_imgfmt
 | |
| 
 | |
| # Returns a node for blockdev-add
 | |
| def node(node_name, path, backing=None, fmt=None, throttle=None):
 | |
|     if fmt is None:
 | |
|         fmt = iotests.imgfmt
 | |
| 
 | |
|     res = {
 | |
|         'node-name': node_name,
 | |
|         'driver': fmt,
 | |
|         'file': {
 | |
|             'driver': 'file',
 | |
|             'filename': path
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if backing is not None:
 | |
|         res['backing'] = backing
 | |
| 
 | |
|     if throttle:
 | |
|         res['file'] = {
 | |
|             'driver': 'throttle',
 | |
|             'throttle-group': throttle,
 | |
|             'file': res['file']
 | |
|         }
 | |
| 
 | |
|     return res
 | |
| 
 | |
| # Finds a node in the debug block graph
 | |
| def find_graph_node(graph, node_id):
 | |
|     return next(node for node in graph['nodes'] if node['id'] == node_id)
 | |
| 
 | |
| 
 | |
| def test_concurrent_finish(write_to_stream_node):
 | |
|     log('')
 | |
|     log('=== Commit and stream finish concurrently (letting %s write) ===' % \
 | |
|         ('stream' if write_to_stream_node else 'commit'))
 | |
|     log('')
 | |
| 
 | |
|     # All chosen in such a way that when the commit job wants to
 | |
|     # finish, it polls and thus makes stream finish concurrently --
 | |
|     # and the other way around, depending on whether the commit job
 | |
|     # is finalized before stream completes or not.
 | |
| 
 | |
|     with iotests.FilePath('node4.img') as node4_path, \
 | |
|          iotests.FilePath('node3.img') as node3_path, \
 | |
|          iotests.FilePath('node2.img') as node2_path, \
 | |
|          iotests.FilePath('node1.img') as node1_path, \
 | |
|          iotests.FilePath('node0.img') as node0_path, \
 | |
|          iotests.VM() as vm:
 | |
| 
 | |
|         # It is important to use raw for the base layer (so that
 | |
|         # permissions are just handed through to the protocol layer)
 | |
|         qemu_img('create', '-f', 'raw', node0_path, '64M')
 | |
| 
 | |
|         stream_throttle=None
 | |
|         commit_throttle=None
 | |
| 
 | |
|         for path in [node1_path, node2_path, node3_path, node4_path]:
 | |
|             qemu_img('create', '-f', iotests.imgfmt, path, '64M')
 | |
| 
 | |
|         if write_to_stream_node:
 | |
|             # This is what (most of the time) makes commit finish
 | |
|             # earlier and then pull in stream
 | |
|             qemu_io(node2_path,
 | |
|                     '-c', 'write %iK 64K' % (65536 - 192),
 | |
|                     '-c', 'write %iK 64K' % (65536 -  64))
 | |
| 
 | |
|             stream_throttle='tg'
 | |
|         else:
 | |
|             # And this makes stream finish earlier
 | |
|             qemu_io(node1_path, '-c', 'write %iK 64K' % (65536 - 64))
 | |
| 
 | |
|             commit_throttle='tg'
 | |
| 
 | |
|         vm.launch()
 | |
| 
 | |
|         vm.qmp_log('object-add',
 | |
|                    qom_type='throttle-group',
 | |
|                    id='tg',
 | |
|                    limits={
 | |
|                        'iops-write': 1,
 | |
|                        'iops-write-max': 1
 | |
|                    })
 | |
| 
 | |
|         vm.qmp_log('blockdev-add',
 | |
|                    filters=[filter_qmp_testfiles, filter_qmp_imgfmt],
 | |
|                    **node('node4', node4_path, throttle=stream_throttle,
 | |
|                      backing=node('node3', node3_path,
 | |
|                      backing=node('node2', node2_path,
 | |
|                      backing=node('node1', node1_path,
 | |
|                      backing=node('node0', node0_path, throttle=commit_throttle,
 | |
|                                   fmt='raw'))))))
 | |
| 
 | |
|         vm.qmp_log('block-commit',
 | |
|                    job_id='commit',
 | |
|                    device='node4',
 | |
|                    filter_node_name='commit-filter',
 | |
|                    top_node='node1',
 | |
|                    base_node='node0',
 | |
|                    auto_finalize=False)
 | |
| 
 | |
|         vm.qmp_log('block-stream',
 | |
|                    job_id='stream',
 | |
|                    device='node3',
 | |
|                    base_node='commit-filter')
 | |
| 
 | |
|         if write_to_stream_node:
 | |
|             vm.run_job('commit', auto_finalize=False, auto_dismiss=True)
 | |
|             vm.run_job('stream', auto_finalize=True, auto_dismiss=True)
 | |
|         else:
 | |
|             # No, the jobs do not really finish concurrently here,
 | |
|             # the stream job does complete strictly before commit.
 | |
|             # But still, this is close enough for what we want to
 | |
|             # test.
 | |
|             vm.run_job('stream', auto_finalize=True, auto_dismiss=True)
 | |
|             vm.run_job('commit', auto_finalize=False, auto_dismiss=True)
 | |
| 
 | |
|         # Assert that the backing node of node3 is node 0 now
 | |
|         graph = vm.qmp('x-debug-query-block-graph')['return']
 | |
|         for edge in graph['edges']:
 | |
|             if edge['name'] == 'backing' and \
 | |
|                find_graph_node(graph, edge['parent'])['name'] == 'node3':
 | |
|                 assert find_graph_node(graph, edge['child'])['name'] == 'node0'
 | |
|                 break
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     log('Running tests:')
 | |
|     test_concurrent_finish(True)
 | |
|     test_concurrent_finish(False)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     # Need backing file and change-backing-file support
 | |
|     iotests.script_main(main,
 | |
|                         supported_fmts=['qcow2', 'qed'],
 | |
|                         supported_platforms=['linux'])
 |