blob: f7a2533746f690bdd75ebc403f3e1cc4d3455649 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: MIT
3#
4
Brad Bishopd7bf8c12018-02-25 22:55:05 -05005from oeqa.selftest.case import OESelftestTestCase
6from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu
Brad Bishopd7bf8c12018-02-25 22:55:05 -05007from oeqa.utils.sshcontrol import SSHControl
8import os
9import json
10
11class ImageFeatures(OESelftestTestCase):
12
13 test_user = 'tester'
14 root_user = 'root'
15
Brad Bishopd7bf8c12018-02-25 22:55:05 -050016 def test_non_root_user_can_connect_via_ssh_without_password(self):
17 """
18 Summary: Check if non root user can connect via ssh without password
19 Expected: 1. Connection to the image via ssh using root user without providing a password should be allowed.
20 2. Connection to the image via ssh using tester user without providing a password should be allowed.
21 Product: oe-core
22 Author: Ionut Chisanovici <ionutx.chisanovici@intel.com>
23 AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
24 """
25
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080026 features = 'EXTRA_IMAGE_FEATURES = "ssh-server-openssh empty-root-password allow-empty-password allow-root-login"\n'
Brad Bishopd7bf8c12018-02-25 22:55:05 -050027 features += 'INHERIT += "extrausers"\n'
28 features += 'EXTRA_USERS_PARAMS = "useradd -p \'\' {}; usermod -s /bin/sh {};"'.format(self.test_user, self.test_user)
29 self.write_config(features)
30
31 # Build a core-image-minimal
32 bitbake('core-image-minimal')
33
34 with runqemu("core-image-minimal") as qemu:
35 # Attempt to ssh with each user into qemu with empty password
36 for user in [self.root_user, self.test_user]:
37 ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user)
38 status, output = ssh.run("true")
39 self.assertEqual(status, 0, 'ssh to user %s failed with %s' % (user, output))
40
Brad Bishopd7bf8c12018-02-25 22:55:05 -050041 def test_all_users_can_connect_via_ssh_without_password(self):
42 """
43 Summary: Check if all users can connect via ssh without password
44 Expected: 1. Connection to the image via ssh using root user without providing a password should NOT be allowed.
45 2. Connection to the image via ssh using tester user without providing a password should be allowed.
46 Product: oe-core
47 Author: Ionut Chisanovici <ionutx.chisanovici@intel.com>
48 AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
49 """
50
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080051 features = 'EXTRA_IMAGE_FEATURES = "ssh-server-openssh allow-empty-password allow-root-login"\n'
Brad Bishopd7bf8c12018-02-25 22:55:05 -050052 features += 'INHERIT += "extrausers"\n'
53 features += 'EXTRA_USERS_PARAMS = "useradd -p \'\' {}; usermod -s /bin/sh {};"'.format(self.test_user, self.test_user)
54 self.write_config(features)
55
56 # Build a core-image-minimal
57 bitbake('core-image-minimal')
58
59 with runqemu("core-image-minimal") as qemu:
60 # Attempt to ssh with each user into qemu with empty password
61 for user in [self.root_user, self.test_user]:
62 ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user)
63 status, output = ssh.run("true")
64 if user == 'root':
65 self.assertNotEqual(status, 0, 'ssh to user root was allowed when it should not have been')
66 else:
67 self.assertEqual(status, 0, 'ssh to user tester failed with %s' % output)
68
69
Brad Bishopd7bf8c12018-02-25 22:55:05 -050070 def test_clutter_image_can_be_built(self):
71 """
72 Summary: Check if clutter image can be built
73 Expected: 1. core-image-clutter can be built
74 Product: oe-core
75 Author: Ionut Chisanovici <ionutx.chisanovici@intel.com>
76 AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
77 """
78
79 # Build a core-image-clutter
80 bitbake('core-image-clutter')
81
Brad Bishopd7bf8c12018-02-25 22:55:05 -050082 def test_wayland_support_in_image(self):
83 """
84 Summary: Check Wayland support in image
85 Expected: 1. Wayland image can be build
86 2. Wayland feature can be installed
87 Product: oe-core
88 Author: Ionut Chisanovici <ionutx.chisanovici@intel.com>
89 AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
90 """
91
92 distro_features = get_bb_var('DISTRO_FEATURES')
93 if not ('opengl' in distro_features and 'wayland' in distro_features):
94 self.skipTest('neither opengl nor wayland present on DISTRO_FEATURES so core-image-weston cannot be built')
95
96 # Build a core-image-weston
97 bitbake('core-image-weston')
98
Brad Bishopd7bf8c12018-02-25 22:55:05 -050099 def test_bmap(self):
100 """
101 Summary: Check bmap support
102 Expected: 1. core-image-minimal can be build with bmap support
103 2. core-image-minimal is sparse
104 Product: oe-core
105 Author: Ed Bartosh <ed.bartosh@linux.intel.com>
106 """
107
108 features = 'IMAGE_FSTYPES += " ext4 ext4.bmap ext4.bmap.gz"'
109 self.write_config(features)
110
111 image_name = 'core-image-minimal'
112 bitbake(image_name)
113
114 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
115 link_name = get_bb_var('IMAGE_LINK_NAME', image_name)
116 image_path = os.path.join(deploy_dir_image, "%s.ext4" % link_name)
117 bmap_path = "%s.bmap" % image_path
118 gzip_path = "%s.gz" % bmap_path
119
120 # check if result image, bmap and bmap.gz files are in deploy directory
121 self.assertTrue(os.path.exists(image_path))
122 self.assertTrue(os.path.exists(bmap_path))
123 self.assertTrue(os.path.exists(gzip_path))
124
125 # check if result image is sparse
126 image_stat = os.stat(image_path)
Brad Bishop64c979e2019-11-04 13:55:29 -0500127 self.assertGreater(image_stat.st_size, image_stat.st_blocks * 512)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500128
129 # check if the resulting gzip is valid
130 self.assertTrue(runCmd('gzip -t %s' % gzip_path))
131
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500132 def test_hypervisor_fmts(self):
133 """
134 Summary: Check various hypervisor formats
135 Expected: 1. core-image-minimal can be built with vmdk, vdi and
136 qcow2 support.
137 2. qemu-img says each image has the expected format
138 Product: oe-core
139 Author: Tom Rini <trini@konsulko.com>
140 """
141
142 img_types = [ 'vmdk', 'vdi', 'qcow2' ]
143 features = ""
144 for itype in img_types:
145 features += 'IMAGE_FSTYPES += "wic.%s"\n' % itype
146 self.write_config(features)
147
148 image_name = 'core-image-minimal'
149 bitbake(image_name)
150
151 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
152 link_name = get_bb_var('IMAGE_LINK_NAME', image_name)
153 for itype in img_types:
154 image_path = os.path.join(deploy_dir_image, "%s.wic.%s" %
155 (link_name, itype))
156
157 # check if result image file is in deploy directory
158 self.assertTrue(os.path.exists(image_path))
159
160 # check if result image is vmdk
161 sysroot = get_bb_var('STAGING_DIR_NATIVE', 'core-image-minimal')
162 result = runCmd('qemu-img info --output json %s' % image_path,
163 native_sysroot=sysroot)
Brad Bishopf3f93bb2019-10-16 14:33:32 -0400164 try:
165 data = json.loads(result.output)
166 self.assertEqual(data.get('format'), itype,
167 msg="Unexpected format in '%s'" % (result.output))
168 except json.decoder.JSONDecodeError:
169 self.fail("Could not parse '%ss'" % result.output)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500170
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500171 def test_long_chain_conversion(self):
172 """
173 Summary: Check for chaining many CONVERSION_CMDs together
174 Expected: 1. core-image-minimal can be built with
175 ext4.bmap.gz.bz2.lzo.xz.u-boot and also create a
176 sha256sum
177 2. The above image has a valid sha256sum
178 Product: oe-core
179 Author: Tom Rini <trini@konsulko.com>
180 """
181
182 conv = "ext4.bmap.gz.bz2.lzo.xz.u-boot"
183 features = 'IMAGE_FSTYPES += "%s %s.sha256sum"' % (conv, conv)
184 self.write_config(features)
185
186 image_name = 'core-image-minimal'
187 bitbake(image_name)
188
189 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
190 link_name = get_bb_var('IMAGE_LINK_NAME', image_name)
191 image_path = os.path.join(deploy_dir_image, "%s.%s" %
192 (link_name, conv))
193
194 # check if resulting image is in the deploy directory
195 self.assertTrue(os.path.exists(image_path))
196 self.assertTrue(os.path.exists(image_path + ".sha256sum"))
197
198 # check if the resulting sha256sum agrees
199 self.assertTrue(runCmd('cd %s;sha256sum -c %s.%s.sha256sum' %
200 (deploy_dir_image, link_name, conv)))
201
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500202 def test_image_fstypes(self):
203 """
204 Summary: Check if image of supported image fstypes can be built
205 Expected: core-image-minimal can be built for various image types
206 Product: oe-core
207 Author: Ed Bartosh <ed.bartosh@linux.intel.com>
208 """
209 image_name = 'core-image-minimal'
210
Andrew Geissler82c905d2020-04-13 13:39:40 -0500211 all_image_types = set(get_bb_var("IMAGE_TYPES", image_name).split())
Andrew Geissler1e34c2d2020-05-29 16:02:59 -0500212 blacklist = set(('container', 'elf', 'f2fs', 'multiubi', 'tar.zst', 'wic.zst'))
Andrew Geissler82c905d2020-04-13 13:39:40 -0500213 img_types = all_image_types - blacklist
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500214
215 config = 'IMAGE_FSTYPES += "%s"\n'\
216 'MKUBIFS_ARGS ?= "-m 2048 -e 129024 -c 2047"\n'\
217 'UBINIZE_ARGS ?= "-m 2048 -p 128KiB -s 512"' % ' '.join(img_types)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500218 self.write_config(config)
219
220 bitbake(image_name)
221
222 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
223 link_name = get_bb_var('IMAGE_LINK_NAME', image_name)
224 for itype in img_types:
225 image_path = os.path.join(deploy_dir_image, "%s.%s" % (link_name, itype))
226 # check if result image is in deploy directory
227 self.assertTrue(os.path.exists(image_path),
228 "%s image %s doesn't exist" % (itype, image_path))
229
230 def test_useradd_static(self):
231 config = """
232USERADDEXTENSION = "useradd-staticids"
233USERADD_ERROR_DYNAMIC = "skip"
234USERADD_UID_TABLES += "files/static-passwd"
235USERADD_GID_TABLES += "files/static-group"
236"""
237 self.write_config(config)
238 bitbake("core-image-base")
Brad Bishop19323692019-04-05 15:28:33 -0400239
240 def test_no_busybox_base_utils(self):
241 config = """
242# Enable x11
243DISTRO_FEATURES_append += "x11"
244
245# Switch to systemd
246DISTRO_FEATURES += "systemd"
247VIRTUAL-RUNTIME_init_manager = "systemd"
248VIRTUAL-RUNTIME_initscripts = ""
249VIRTUAL-RUNTIME_syslog = ""
250VIRTUAL-RUNTIME_login_manager = "shadow-base"
251DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
252
253# Replace busybox
254PREFERRED_PROVIDER_virtual/base-utils = "packagegroup-core-base-utils"
255VIRTUAL-RUNTIME_base-utils = "packagegroup-core-base-utils"
256VIRTUAL-RUNTIME_base-utils-hwclock = "util-linux-hwclock"
257VIRTUAL-RUNTIME_base-utils-syslog = ""
258
259# Blacklist busybox
260PNBLACKLIST[busybox] = "Don't build this"
261"""
262 self.write_config(config)
263
264 bitbake("--graphviz core-image-sato")
Andrew Geisslerc182c622020-05-15 14:13:32 -0500265
Andrew Geissler635e0e42020-08-21 15:58:33 -0500266 def test_fit_image(self):
267 """
268 Summary: Check if FIT image and Image Tree Source (its) are built
269 and the Image Tree Source has the correct fields.
270 Expected: 1. fitImage and fitImage-its can be built
271 2. The type, load address, entrypoint address and
272 default values of kernel and ramdisk are as expected
273 in the Image Tree Source. Not all the fields are tested,
274 only the key fields that wont vary between different
275 architectures.
276 Product: oe-core
277 Author: Usama Arif <usama.arif@arm.com>
278 """
279 config = """
280# Enable creation of fitImage
281KERNEL_IMAGETYPE = "Image"
282KERNEL_IMAGETYPES += " fitImage "
283KERNEL_CLASSES = " kernel-fitimage "
284
285# RAM disk variables including load address and entrypoint for kernel and RAM disk
286IMAGE_FSTYPES += "cpio.gz"
287INITRAMFS_IMAGE = "core-image-minimal"
288UBOOT_RD_LOADADDRESS = "0x88000000"
289UBOOT_RD_ENTRYPOINT = "0x88000000"
290UBOOT_LOADADDRESS = "0x80080000"
291UBOOT_ENTRYPOINT = "0x80080000"
292"""
293 self.write_config(config)
294
295 # fitImage is created as part of linux recipe
296 bitbake("virtual/kernel")
297
298 image_type = "core-image-minimal"
299 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
300 machine = get_bb_var('MACHINE')
301 fitimage_its_path = os.path.join(deploy_dir_image,
302 "fitImage-its-%s-%s-%s" % (image_type, machine, machine))
303 fitimage_path = os.path.join(deploy_dir_image,
304 "fitImage-%s-%s-%s" % (image_type, machine, machine))
305
306 self.assertTrue(os.path.exists(fitimage_its_path),
307 "%s image tree source doesn't exist" % (fitimage_its_path))
308 self.assertTrue(os.path.exists(fitimage_path),
309 "%s FIT image doesn't exist" % (fitimage_path))
310
311 # Check that the type, load address, entrypoint address and default
312 # values for kernel and ramdisk in Image Tree Source are as expected.
313 # The order of fields in the below array is important. Not all the
314 # fields are tested, only the key fields that wont vary between
315 # different architectures.
316 its_field_check = ['type = "kernel";',
317 'load = <0x80080000>;',
318 'entry = <0x80080000>;',
319 'type = "ramdisk";',
320 'load = <0x88000000>;',
321 'entry = <0x88000000>;',
322 'default = "conf@1";',
323 'kernel = "kernel@1";',
324 'ramdisk = "ramdisk@1";'
325 ]
326
327 with open(fitimage_its_path) as its_file:
328 field_index = 0
329 for line in its_file:
330 if field_index == len(its_field_check):
331 break
332 if its_field_check[field_index] in line:
333 field_index +=1
334
335 if field_index != len(its_field_check): # if its equal, the test passed
336 self.assertTrue(field_index == len(its_field_check),
337 "Fields in Image Tree Source File %s did not match, error in finding %s"
338 % (fitimage_its_path, its_field_check[field_index]))
339
Andrew Geisslerc182c622020-05-15 14:13:32 -0500340 def test_image_gen_debugfs(self):
341 """
342 Summary: Check debugfs generation
343 Expected: 1. core-image-minimal can be build with IMAGE_GEN_DEBUGFS variable set
344 2. debug filesystem is created when variable set
345 3. debug symbols available
346 Product: oe-core
347 Author: Humberto Ibarra <humberto.ibarra.lopez@intel.com>
348 Yeoh Ee Peng <ee.peng.yeoh@intel.com>
349 """
350 import glob
351 image_name = 'core-image-minimal'
352 features = 'IMAGE_GEN_DEBUGFS = "1"\n'
353 features += 'IMAGE_FSTYPES_DEBUGFS = "tar.bz2"\n'
354 features += 'MACHINE = "genericx86-64"\n'
355 self.write_config(features)
356
357 bitbake(image_name)
358 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
359 dbg_tar_file = os.path.join(deploy_dir_image, "*-dbg.rootfs.tar.bz2")
360 debug_files = glob.glob(dbg_tar_file)
361 self.assertNotEqual(len(debug_files), 0, 'debug filesystem not generated at %s' % dbg_tar_file)
362 result = runCmd('cd %s; tar xvf %s' % (deploy_dir_image, dbg_tar_file))
363 self.assertEqual(result.status, 0, msg='Failed to extract %s: %s' % (dbg_tar_file, result.output))
364 result = runCmd('find %s -name %s' % (deploy_dir_image, "udevadm"))
365 self.assertTrue("udevadm" in result.output, msg='Failed to find udevadm: %s' % result.output)
366 dbg_symbols_targets = result.output.splitlines()
367 self.assertTrue(dbg_symbols_targets, msg='Failed to split udevadm: %s' % dbg_symbols_targets)
368 for t in dbg_symbols_targets:
369 result = runCmd('objdump --syms %s | grep debug' % t)
370 self.assertTrue("debug" in result.output, msg='Failed to find debug symbol: %s' % result.output)