poky/scripts/lib/checklayer/cases/common.py
Richard Purdie 7458ad340f yocto-check-layer: Allow OE-Core to be tested
For unknown reasons we've never seemingly run the check layer script
against OE-Core itself. This isn't entirely straightforward as the core
layer is a bit of a special case, we can't for example compare signatures
against ourselve and we can't remove core from bblayers.conf.

Core does have distro, machine and software components too, in the case
of distro, our fallback default settings. Whilst the qemu machines could
be split into a seperate layer directory, core wouldn't then parse at all
standalone due to the lack of any machine so it seems a bit pointless to
do that.

These changes tweak the script to handle core's special cases, specifically
to allow distro and machine directories and to account for the README placed
a directory level higher than other layers.

(From OE-Core rev: ba312ed228507d05f280aeb96819d671b01400b8)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2022-12-09 13:18:41 +00:00

90 lines
3.8 KiB
Python

# Copyright (C) 2017 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
import glob
import os
import unittest
import re
from checklayer import get_signatures, LayerType, check_command, get_depgraph, compare_signatures
from checklayer.case import OECheckLayerTestCase
class CommonCheckLayer(OECheckLayerTestCase):
def test_readme(self):
if self.tc.layer['type'] == LayerType.CORE:
raise unittest.SkipTest("Core layer's README is top level")
# The top-level README file may have a suffix (like README.rst or README.txt).
readme_files = glob.glob(os.path.join(self.tc.layer['path'], '[Rr][Ee][Aa][Dd][Mm][Ee]*'))
self.assertTrue(len(readme_files) > 0,
msg="Layer doesn't contain a README file.")
# There might be more than one file matching the file pattern above
# (for example, README.rst and README-COPYING.rst). The one with the shortest
# name is considered the "main" one.
readme_file = sorted(readme_files)[0]
data = ''
with open(readme_file, 'r') as f:
data = f.read()
self.assertTrue(data,
msg="Layer contains a README file but it is empty.")
# If a layer's README references another README, then the checks below are not valid
if re.search('README', data, re.IGNORECASE):
return
self.assertIn('maintainer', data.lower())
self.assertIn('patch', data.lower())
# Check that there is an email address in the README
email_regex = re.compile(r"[^@]+@[^@]+")
self.assertTrue(email_regex.match(data))
def test_parse(self):
check_command('Layer %s failed to parse.' % self.tc.layer['name'],
'bitbake -p')
def test_show_environment(self):
check_command('Layer %s failed to show environment.' % self.tc.layer['name'],
'bitbake -e')
def test_world(self):
'''
"bitbake world" is expected to work. test_signatures does not cover that
because it is more lenient and ignores recipes in a world build that
are not actually buildable, so here we fail when "bitbake -S none world"
fails.
'''
get_signatures(self.td['builddir'], failsafe=False)
def test_world_inherit_class(self):
'''
This also does "bitbake -S none world" along with inheriting "yocto-check-layer"
class, which can do additional per-recipe test cases.
'''
msg = []
try:
get_signatures(self.td['builddir'], failsafe=False, machine=None, extravars='BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS INHERIT" INHERIT="yocto-check-layer"')
except RuntimeError as ex:
msg.append(str(ex))
if msg:
msg.insert(0, 'Layer %s failed additional checks from yocto-check-layer.bbclass\nSee below log for specific recipe parsing errors:\n' % \
self.tc.layer['name'])
self.fail('\n'.join(msg))
def test_signatures(self):
if self.tc.layer['type'] == LayerType.SOFTWARE and \
not self.tc.test_software_layer_signatures:
raise unittest.SkipTest("Not testing for signature changes in a software layer %s." \
% self.tc.layer['name'])
curr_sigs, _ = get_signatures(self.td['builddir'], failsafe=True)
msg = compare_signatures(self.td['sigs'], curr_sigs)
if msg is not None:
self.fail('Adding layer %s changed signatures.\n%s' % (self.tc.layer['name'], msg))
def test_layerseries_compat(self):
for collection_name, collection_data in self.tc.layer['collections'].items():
self.assertTrue(collection_data['compat'], "Collection %s from layer %s does not set compatible oe-core versions via LAYERSERIES_COMPAT_collection." \
% (collection_name, self.tc.layer['name']))