1 # Functional test that boots a complete Linux system via a cloud image
3 # Copyright (c) 2018-2020 Red Hat, Inc.
6 # Cleber Rosa <crosa@redhat.com>
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.
13 from avocado_qemu
import Test
, BUILD_DIR
15 from qemu
.accel
import kvm_available
16 from qemu
.accel
import tcg_available
18 from avocado
.utils
import cloudinit
19 from avocado
.utils
import network
20 from avocado
.utils
import vmimage
21 from avocado
.utils
import datadrainer
22 from avocado
.utils
.path
import find_command
23 from avocado
import skipIf
25 ACCEL_NOT_AVAILABLE_FMT
= "%s accelerator does not seem to be available"
26 KVM_NOT_AVAILABLE
= ACCEL_NOT_AVAILABLE_FMT
% "KVM"
27 TCG_NOT_AVAILABLE
= ACCEL_NOT_AVAILABLE_FMT
% "TCG"
30 class BootLinuxBase(Test
):
31 def download_boot(self
):
32 self
.log
.debug('Looking for and selecting a qemu-img binary to be '
33 'used to create the bootable snapshot image')
34 # If qemu-img has been built, use it, otherwise the system wide one
35 # will be used. If none is available, the test will cancel.
36 qemu_img
= os
.path
.join(BUILD_DIR
, 'qemu-img')
37 if not os
.path
.exists(qemu_img
):
38 qemu_img
= find_command('qemu-img', False)
40 self
.cancel('Could not find "qemu-img", which is required to '
41 'create the bootable image')
42 vmimage
.QEMU_IMG
= qemu_img
44 self
.log
.info('Downloading/preparing boot image')
45 # Fedora 31 only provides ppc64le images
46 image_arch
= self
.arch
47 if image_arch
== 'ppc64':
48 image_arch
= 'ppc64le'
51 'fedora', arch
=image_arch
, version
='31',
54 cache_dir
=self
.cache_dirs
[0],
55 snapshot_dir
=self
.workdir
)
57 self
.cancel('Failed to download/prepare boot image')
60 def download_cloudinit(self
):
61 self
.log
.info('Preparing cloudinit image')
63 cloudinit_iso
= os
.path
.join(self
.workdir
, 'cloudinit.iso')
64 self
.phone_home_port
= network
.find_free_port()
65 cloudinit
.iso(cloudinit_iso
, self
.name
,
68 # QEMU's hard coded usermode router address
69 phone_home_host
='10.0.2.2',
70 phone_home_port
=self
.phone_home_port
)
72 self
.cancel('Failed to prepared cloudinit image')
75 class BootLinux(BootLinuxBase
):
77 Boots a Linux system, checking for a successful initialization
84 super(BootLinux
, self
).setUp()
85 self
.vm
.add_args('-smp', '2')
86 self
.vm
.add_args('-m', '1024')
88 self
.prepare_cloudinit()
90 def prepare_boot(self
):
91 path
= self
.download_boot()
92 self
.vm
.add_args('-drive', 'file=%s' % path
)
94 def prepare_cloudinit(self
):
95 cloudinit_iso
= self
.download_cloudinit()
96 self
.vm
.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso
)
98 def launch_and_wait(self
):
101 console_drainer
= datadrainer
.LineLogger(self
.vm
.console_socket
.fileno(),
102 logger
=self
.log
.getChild('console'))
103 console_drainer
.start()
104 self
.log
.info('VM launched, waiting for boot confirmation from guest')
105 cloudinit
.wait_for_phone_home(('0.0.0.0', self
.phone_home_port
), self
.name
)
108 class BootLinuxX8664(BootLinux
):
110 :avocado: tags=arch:x86_64
113 chksum
= 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
115 def test_pc_i440fx_tcg(self
):
117 :avocado: tags=machine:pc
118 :avocado: tags=accel:tcg
120 if not tcg_available(self
.qemu_bin
):
121 self
.cancel(TCG_NOT_AVAILABLE
)
122 self
.vm
.add_args("-accel", "tcg")
123 self
.launch_and_wait()
125 def test_pc_i440fx_kvm(self
):
127 :avocado: tags=machine:pc
128 :avocado: tags=accel:kvm
130 if not kvm_available(self
.arch
, self
.qemu_bin
):
131 self
.cancel(KVM_NOT_AVAILABLE
)
132 self
.vm
.add_args("-accel", "kvm")
133 self
.launch_and_wait()
135 def test_pc_q35_tcg(self
):
137 :avocado: tags=machine:q35
138 :avocado: tags=accel:tcg
140 if not tcg_available(self
.qemu_bin
):
141 self
.cancel(TCG_NOT_AVAILABLE
)
142 self
.vm
.add_args("-accel", "tcg")
143 self
.launch_and_wait()
145 def test_pc_q35_kvm(self
):
147 :avocado: tags=machine:q35
148 :avocado: tags=accel:kvm
150 if not kvm_available(self
.arch
, self
.qemu_bin
):
151 self
.cancel(KVM_NOT_AVAILABLE
)
152 self
.vm
.add_args("-accel", "kvm")
153 self
.launch_and_wait()
156 class BootLinuxAarch64(BootLinux
):
158 :avocado: tags=arch:aarch64
159 :avocado: tags=machine:virt
160 :avocado: tags=machine:gic-version=2
163 chksum
= '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49'
165 def add_common_args(self
):
166 self
.vm
.add_args('-bios',
167 os
.path
.join(BUILD_DIR
, 'pc-bios',
168 'edk2-aarch64-code.fd'))
169 self
.vm
.add_args('-device', 'virtio-rng-pci,rng=rng0')
170 self
.vm
.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
172 def test_virt_tcg(self
):
174 :avocado: tags=accel:tcg
175 :avocado: tags=cpu:max
177 if not tcg_available(self
.qemu_bin
):
178 self
.cancel(TCG_NOT_AVAILABLE
)
179 self
.vm
.add_args("-accel", "tcg")
180 self
.vm
.add_args("-cpu", "max")
181 self
.vm
.add_args("-machine", "virt,gic-version=2")
182 self
.add_common_args()
183 self
.launch_and_wait()
185 def test_virt_kvm(self
):
187 :avocado: tags=accel:kvm
188 :avocado: tags=cpu:host
190 if not kvm_available(self
.arch
, self
.qemu_bin
):
191 self
.cancel(KVM_NOT_AVAILABLE
)
192 self
.vm
.add_args("-accel", "kvm")
193 self
.vm
.add_args("-cpu", "host")
194 self
.vm
.add_args("-machine", "virt,gic-version=2")
195 self
.add_common_args()
196 self
.launch_and_wait()
199 class BootLinuxPPC64(BootLinux
):
201 :avocado: tags=arch:ppc64
204 chksum
= '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58'
206 def test_pseries_tcg(self
):
208 :avocado: tags=machine:pseries
209 :avocado: tags=accel:tcg
211 if not tcg_available(self
.qemu_bin
):
212 self
.cancel(TCG_NOT_AVAILABLE
)
213 self
.vm
.add_args("-accel", "tcg")
214 self
.launch_and_wait()
217 class BootLinuxS390X(BootLinux
):
219 :avocado: tags=arch:s390x
222 chksum
= '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d'
224 @skipIf(os
.getenv('GITLAB_CI'), 'Running on GitLab')
225 def test_s390_ccw_virtio_tcg(self
):
227 :avocado: tags=machine:s390-ccw-virtio
228 :avocado: tags=accel:tcg
230 if not tcg_available(self
.qemu_bin
):
231 self
.cancel(TCG_NOT_AVAILABLE
)
232 self
.vm
.add_args("-accel", "tcg")
233 self
.launch_and_wait()