]>
Commit | Line | Data |
---|---|---|
6fd52d67 CR |
1 | # Functional test that boots a complete Linux system via a cloud image |
2 | # | |
3 | # Copyright (c) 2018-2020 Red Hat, Inc. | |
4 | # | |
5 | # Author: | |
6 | # Cleber Rosa <crosa@redhat.com> | |
7 | # | |
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. | |
10 | ||
11 | import os | |
12 | ||
13 | from avocado_qemu import Test, BUILD_DIR | |
14 | ||
15 | from qemu.accel import kvm_available | |
16 | from qemu.accel import tcg_available | |
17 | ||
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 | |
0f26d94e | 23 | from avocado import skipIf |
6fd52d67 CR |
24 | |
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" | |
28 | ||
29 | ||
1c80c87c PD |
30 | class BootLinuxBase(Test): |
31 | def download_boot(self): | |
6fd52d67 CR |
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) | |
39 | if qemu_img is False: | |
40 | self.cancel('Could not find "qemu-img", which is required to ' | |
41 | 'create the bootable image') | |
42 | vmimage.QEMU_IMG = qemu_img | |
43 | ||
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' | |
49 | try: | |
1c80c87c | 50 | boot = vmimage.get( |
6fd52d67 CR |
51 | 'fedora', arch=image_arch, version='31', |
52 | checksum=self.chksum, | |
53 | algorithm='sha256', | |
54 | cache_dir=self.cache_dirs[0], | |
55 | snapshot_dir=self.workdir) | |
6fd52d67 CR |
56 | except: |
57 | self.cancel('Failed to download/prepare boot image') | |
1c80c87c | 58 | return boot.path |
6fd52d67 | 59 | |
1c80c87c | 60 | def download_cloudinit(self): |
6fd52d67 CR |
61 | self.log.info('Preparing cloudinit image') |
62 | try: | |
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, | |
66 | username='root', | |
67 | password='password', | |
68 | # QEMU's hard coded usermode router address | |
69 | phone_home_host='10.0.2.2', | |
70 | phone_home_port=self.phone_home_port) | |
6fd52d67 CR |
71 | except Exception: |
72 | self.cancel('Failed to prepared cloudinit image') | |
1c80c87c PD |
73 | return cloudinit_iso |
74 | ||
75 | class BootLinux(BootLinuxBase): | |
76 | """ | |
77 | Boots a Linux system, checking for a successful initialization | |
78 | """ | |
79 | ||
80 | timeout = 900 | |
81 | chksum = None | |
82 | ||
83 | def setUp(self): | |
84 | super(BootLinux, self).setUp() | |
85 | self.vm.add_args('-smp', '2') | |
86 | self.vm.add_args('-m', '1024') | |
87 | self.prepare_boot() | |
88 | self.prepare_cloudinit() | |
89 | ||
90 | def prepare_boot(self): | |
91 | path = self.download_boot() | |
92 | self.vm.add_args('-drive', 'file=%s' % path) | |
93 | ||
94 | def prepare_cloudinit(self): | |
95 | cloudinit_iso = self.download_cloudinit() | |
96 | self.vm.add_args('-drive', 'file=%s,format=raw' % cloudinit_iso) | |
6fd52d67 CR |
97 | |
98 | def launch_and_wait(self): | |
99 | self.vm.set_console() | |
100 | self.vm.launch() | |
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) | |
106 | ||
107 | ||
108 | class BootLinuxX8664(BootLinux): | |
109 | """ | |
110 | :avocado: tags=arch:x86_64 | |
111 | """ | |
112 | ||
113 | chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0' | |
114 | ||
115 | def test_pc_i440fx_tcg(self): | |
116 | """ | |
117 | :avocado: tags=machine:pc | |
118 | :avocado: tags=accel:tcg | |
119 | """ | |
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() | |
124 | ||
125 | def test_pc_i440fx_kvm(self): | |
126 | """ | |
127 | :avocado: tags=machine:pc | |
128 | :avocado: tags=accel:kvm | |
129 | """ | |
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() | |
134 | ||
135 | def test_pc_q35_tcg(self): | |
136 | """ | |
137 | :avocado: tags=machine:q35 | |
138 | :avocado: tags=accel:tcg | |
139 | """ | |
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() | |
144 | ||
145 | def test_pc_q35_kvm(self): | |
146 | """ | |
147 | :avocado: tags=machine:q35 | |
148 | :avocado: tags=accel:kvm | |
149 | """ | |
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() | |
154 | ||
155 | ||
156 | class BootLinuxAarch64(BootLinux): | |
157 | """ | |
158 | :avocado: tags=arch:aarch64 | |
159 | :avocado: tags=machine:virt | |
160 | :avocado: tags=machine:gic-version=2 | |
161 | """ | |
162 | ||
163 | chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49' | |
164 | ||
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') | |
171 | ||
172 | def test_virt_tcg(self): | |
173 | """ | |
174 | :avocado: tags=accel:tcg | |
175 | :avocado: tags=cpu:max | |
176 | """ | |
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() | |
184 | ||
185 | def test_virt_kvm(self): | |
186 | """ | |
187 | :avocado: tags=accel:kvm | |
188 | :avocado: tags=cpu:host | |
189 | """ | |
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() | |
197 | ||
198 | ||
199 | class BootLinuxPPC64(BootLinux): | |
200 | """ | |
201 | :avocado: tags=arch:ppc64 | |
202 | """ | |
203 | ||
204 | chksum = '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58' | |
205 | ||
206 | def test_pseries_tcg(self): | |
207 | """ | |
208 | :avocado: tags=machine:pseries | |
209 | :avocado: tags=accel:tcg | |
210 | """ | |
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() | |
215 | ||
216 | ||
217 | class BootLinuxS390X(BootLinux): | |
218 | """ | |
219 | :avocado: tags=arch:s390x | |
220 | """ | |
221 | ||
222 | chksum = '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d' | |
223 | ||
0f26d94e | 224 | @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') |
6fd52d67 CR |
225 | def test_s390_ccw_virtio_tcg(self): |
226 | """ | |
227 | :avocado: tags=machine:s390-ccw-virtio | |
228 | :avocado: tags=accel:tcg | |
229 | """ | |
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() |