1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7import os
8import tempfile
9import fnmatch
10
11from oeqa.selftest.case import OESelftestTestCase
12from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars
13
14class OePkgdataUtilTests(OESelftestTestCase):
15
16    @classmethod
17    def setUpClass(cls):
18        super(OePkgdataUtilTests, cls).setUpClass()
19        # Ensure we have the right data in pkgdata
20        cls.logger.info('Running bitbake to generate pkgdata')
21        bitbake('target-sdk-provides-dummy -c clean')
22        bitbake('busybox zlib m4')
23
24    def test_lookup_pkg(self):
25        # Forward tests
26        result = runCmd('oe-pkgdata-util lookup-pkg "zlib busybox"')
27        self.assertEqual(result.output, 'libz1\nbusybox')
28        result = runCmd('oe-pkgdata-util lookup-pkg zlib-dev')
29        self.assertEqual(result.output, 'libz-dev')
30        result = runCmd('oe-pkgdata-util lookup-pkg nonexistentpkg', ignore_status=True)
31        self.assertEqual(result.status, 1, "Status different than 1. output: %s" % result.output)
32        self.assertEqual(result.output, 'ERROR: The following packages could not be found: nonexistentpkg')
33        # Reverse tests
34        result = runCmd('oe-pkgdata-util lookup-pkg -r "libz1 busybox"')
35        self.assertEqual(result.output, 'zlib\nbusybox')
36        result = runCmd('oe-pkgdata-util lookup-pkg -r libz-dev')
37        self.assertEqual(result.output, 'zlib-dev')
38        result = runCmd('oe-pkgdata-util lookup-pkg -r nonexistentpkg', ignore_status=True)
39        self.assertEqual(result.status, 1, "Status different than 1. output: %s" % result.output)
40        self.assertEqual(result.output, 'ERROR: The following packages could not be found: nonexistentpkg')
41
42    def test_read_value(self):
43        result = runCmd('oe-pkgdata-util read-value PN libz1')
44        self.assertEqual(result.output, 'zlib')
45        result = runCmd('oe-pkgdata-util read-value PKG libz1')
46        self.assertEqual(result.output, 'libz1')
47        result = runCmd('oe-pkgdata-util read-value PKGSIZE m4')
48        pkgsize = int(result.output.strip())
49        self.assertGreater(pkgsize, 1, "Size should be greater than 1. %s" % result.output)
50
51    def test_find_path(self):
52        result = runCmd('oe-pkgdata-util find-path /usr/lib/libz.so.1')
53        self.assertEqual(result.output, 'zlib: /usr/lib/libz.so.1')
54        result = runCmd('oe-pkgdata-util find-path /usr/bin/m4')
55        self.assertEqual(result.output, 'm4: /usr/bin/m4')
56        result = runCmd('oe-pkgdata-util find-path /not/exist', ignore_status=True)
57        self.assertEqual(result.status, 1, "Status different than 1. output: %s" % result.output)
58        self.assertEqual(result.output, 'ERROR: Unable to find any package producing path /not/exist')
59
60    def test_lookup_recipe(self):
61        result = runCmd('oe-pkgdata-util lookup-recipe "libz-staticdev busybox"')
62        self.assertEqual(result.output, 'zlib\nbusybox')
63        result = runCmd('oe-pkgdata-util lookup-recipe libz-dbg')
64        self.assertEqual(result.output, 'zlib')
65        result = runCmd('oe-pkgdata-util lookup-recipe nonexistentpkg', ignore_status=True)
66        self.assertEqual(result.status, 1, "Status different than 1. output: %s" % result.output)
67        self.assertEqual(result.output, 'ERROR: The following packages could not be found: nonexistentpkg')
68
69    def test_list_pkgs(self):
70        # No arguments
71        result = runCmd('oe-pkgdata-util list-pkgs')
72        pkglist = result.output.split()
73        self.assertIn('zlib', pkglist, "Listed packages: %s" % result.output)
74        self.assertIn('zlib-dev', pkglist, "Listed packages: %s" % result.output)
75        # No pkgspec, runtime
76        result = runCmd('oe-pkgdata-util list-pkgs -r')
77        pkglist = result.output.split()
78        self.assertIn('libz-dev', pkglist, "Listed packages: %s" % result.output)
79        # With recipe specified
80        result = runCmd('oe-pkgdata-util list-pkgs -p zlib')
81        pkglist = sorted(result.output.split())
82        try:
83            pkglist.remove('zlib-ptest') # in case ptest is disabled
84        except ValueError:
85            pass
86        self.assertEqual(pkglist, ['zlib', 'zlib-dbg', 'zlib-dev', 'zlib-doc', 'zlib-src', 'zlib-staticdev'], "Packages listed after remove: %s" % result.output)
87        # With recipe specified, runtime
88        result = runCmd('oe-pkgdata-util list-pkgs -p zlib -r')
89        pkglist = sorted(result.output.split())
90        try:
91            pkglist.remove('libz-ptest') # in case ptest is disabled
92        except ValueError:
93            pass
94        self.assertEqual(pkglist, ['libz-dbg', 'libz-dev', 'libz-doc', 'libz-src', 'libz-staticdev', 'libz1'], "Packages listed after remove: %s" % result.output)
95        # With recipe specified and unpackaged
96        result = runCmd('oe-pkgdata-util list-pkgs -p zlib -u')
97        pkglist = sorted(result.output.split())
98        self.assertIn('zlib-locale', pkglist, "Listed packages: %s" % result.output)
99        # With recipe specified and unpackaged, runtime
100        result = runCmd('oe-pkgdata-util list-pkgs -p zlib -u -r')
101        pkglist = sorted(result.output.split())
102        self.assertIn('libz-locale', pkglist, "Listed packages: %s" % result.output)
103        # With recipe specified and pkgspec
104        result = runCmd('oe-pkgdata-util list-pkgs -p zlib "*-d*"')
105        pkglist = sorted(result.output.split())
106        self.assertEqual(pkglist, ['zlib-dbg', 'zlib-dev', 'zlib-doc'], "Packages listed: %s" % result.output)
107        # With recipe specified and pkgspec, runtime
108        result = runCmd('oe-pkgdata-util list-pkgs -p zlib -r "*-d*"')
109        pkglist = sorted(result.output.split())
110        self.assertEqual(pkglist, ['libz-dbg', 'libz-dev', 'libz-doc'], "Packages listed: %s" % result.output)
111
112    def test_list_pkg_files(self):
113        def splitoutput(output):
114            files = {}
115            curpkg = None
116            for line in output.splitlines():
117                if line.startswith('\t'):
118                    self.assertTrue(curpkg, 'Unexpected non-package line:\n%s' % line)
119                    files[curpkg].append(line.strip())
120                else:
121                    self.assertTrue(line.rstrip().endswith(':'), 'Invalid package line in output:\n%s' % line)
122                    curpkg = line.split(':')[0]
123                    files[curpkg] = []
124            return files
125        bb_vars = get_bb_vars(['libdir', 'includedir', 'mandir'])
126        libdir = bb_vars['libdir']
127        includedir = bb_vars['includedir']
128        mandir = bb_vars['mandir']
129        # Test recipe-space package name
130        result = runCmd('oe-pkgdata-util list-pkg-files zlib-dev zlib-doc')
131        files = splitoutput(result.output)
132        self.assertIn('zlib-dev', list(files.keys()), "listed pkgs. files: %s" %result.output)
133        self.assertIn('zlib-doc', list(files.keys()), "listed pkgs. files: %s" %result.output)
134        self.assertIn(os.path.join(includedir, 'zlib.h'), files['zlib-dev'])
135        self.assertIn(os.path.join(mandir, 'man3/zlib.3'), files['zlib-doc'])
136        # Test runtime package name
137        result = runCmd('oe-pkgdata-util list-pkg-files -r libz1 libz-dev')
138        files = splitoutput(result.output)
139        self.assertIn('libz1', list(files.keys()), "listed pkgs. files: %s" %result.output)
140        self.assertIn('libz-dev', list(files.keys()), "listed pkgs. files: %s" %result.output)
141        self.assertGreater(len(files['libz1']), 1)
142        libspec = os.path.join(libdir, 'libz.so.1.*')
143        found = False
144        for fileitem in files['libz1']:
145            if fnmatch.fnmatchcase(fileitem, libspec):
146                found = True
147                break
148        self.assertTrue(found, 'Could not find zlib library file %s in libz1 package file list: %s' % (libspec, files['libz1']))
149        self.assertIn(os.path.join(includedir, 'zlib.h'), files['libz-dev'])
150        # Test recipe
151        result = runCmd('oe-pkgdata-util list-pkg-files -p zlib')
152        files = splitoutput(result.output)
153        self.assertIn('zlib-dbg', list(files.keys()), "listed pkgs. files: %s" %result.output)
154        self.assertIn('zlib-doc', list(files.keys()), "listed pkgs. files: %s" %result.output)
155        self.assertIn('zlib-dev', list(files.keys()), "listed pkgs. files: %s" %result.output)
156        self.assertIn('zlib-staticdev', list(files.keys()), "listed pkgs. files: %s" %result.output)
157        self.assertIn('zlib', list(files.keys()), "listed pkgs. files: %s" %result.output)
158        self.assertNotIn('zlib-locale', list(files.keys()), "listed pkgs. files: %s" %result.output)
159        # (ignore ptest, might not be there depending on config)
160        self.assertIn(os.path.join(includedir, 'zlib.h'), files['zlib-dev'])
161        self.assertIn(os.path.join(mandir, 'man3/zlib.3'), files['zlib-doc'])
162        self.assertIn(os.path.join(libdir, 'libz.a'), files['zlib-staticdev'])
163        # Test recipe, runtime
164        result = runCmd('oe-pkgdata-util list-pkg-files -p zlib -r')
165        files = splitoutput(result.output)
166        self.assertIn('libz-dbg', list(files.keys()), "listed pkgs. files: %s" %result.output)
167        self.assertIn('libz-doc', list(files.keys()), "listed pkgs. files: %s" %result.output)
168        self.assertIn('libz-dev', list(files.keys()), "listed pkgs. files: %s" %result.output)
169        self.assertIn('libz-staticdev', list(files.keys()), "listed pkgs. files: %s" %result.output)
170        self.assertIn('libz1', list(files.keys()), "listed pkgs. files: %s" %result.output)
171        self.assertNotIn('libz-locale', list(files.keys()), "listed pkgs. files: %s" %result.output)
172        self.assertIn(os.path.join(includedir, 'zlib.h'), files['libz-dev'])
173        self.assertIn(os.path.join(mandir, 'man3/zlib.3'), files['libz-doc'])
174        self.assertIn(os.path.join(libdir, 'libz.a'), files['libz-staticdev'])
175        # Test recipe, unpackaged
176        result = runCmd('oe-pkgdata-util list-pkg-files -p zlib -u')
177        files = splitoutput(result.output)
178        self.assertIn('zlib-dbg', list(files.keys()), "listed pkgs. files: %s" %result.output)
179        self.assertIn('zlib-doc', list(files.keys()), "listed pkgs. files: %s" %result.output)
180        self.assertIn('zlib-dev', list(files.keys()), "listed pkgs. files: %s" %result.output)
181        self.assertIn('zlib-staticdev', list(files.keys()), "listed pkgs. files: %s" %result.output)
182        self.assertIn('zlib', list(files.keys()), "listed pkgs. files: %s" %result.output)
183        self.assertIn('zlib-locale', list(files.keys()), "listed pkgs. files: %s" %result.output) # this is the key one
184        self.assertIn(os.path.join(includedir, 'zlib.h'), files['zlib-dev'])
185        self.assertIn(os.path.join(mandir, 'man3/zlib.3'), files['zlib-doc'])
186        self.assertIn(os.path.join(libdir, 'libz.a'), files['zlib-staticdev'])
187        # Test recipe, runtime, unpackaged
188        result = runCmd('oe-pkgdata-util list-pkg-files -p zlib -r -u')
189        files = splitoutput(result.output)
190        self.assertIn('libz-dbg', list(files.keys()), "listed pkgs. files: %s" %result.output)
191        self.assertIn('libz-doc', list(files.keys()), "listed pkgs. files: %s" %result.output)
192        self.assertIn('libz-dev', list(files.keys()), "listed pkgs. files: %s" %result.output)
193        self.assertIn('libz-staticdev', list(files.keys()), "listed pkgs. files: %s" %result.output)
194        self.assertIn('libz1', list(files.keys()), "listed pkgs. files: %s" %result.output)
195        self.assertIn('libz-locale', list(files.keys()), "listed pkgs. files: %s" %result.output) # this is the key one
196        self.assertIn(os.path.join(includedir, 'zlib.h'), files['libz-dev'])
197        self.assertIn(os.path.join(mandir, 'man3/zlib.3'), files['libz-doc'])
198        self.assertIn(os.path.join(libdir, 'libz.a'), files['libz-staticdev'])
199
200    def test_glob(self):
201        tempdir = tempfile.mkdtemp(prefix='pkgdataqa')
202        self.track_for_cleanup(tempdir)
203        pkglistfile = os.path.join(tempdir, 'pkglist')
204        with open(pkglistfile, 'w') as f:
205            f.write('libz1\n')
206            f.write('busybox\n')
207        result = runCmd('oe-pkgdata-util glob %s "*-dev"' % pkglistfile)
208        desiredresult = ['libz-dev', 'busybox-dev']
209        self.assertEqual(sorted(result.output.split()), sorted(desiredresult))
210        # The following should not error (because when we use this during rootfs construction, sometimes the complementary package won't exist)
211        result = runCmd('oe-pkgdata-util glob %s "*-nonexistent"' % pkglistfile)
212        self.assertEqual(result.output, '')
213        # Test exclude option
214        result = runCmd('oe-pkgdata-util glob %s "*-dev *-dbg" -x "^libz"' % pkglistfile)
215        resultlist = result.output.split()
216        self.assertNotIn('libz-dev', resultlist)
217        self.assertNotIn('libz-dbg', resultlist)
218
219    def test_specify_pkgdatadir(self):
220        result = runCmd('oe-pkgdata-util -p %s lookup-pkg zlib' % get_bb_var('PKGDATA_DIR'))
221        self.assertEqual(result.output, 'libz1')
222
223    def test_no_param(self):
224        result = runCmd('oe-pkgdata-util', ignore_status=True)
225        self.assertEqual(result.status, 2, "Status different than 2. output: %s" % result.output)
226        currpos = result.output.find('usage: oe-pkgdata-util')
227        self.assertTrue(currpos != -1, msg = "Test is Failed. Help is not Displayed in %s" % result.output)
228