1 # Record/replay test that boots a complete Linux system via a cloud image
3 # Copyright (c) 2020 ISP RAS
6 # Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
8 # This work is licensed under the terms of the GNU GPL, version 2 or
9 # later. See the COPYING file in the top-level directory.
15 from avocado
import skipUnless
16 from avocado_qemu
import BUILD_DIR
17 from avocado
.utils
import cloudinit
18 from avocado
.utils
import network
19 from avocado
.utils
import vmimage
20 from avocado
.utils
import datadrainer
21 from avocado
.utils
.path
import find_command
22 from avocado_qemu
import LinuxTest
24 class ReplayLinux(LinuxTest
):
26 Boots a Linux system, checking for a successful initialization
36 # LinuxTest does many replay-incompatible things, but includes
37 # useful methods. Do not setup LinuxTest here and just
38 # call some functions.
39 super(LinuxTest
, self
).setUp()
41 self
.boot_path
= self
.download_boot()
42 self
.phone_server
= cloudinit
.PhoneHomeServer(('0.0.0.0', 0),
44 ssh_pubkey
, self
.ssh_key
= self
.set_up_existing_ssh_keys()
45 self
.cloudinit_path
= self
.prepare_cloudinit(ssh_pubkey
)
47 def vm_add_disk(self
, vm
, path
, id, device
):
50 bus_string
= ',bus=%s.%d' % (self
.bus
, id,)
51 vm
.add_args('-drive', 'file=%s,snapshot=on,id=disk%s,if=none' % (path
, id))
53 'driver=blkreplay,id=disk%s-rr,if=none,image=disk%s' % (id, id))
54 vm
.add_args('-device',
55 '%s,drive=disk%s-rr%s' % (device
, id, bus_string
))
57 def vm_add_cdrom(self
, vm
, path
, id, device
):
58 vm
.add_args('-drive', 'file=%s,id=disk%s,if=none,media=cdrom' % (path
, id))
60 def launch_and_wait(self
, record
, args
, shift
):
61 self
.require_netdev('user')
63 vm
.add_args('-smp', '1')
64 vm
.add_args('-m', '1024')
65 vm
.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
66 '-device', 'virtio-net,netdev=vnet')
67 vm
.add_args('-object', 'filter-replay,id=replay,netdev=vnet')
70 self
.vm_add_disk(vm
, self
.boot_path
, 0, self
.hdd
)
71 self
.vm_add_cdrom(vm
, self
.cloudinit_path
, 1, self
.cd
)
72 logger
= logging
.getLogger('replay')
74 logger
.info('recording the execution...')
77 logger
.info('replaying the execution...')
79 replay_path
= os
.path
.join(self
.workdir
, 'replay.bin')
80 vm
.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' %
81 (shift
, mode
, replay_path
))
83 start_time
= time
.time()
87 console_drainer
= datadrainer
.LineLogger(vm
.console_socket
.fileno(),
88 logger
=self
.log
.getChild('console'),
89 stop_check
=(lambda : not vm
.is_running()))
90 console_drainer
.start()
92 while not self
.phone_server
.instance_phoned_back
:
93 self
.phone_server
.handle_request()
95 logger
.info('finished the recording with log size %s bytes'
96 % os
.path
.getsize(replay_path
))
98 vm
.event_wait('SHUTDOWN', self
.timeout
)
100 logger
.info('successfully finished the replay')
101 elapsed
= time
.time() - start_time
102 logger
.info('elapsed time %.2f sec' % elapsed
)
105 def run_rr(self
, args
=None, shift
=7):
106 t1
= self
.launch_and_wait(True, args
, shift
)
107 t2
= self
.launch_and_wait(False, args
, shift
)
108 logger
= logging
.getLogger('replay')
109 logger
.info('replay overhead {:.2%}'.format(t2
/ t1
- 1))
111 @skipUnless(os
.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
112 class ReplayLinuxX8664(ReplayLinux
):
114 :avocado: tags=arch:x86_64
115 :avocado: tags=accel:tcg
118 chksum
= 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
120 def test_pc_i440fx(self
):
122 :avocado: tags=machine:pc
126 def test_pc_q35(self
):
128 :avocado: tags=machine:q35
132 @skipUnless(os
.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
133 class ReplayLinuxX8664Virtio(ReplayLinux
):
135 :avocado: tags=arch:x86_64
136 :avocado: tags=virtio
137 :avocado: tags=accel:tcg
140 hdd
= 'virtio-blk-pci'
141 cd
= 'virtio-blk-pci'
144 chksum
= 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
146 def test_pc_i440fx(self
):
148 :avocado: tags=machine:pc
152 def test_pc_q35(self
):
154 :avocado: tags=machine:q35
158 @skipUnless(os
.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
159 class ReplayLinuxAarch64(ReplayLinux
):
161 :avocado: tags=accel:tcg
162 :avocado: tags=arch:aarch64
163 :avocado: tags=machine:virt
164 :avocado: tags=cpu:max
167 chksum
= '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49'
169 hdd
= 'virtio-blk-device'
170 cd
= 'virtio-blk-device'
173 def get_common_args(self
):
175 os
.path
.join(BUILD_DIR
, 'pc-bios', 'edk2-aarch64-code.fd'),
176 "-cpu", "max,lpa2=off",
177 '-device', 'virtio-rng-pci,rng=rng0',
178 '-object', 'rng-builtin,id=rng0')
180 def test_virt_gicv2(self
):
182 :avocado: tags=machine:gic-version=2
186 args
=(*self
.get_common_args(),
187 "-machine", "virt,gic-version=2"))
189 def test_virt_gicv3(self
):
191 :avocado: tags=machine:gic-version=3
195 args
=(*self
.get_common_args(),
196 "-machine", "virt,gic-version=3"))