xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oeqa/selftest/cases/distrodata.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1#
2# SPDX-License-Identifier: MIT
3#
4
5from oeqa.selftest.case import OESelftestTestCase
6
7import oe.recipeutils
8
9class Distrodata(OESelftestTestCase):
10
11    def test_checkpkg(self):
12        """
13        Summary:     Test that upstream version checks do not regress
14        Expected:    Upstream version checks should succeed except for the recipes listed in the exception list.
15        Product:     oe-core
16        Author:      Alexander Kanavin <alex.kanavin@gmail.com>
17        """
18        feature = 'LICENSE_FLAGS_ACCEPTED += " commercial"\n'
19        self.write_config(feature)
20
21        pkgs = oe.recipeutils.get_recipe_upgrade_status()
22
23        regressed_failures = [pkg[0] for pkg in pkgs if pkg[1] == 'UNKNOWN_BROKEN']
24        regressed_successes = [pkg[0] for pkg in pkgs if pkg[1] == 'KNOWN_BROKEN']
25        msg = ""
26        if len(regressed_failures) > 0:
27            msg = msg + """
28The following packages failed upstream version checks. Please fix them using UPSTREAM_CHECK_URI/UPSTREAM_CHECK_REGEX
29(when using tarballs) or UPSTREAM_CHECK_GITTAGREGEX (when using git). If an upstream version check cannot be performed
30(for example, if upstream does not use git tags), you can set UPSTREAM_VERSION_UNKNOWN to '1' in the recipe to acknowledge
31that the check cannot be performed.
32""" + "\n".join(regressed_failures)
33        if len(regressed_successes) > 0:
34            msg = msg + """
35The following packages have been checked successfully for upstream versions,
36but their recipes claim otherwise by setting UPSTREAM_VERSION_UNKNOWN. Please remove that line from the recipes.
37""" + "\n".join(regressed_successes)
38        self.assertTrue(len(regressed_failures) == 0 and len(regressed_successes) == 0, msg)
39
40    def test_missing_homepg(self):
41        """
42        Summary:     Test for oe-core recipes that don't have a HOMEPAGE or DESCRIPTION
43        Expected:    All oe-core recipes should have a DESCRIPTION entry
44        Expected:    All oe-core recipes should have a HOMEPAGE entry except for recipes that are not fetched from external sources.
45        Product:     oe-core
46        """
47        with bb.tinfoil.Tinfoil() as tinfoil:
48            tinfoil.prepare(config_only=False)
49            no_description = []
50            no_homepage = []
51            for fn in tinfoil.all_recipe_files(variants=False):
52                if not '/meta/recipes-' in fn:
53                    # We are only interested in OE-Core
54                    continue
55                rd = tinfoil.parse_recipe_file(fn, appends=False)
56                pn = rd.getVar('BPN')
57                srcfile = rd.getVar('SRC_URI').split()
58                #Since DESCRIPTION defaults to SUMMARY if not set, we are only interested in recipes without DESCRIPTION or SUMMARY
59                if not (rd.getVar('SUMMARY') or rd.getVar('DESCRIPTION')):
60                    no_description.append((pn, fn))
61                if not rd.getVar('HOMEPAGE'):
62                    if srcfile and srcfile[0].startswith('file') or not rd.getVar('SRC_URI'):
63                        # We are only interested in recipes SRC_URI fetched from external sources
64                        continue
65                    no_homepage.append((pn, fn))
66        if no_homepage:
67            self.fail("""
68The following recipes do not have a HOMEPAGE. Please add an entry for HOMEPAGE in the recipe.
69""" + "\n".join(['%s (%s)' % i for i in no_homepage]))
70
71        if no_description:
72            self.fail("""
73The following recipes do not have a DESCRIPTION. Please add an entry for DESCRIPTION in the recipe.
74""" + "\n".join(['%s (%s)' % i for i in no_description]))
75
76    def test_maintainers(self):
77        """
78        Summary:     Test that oe-core recipes have a maintainer and entries in maintainers list have a recipe
79        Expected:    All oe-core recipes (except a few special static/testing ones) should have a maintainer listed in maintainers.inc file.
80        Expected:    All entries in maintainers list should have a recipe file that matches them
81        Product:     oe-core
82        Author:      Alexander Kanavin <alex.kanavin@gmail.com>
83        """
84        def is_exception(pkg):
85            exceptions = ["packagegroup-", "initramfs-", "systemd-machine-units", "target-sdk-provides-dummy"]
86            for i in exceptions:
87                 if i in pkg:
88                     return True
89            return False
90
91        def is_maintainer_exception(entry):
92            exceptions = ["musl", "newlib", "linux-yocto", "linux-dummy", "mesa-gl", "libgfortran",
93                          "cve-update-db-native", "rust"]
94            for i in exceptions:
95                 if i in entry:
96                     return True
97            return False
98
99        feature = 'require conf/distro/include/maintainers.inc\nLICENSE_FLAGS_ACCEPTED += " commercial"\nPARSE_ALL_RECIPES = "1"\nPACKAGE_CLASSES = "package_ipk package_deb package_rpm"\n'
100        self.write_config(feature)
101
102        with bb.tinfoil.Tinfoil() as tinfoil:
103            tinfoil.prepare(config_only=False)
104
105            with_maintainer_list = []
106            no_maintainer_list = []
107
108            missing_recipes = []
109            recipes = []
110            prefix = "RECIPE_MAINTAINER:pn-"
111
112            # We could have used all_recipes() here, but this method will find
113            # every recipe if we ever move to setting RECIPE_MAINTAINER in recipe files
114            # instead of maintainers.inc
115            for fn in tinfoil.all_recipe_files(variants=False):
116                if not '/meta/recipes-' in fn:
117                    # We are only interested in OE-Core
118                    continue
119                rd = tinfoil.parse_recipe_file(fn, appends=False)
120                pn = rd.getVar('PN')
121                recipes.append(pn)
122                if is_exception(pn):
123                    continue
124                if rd.getVar('RECIPE_MAINTAINER'):
125                    with_maintainer_list.append((pn, fn))
126                else:
127                    no_maintainer_list.append((pn, fn))
128
129            maintainers = tinfoil.config_data.keys()
130            for key in maintainers:
131                 if key.startswith(prefix):
132                     recipe = tinfoil.config_data.expand(key[len(prefix):])
133                     if is_maintainer_exception(recipe):
134                         continue
135                     if recipe not in recipes:
136                         missing_recipes.append(recipe)
137
138        if no_maintainer_list:
139            self.fail("""
140The following recipes do not have a maintainer assigned to them. Please add an entry to meta/conf/distro/include/maintainers.inc file.
141""" + "\n".join(['%s (%s)' % i for i in no_maintainer_list]))
142
143        if not with_maintainer_list:
144            self.fail("""
145The list of oe-core recipes with maintainers is empty. This may indicate that the test has regressed and needs fixing.
146""")
147
148        if missing_recipes:
149                self.fail("""
150Unable to find recipes for the following entries in maintainers.inc:
151""" + "\n".join(['%s' % i for i in missing_recipes]))
152