xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oeqa/selftest/cases/buildoptions.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# SPDX-License-Identifier: MIT
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun
5*4882a593Smuzhiyunimport os
6*4882a593Smuzhiyunimport re
7*4882a593Smuzhiyunimport glob as g
8*4882a593Smuzhiyunimport shutil
9*4882a593Smuzhiyunimport tempfile
10*4882a593Smuzhiyunfrom oeqa.selftest.case import OESelftestTestCase
11*4882a593Smuzhiyunfrom oeqa.selftest.cases.buildhistory import BuildhistoryBase
12*4882a593Smuzhiyunfrom oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars
13*4882a593Smuzhiyunimport oeqa.utils.ftools as ftools
14*4882a593Smuzhiyun
15*4882a593Smuzhiyunclass ImageOptionsTests(OESelftestTestCase):
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun    def test_incremental_image_generation(self):
18*4882a593Smuzhiyun        image_pkgtype = get_bb_var("IMAGE_PKGTYPE")
19*4882a593Smuzhiyun        if image_pkgtype != 'rpm':
20*4882a593Smuzhiyun            self.skipTest('Not using RPM as main package format')
21*4882a593Smuzhiyun        bitbake("-c clean core-image-minimal")
22*4882a593Smuzhiyun        self.write_config('INC_RPM_IMAGE_GEN = "1"')
23*4882a593Smuzhiyun        self.append_config('IMAGE_FEATURES += "ssh-server-openssh"')
24*4882a593Smuzhiyun        bitbake("core-image-minimal")
25*4882a593Smuzhiyun        log_data_file = os.path.join(get_bb_var("WORKDIR", "core-image-minimal"), "temp/log.do_rootfs")
26*4882a593Smuzhiyun        log_data_created = ftools.read_file(log_data_file)
27*4882a593Smuzhiyun        incremental_created = re.search(r"Installing\s*:\s*packagegroup-core-ssh-openssh", log_data_created)
28*4882a593Smuzhiyun        self.remove_config('IMAGE_FEATURES += "ssh-server-openssh"')
29*4882a593Smuzhiyun        self.assertTrue(incremental_created, msg = "Match failed in:\n%s" % log_data_created)
30*4882a593Smuzhiyun        bitbake("core-image-minimal")
31*4882a593Smuzhiyun        log_data_removed = ftools.read_file(log_data_file)
32*4882a593Smuzhiyun        incremental_removed = re.search(r"Erasing\s*:\s*packagegroup-core-ssh-openssh", log_data_removed)
33*4882a593Smuzhiyun        self.assertTrue(incremental_removed, msg = "Match failed in:\n%s" % log_data_removed)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun    def test_ccache_tool(self):
36*4882a593Smuzhiyun        bitbake("ccache-native")
37*4882a593Smuzhiyun        bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'ccache-native')
38*4882a593Smuzhiyun        p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "ccache"
39*4882a593Smuzhiyun        self.assertTrue(os.path.isfile(p), msg = "No ccache found (%s)" % p)
40*4882a593Smuzhiyun        self.write_config('INHERIT += "ccache"')
41*4882a593Smuzhiyun        recipe = "libgcc-initial"
42*4882a593Smuzhiyun        self.add_command_to_tearDown('bitbake -c clean %s' % recipe)
43*4882a593Smuzhiyun        bitbake("%s -c clean" % recipe)
44*4882a593Smuzhiyun        bitbake("%s -f -c compile" % recipe)
45*4882a593Smuzhiyun        log_compile = os.path.join(get_bb_var("WORKDIR", recipe), "temp/log.do_compile")
46*4882a593Smuzhiyun        with open(log_compile, "r") as f:
47*4882a593Smuzhiyun            loglines = "".join(f.readlines())
48*4882a593Smuzhiyun        self.assertIn("ccache", loglines, msg="No match for ccache in %s log.do_compile. For further details: %s" % (recipe , log_compile))
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun    def test_read_only_image(self):
51*4882a593Smuzhiyun        distro_features = get_bb_var('DISTRO_FEATURES')
52*4882a593Smuzhiyun        if not ('x11' in distro_features and 'opengl' in distro_features):
53*4882a593Smuzhiyun            self.skipTest('core-image-sato/weston requires x11 and opengl in distro features')
54*4882a593Smuzhiyun        self.write_config('IMAGE_FEATURES += "read-only-rootfs"')
55*4882a593Smuzhiyun        bitbake("core-image-sato core-image-weston")
56*4882a593Smuzhiyun        # do_image will fail if there are any pending postinsts
57*4882a593Smuzhiyun
58*4882a593Smuzhiyunclass DiskMonTest(OESelftestTestCase):
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun    def test_stoptask_behavior(self):
61*4882a593Smuzhiyun        self.write_config('BB_DISKMON_DIRS = "STOPTASKS,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"')
62*4882a593Smuzhiyun        res = bitbake("delay -c delay", ignore_status = True)
63*4882a593Smuzhiyun        self.assertTrue('ERROR: No new tasks can be executed since the disk space monitor action is "STOPTASKS"!' in res.output, msg = "Tasks should have stopped. Disk monitor is set to STOPTASK: %s" % res.output)
64*4882a593Smuzhiyun        self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output))
65*4882a593Smuzhiyun        self.write_config('BB_DISKMON_DIRS = "HALT,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"')
66*4882a593Smuzhiyun        res = bitbake("delay -c delay", ignore_status = True)
67*4882a593Smuzhiyun        self.assertTrue('ERROR: Immediately halt since the disk space monitor action is "HALT"!' in res.output, "Tasks should have been halted immediately. Disk monitor is set to HALT: %s" % res.output)
68*4882a593Smuzhiyun        self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output))
69*4882a593Smuzhiyun        self.write_config('BB_DISKMON_DIRS = "WARN,${TMPDIR},100000G,100K"\nBB_HEARTBEAT_EVENT = "1"')
70*4882a593Smuzhiyun        res = bitbake("delay -c delay")
71*4882a593Smuzhiyun        self.assertTrue('WARNING: The free space' in res.output, msg = "A warning should have been displayed for disk monitor is set to WARN: %s" %res.output)
72*4882a593Smuzhiyun
73*4882a593Smuzhiyunclass SanityOptionsTest(OESelftestTestCase):
74*4882a593Smuzhiyun    def getline(self, res, line):
75*4882a593Smuzhiyun        for l in res.output.split('\n'):
76*4882a593Smuzhiyun            if line in l:
77*4882a593Smuzhiyun                return l
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun    def test_options_warnqa_errorqa_switch(self):
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun        self.write_config("INHERIT:remove = \"report-error\"")
82*4882a593Smuzhiyun        if "packages-list" not in get_bb_var("ERROR_QA"):
83*4882a593Smuzhiyun            self.append_config("ERROR_QA:append = \" packages-list\"")
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun        self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"')
86*4882a593Smuzhiyun        self.add_command_to_tearDown('bitbake -c clean xcursor-transparent-theme')
87*4882a593Smuzhiyun        res = bitbake("xcursor-transparent-theme -f -c package", ignore_status=True)
88*4882a593Smuzhiyun        self.delete_recipeinc('xcursor-transparent-theme')
89*4882a593Smuzhiyun        line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.")
90*4882a593Smuzhiyun        self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
91*4882a593Smuzhiyun        self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output))
92*4882a593Smuzhiyun        self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"')
93*4882a593Smuzhiyun        self.append_config('ERROR_QA:remove = "packages-list"')
94*4882a593Smuzhiyun        self.append_config('WARN_QA:append = " packages-list"')
95*4882a593Smuzhiyun        res = bitbake("xcursor-transparent-theme -f -c package")
96*4882a593Smuzhiyun        self.delete_recipeinc('xcursor-transparent-theme')
97*4882a593Smuzhiyun        line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.")
98*4882a593Smuzhiyun        self.assertTrue(line and line.startswith("WARNING:"), msg=res.output)
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun    def test_layer_without_git_dir(self):
101*4882a593Smuzhiyun        """
102*4882a593Smuzhiyun        Summary:     Test that layer git revisions are displayed and do not fail without git repository
103*4882a593Smuzhiyun        Expected:    The build to be successful and without "fatal" errors
104*4882a593Smuzhiyun        Product:     oe-core
105*4882a593Smuzhiyun        Author:      Daniel Istrate <daniel.alexandrux.istrate@intel.com>
106*4882a593Smuzhiyun        AutomatedBy: Daniel Istrate <daniel.alexandrux.istrate@intel.com>
107*4882a593Smuzhiyun        """
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun        dirpath = tempfile.mkdtemp()
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun        dummy_layer_name = 'meta-dummy'
112*4882a593Smuzhiyun        dummy_layer_path = os.path.join(dirpath, dummy_layer_name)
113*4882a593Smuzhiyun        dummy_layer_conf_dir = os.path.join(dummy_layer_path, 'conf')
114*4882a593Smuzhiyun        os.makedirs(dummy_layer_conf_dir)
115*4882a593Smuzhiyun        dummy_layer_conf_path = os.path.join(dummy_layer_conf_dir, 'layer.conf')
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun        dummy_layer_content = 'BBPATH .= ":${LAYERDIR}"\n' \
118*4882a593Smuzhiyun                              'BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"\n' \
119*4882a593Smuzhiyun                              'BBFILE_COLLECTIONS += "%s"\n' \
120*4882a593Smuzhiyun                              'BBFILE_PATTERN_%s = "^${LAYERDIR}/"\n' \
121*4882a593Smuzhiyun                              'BBFILE_PRIORITY_%s = "6"\n' % (dummy_layer_name, dummy_layer_name, dummy_layer_name)
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun        ftools.write_file(dummy_layer_conf_path, dummy_layer_content)
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun        bblayers_conf = 'BBLAYERS += "%s"\n' % dummy_layer_path
126*4882a593Smuzhiyun        self.write_bblayers_config(bblayers_conf)
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun        test_recipe = 'ed'
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun        ret = bitbake('-n %s' % test_recipe)
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun        err = 'fatal: Not a git repository'
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun        shutil.rmtree(dirpath)
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun        self.assertNotIn(err, ret.output)
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun
139*4882a593Smuzhiyunclass BuildhistoryTests(BuildhistoryBase):
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun    def test_buildhistory_basic(self):
142*4882a593Smuzhiyun        self.run_buildhistory_operation('xcursor-transparent-theme')
143*4882a593Smuzhiyun        self.assertTrue(os.path.isdir(get_bb_var('BUILDHISTORY_DIR')), "buildhistory dir was not created.")
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun    def test_buildhistory_buildtime_pr_backwards(self):
146*4882a593Smuzhiyun        target = 'xcursor-transparent-theme'
147*4882a593Smuzhiyun        error = "ERROR:.*QA Issue: Package version for package %s went backwards which would break package feeds \(from .*-r1.* to .*-r0.*\)" % target
148*4882a593Smuzhiyun        self.run_buildhistory_operation(target, target_config="PR = \"r1\"", change_bh_location=True)
149*4882a593Smuzhiyun        self.run_buildhistory_operation(target, target_config="PR = \"r0\"", change_bh_location=False, expect_error=True, error_regex=error)
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun    def test_fileinfo(self):
152*4882a593Smuzhiyun        self.config_buildhistory()
153*4882a593Smuzhiyun        bitbake('hicolor-icon-theme')
154*4882a593Smuzhiyun        history_dir = get_bb_var('BUILDHISTORY_DIR_PACKAGE', 'hicolor-icon-theme')
155*4882a593Smuzhiyun        self.assertTrue(os.path.isdir(history_dir), 'buildhistory dir was not created.')
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun        def load_bh(f):
158*4882a593Smuzhiyun            d = {}
159*4882a593Smuzhiyun            for line in open(f):
160*4882a593Smuzhiyun                split = [s.strip() for s in line.split('=', 1)]
161*4882a593Smuzhiyun                if len(split) > 1:
162*4882a593Smuzhiyun                    d[split[0]] = split[1]
163*4882a593Smuzhiyun            return d
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun        data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme', 'latest'))
166*4882a593Smuzhiyun        self.assertIn('FILELIST', data)
167*4882a593Smuzhiyun        self.assertEqual(data['FILELIST'], '/usr/share/icons/hicolor/index.theme')
168*4882a593Smuzhiyun        self.assertGreater(int(data['PKGSIZE']), 0)
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun        data = load_bh(os.path.join(history_dir, 'hicolor-icon-theme-dev', 'latest'))
171*4882a593Smuzhiyun        if 'FILELIST' in data:
172*4882a593Smuzhiyun            self.assertEqual(data['FILELIST'], '')
173*4882a593Smuzhiyun        self.assertEqual(int(data['PKGSIZE']), 0)
174*4882a593Smuzhiyun
175*4882a593Smuzhiyunclass ArchiverTest(OESelftestTestCase):
176*4882a593Smuzhiyun    def test_arch_work_dir_and_export_source(self):
177*4882a593Smuzhiyun        """
178*4882a593Smuzhiyun        Test for archiving the work directory and exporting the source files.
179*4882a593Smuzhiyun        """
180*4882a593Smuzhiyun        self.write_config("""
181*4882a593SmuzhiyunINHERIT += "archiver"
182*4882a593SmuzhiyunPACKAGE_CLASSES = "package_rpm"
183*4882a593SmuzhiyunARCHIVER_MODE[src] = "original"
184*4882a593SmuzhiyunARCHIVER_MODE[srpm] = "1"
185*4882a593Smuzhiyun""")
186*4882a593Smuzhiyun        res = bitbake("xcursor-transparent-theme", ignore_status=True)
187*4882a593Smuzhiyun        self.assertEqual(res.status, 0, "\nCouldn't build xcursortransparenttheme.\nbitbake output %s" % res.output)
188*4882a593Smuzhiyun        deploy_dir_src = get_bb_var('DEPLOY_DIR_SRC')
189*4882a593Smuzhiyun        pkgs_path = g.glob(str(deploy_dir_src) + "/allarch*/xcurs*")
190*4882a593Smuzhiyun        src_file_glob = str(pkgs_path[0]) + "/xcursor*.src.rpm"
191*4882a593Smuzhiyun        tar_file_glob = str(pkgs_path[0]) + "/xcursor*.tar.xz"
192*4882a593Smuzhiyun        self.assertTrue((g.glob(src_file_glob) and g.glob(tar_file_glob)), "Couldn't find .src.rpm and .tar.xz files under %s/allarch*/xcursor*" % deploy_dir_src)
193*4882a593Smuzhiyun
194*4882a593Smuzhiyunclass ToolchainOptions(OESelftestTestCase):
195*4882a593Smuzhiyun    def test_toolchain_fortran(self):
196*4882a593Smuzhiyun        """
197*4882a593Smuzhiyun        Test that Fortran works by building a Hello, World binary.
198*4882a593Smuzhiyun        """
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun        features = 'FORTRAN:forcevariable = ",fortran"\n'
201*4882a593Smuzhiyun        self.write_config(features)
202*4882a593Smuzhiyun        bitbake('fortran-helloworld')
203*4882a593Smuzhiyun
204*4882a593Smuzhiyunclass SourceMirroring(OESelftestTestCase):
205*4882a593Smuzhiyun    # Can we download everything from the Yocto Sources Mirror over http only
206*4882a593Smuzhiyun    def test_yocto_source_mirror(self):
207*4882a593Smuzhiyun        self.write_config("""
208*4882a593SmuzhiyunBB_ALLOWED_NETWORKS = "downloads.yoctoproject.org"
209*4882a593SmuzhiyunMIRRORS = ""
210*4882a593SmuzhiyunDL_DIR = "${TMPDIR}/test_downloads"
211*4882a593SmuzhiyunSTAMPS_DIR = "${TMPDIR}/test_stamps"
212*4882a593SmuzhiyunSSTATE_DIR = "${TMPDIR}/test_sstate-cache"
213*4882a593SmuzhiyunPREMIRRORS = "\\
214*4882a593Smuzhiyun    bzr://.*/.*   http://downloads.yoctoproject.org/mirror/sources/ \\n \\
215*4882a593Smuzhiyun    cvs://.*/.*   http://downloads.yoctoproject.org/mirror/sources/ \\n \\
216*4882a593Smuzhiyun    git://.*/.*   http://downloads.yoctoproject.org/mirror/sources/ \\n \\
217*4882a593Smuzhiyun    gitsm://.*/.* http://downloads.yoctoproject.org/mirror/sources/ \\n \\
218*4882a593Smuzhiyun    hg://.*/.*    http://downloads.yoctoproject.org/mirror/sources/ \\n \\
219*4882a593Smuzhiyun    osc://.*/.*   http://downloads.yoctoproject.org/mirror/sources/ \\n \\
220*4882a593Smuzhiyun    p4://.*/.*    http://downloads.yoctoproject.org/mirror/sources/ \\n \\
221*4882a593Smuzhiyun    svn://.*/.*   http://downloads.yoctoproject.org/mirror/sources/ \\n \\
222*4882a593Smuzhiyun    ftp://.*/.*      http://downloads.yoctoproject.org/mirror/sources/ \\n \\
223*4882a593Smuzhiyun    http://.*/.*     http://downloads.yoctoproject.org/mirror/sources/ \\n \\
224*4882a593Smuzhiyun    https://.*/.*    http://downloads.yoctoproject.org/mirror/sources/ \\n"
225*4882a593Smuzhiyun""")
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun        bitbake("world --runall fetch")
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun
230*4882a593Smuzhiyunclass Poisoning(OESelftestTestCase):
231*4882a593Smuzhiyun    def test_poisoning(self):
232*4882a593Smuzhiyun        res = bitbake("poison", ignore_status=True)
233*4882a593Smuzhiyun        self.assertNotEqual(res.status, 0)
234*4882a593Smuzhiyun        self.assertTrue("is unsafe for cross-compilation" in res.output)
235