1#
2# SPDX-License-Identifier: MIT
3#
4
5import os
6
7from oeqa.selftest.case import OESelftestTestCase
8from oeqa.utils.commands import get_bb_var, get_bb_vars, bitbake
9
10class ManifestEntry:
11    '''A manifest item of a collection able to list missing packages'''
12    def __init__(self, entry):
13        self.file = entry
14        self.missing = []
15
16class VerifyManifest(OESelftestTestCase):
17    '''Tests for the manifest files and contents of an image'''
18
19    @classmethod
20    def check_manifest_entries(self, manifest, path):
21        manifest_errors = []
22        try:
23            with open(manifest, "r") as mfile:
24                for line in mfile:
25                    manifest_entry = os.path.join(path, line.split()[0])
26                    self.logger.debug("{}: looking for {}"\
27                                    .format(self.classname, manifest_entry))
28                    if not os.path.isfile(manifest_entry):
29                        manifest_errors.append(manifest_entry)
30                        self.logger.debug("{}: {} not found"\
31                                    .format(self.classname, manifest_entry))
32        except OSError as e:
33            self.logger.debug("{}: checking of {} failed"\
34                    .format(self.classname, manifest))
35            raise e
36
37        return manifest_errors
38
39    #this will possibly move from here
40    @classmethod
41    def get_dir_from_bb_var(self, bb_var, target = None):
42        target == self.buildtarget if target == None else target
43        directory = get_bb_var(bb_var, target);
44        if not directory or not os.path.isdir(directory):
45            self.logger.debug("{}: {} points to {} when target = {}"\
46                    .format(self.classname, bb_var, directory, target))
47            raise OSError
48        return directory
49
50    @classmethod
51    def setUpClass(self):
52
53        super(VerifyManifest, self).setUpClass()
54        self.buildtarget = 'core-image-minimal'
55        self.classname = 'VerifyManifest'
56
57        self.logger.info("{}: doing bitbake {} as a prerequisite of the test"\
58                .format(self.classname, self.buildtarget))
59        if bitbake(self.buildtarget).status:
60            self.logger.debug("{} Failed to setup {}"\
61                    .format(self.classname, self.buildtarget))
62            self.skipTest("{}: Cannot setup testing scenario"\
63                    .format(self.classname))
64
65    def test_SDK_manifest_entries(self):
66        '''Verifying the SDK manifest entries exist, this may take a build'''
67
68        # the setup should bitbake core-image-minimal and here it is required
69        # to do an additional setup for the sdk
70        sdktask = '-c populate_sdk'
71        bbargs = sdktask + ' ' + self.buildtarget
72        self.logger.debug("{}: doing bitbake {} as a prerequisite of the test"\
73                .format(self.classname, bbargs))
74        if bitbake(bbargs).status:
75            self.logger.debug("{} Failed to bitbake {}"\
76                    .format(self.classname, bbargs))
77            self.skipTest("{}: Cannot setup testing scenario"\
78                    .format(self.classname))
79
80
81        pkgdata_dir = reverse_dir = {}
82        mfilename = mpath = m_entry = {}
83        # get manifest location based on target to query about
84        d_target= dict(target = self.buildtarget,
85                         host = 'nativesdk-packagegroup-sdk-host')
86        try:
87            mdir = self.get_dir_from_bb_var('SDK_DEPLOY', self.buildtarget)
88            for k in d_target.keys():
89                toolchain_outputname = get_bb_var('TOOLCHAIN_OUTPUTNAME', self.buildtarget)
90                mfilename[k] = "{}.{}.manifest".format(toolchain_outputname, k)
91                mpath[k] = os.path.join(mdir, mfilename[k])
92                if not os.path.isfile(mpath[k]):
93                    self.logger.debug("{}: {} does not exist".format(
94                        self.classname, mpath[k]))
95                    raise IOError
96                m_entry[k] = ManifestEntry(mpath[k])
97
98                pkgdata_dir[k] = self.get_dir_from_bb_var('PKGDATA_DIR',
99                        d_target[k])
100                reverse_dir[k] = os.path.join(pkgdata_dir[k],
101                        'runtime-reverse')
102                if not os.path.exists(reverse_dir[k]):
103                    self.logger.debug("{}: {} does not exist".format(
104                        self.classname, reverse_dir[k]))
105                    raise IOError
106        except OSError:
107            raise self.skipTest("{}: Error in obtaining manifest dirs"\
108                .format(self.classname))
109        except IOError:
110            msg = "{}: Error cannot find manifests in the specified dir:\n{}"\
111                    .format(self.classname, mdir)
112            self.fail(msg)
113
114        for k in d_target.keys():
115            self.logger.debug("{}: Check manifest {}".format(
116                self.classname, m_entry[k].file))
117
118            m_entry[k].missing = self.check_manifest_entries(\
119                                               m_entry[k].file,reverse_dir[k])
120            if m_entry[k].missing:
121                msg = '{}: {} Error has the following missing entries'\
122                        .format(self.classname, m_entry[k].file)
123                logmsg = msg+':\n'+'\n'.join(m_entry[k].missing)
124                self.logger.debug(logmsg)
125                self.logger.info(msg)
126                self.fail(logmsg)
127
128    def test_image_manifest_entries(self):
129        '''Verifying the image manifest entries exist'''
130
131        # get manifest location based on target to query about
132        try:
133            mdir = self.get_dir_from_bb_var('DEPLOY_DIR_IMAGE',
134                                                self.buildtarget)
135            mfilename = get_bb_var("IMAGE_LINK_NAME", self.buildtarget)\
136                    + ".manifest"
137            mpath = os.path.join(mdir, mfilename)
138            if not os.path.isfile(mpath): raise IOError
139            m_entry = ManifestEntry(mpath)
140
141            pkgdata_dir = {}
142            pkgdata_dir = self.get_dir_from_bb_var('PKGDATA_DIR',
143                                                self.buildtarget)
144            revdir = os.path.join(pkgdata_dir, 'runtime-reverse')
145            if not os.path.exists(revdir): raise IOError
146        except OSError:
147            raise self.skipTest("{}: Error in obtaining manifest dirs"\
148                .format(self.classname))
149        except IOError:
150            msg = "{}: Error cannot find manifests in dir:\n{}"\
151                    .format(self.classname, mdir)
152            self.fail(msg)
153
154        self.logger.debug("{}: Check manifest {}"\
155                            .format(self.classname, m_entry.file))
156        m_entry.missing = self.check_manifest_entries(\
157                                                    m_entry.file, revdir)
158        if m_entry.missing:
159            msg = '{}: {} Error has the following missing entries'\
160                    .format(self.classname, m_entry.file)
161            logmsg = msg+':\n'+'\n'.join(m_entry.missing)
162            self.logger.debug(logmsg)
163            self.logger.info(msg)
164            self.fail(logmsg)
165