1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7import os
8import re
9import subprocess
10from oeqa.utils.httpserver import HTTPService
11
12from oeqa.runtime.case import OERuntimeTestCase
13from oeqa.core.decorator.depends import OETestDepends
14from oeqa.core.decorator.data import skipIfNotDataVar, skipIfNotFeature, skipIfInDataVar, skipIfNotInDataVar
15from oeqa.runtime.decorator.package import OEHasPackage
16
17class DnfTest(OERuntimeTestCase):
18
19    def dnf(self, command, expected = 0):
20        command = 'dnf %s' % command
21        status, output = self.target.run(command, 1500)
22        message = os.linesep.join([command, output])
23        self.assertEqual(status, expected, message)
24        return output
25
26class DnfBasicTest(DnfTest):
27
28    @skipIfNotFeature('package-management',
29                      'Test requires package-management to be in IMAGE_FEATURES')
30    @skipIfNotDataVar('IMAGE_PKGTYPE', 'rpm',
31                      'RPM is not the primary package manager')
32    @OEHasPackage(['dnf'])
33    @OETestDepends(['ssh.SSHTest.test_ssh'])
34    def test_dnf_help(self):
35        self.dnf('--help')
36
37    @OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
38    def test_dnf_version(self):
39        self.dnf('--version')
40
41    @OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
42    def test_dnf_info(self):
43        self.dnf('info dnf')
44
45    @OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
46    def test_dnf_search(self):
47        self.dnf('search dnf')
48
49    @OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
50    def test_dnf_history(self):
51        self.dnf('history')
52
53class DnfRepoTest(DnfTest):
54
55    @classmethod
56    def setUpClass(cls):
57        cls.repo_server = HTTPService(os.path.join(cls.tc.td['WORKDIR'], 'oe-testimage-repo'),
58                                      '0.0.0.0', port=cls.tc.target.server_port,
59                                      logger=cls.tc.logger)
60        cls.repo_server.start()
61
62    @classmethod
63    def tearDownClass(cls):
64        cls.repo_server.stop()
65
66    def dnf_with_repo(self, command):
67        pkgarchs = os.listdir(os.path.join(self.tc.td['WORKDIR'], 'oe-testimage-repo'))
68        deploy_url = 'http://%s:%s/' %(self.target.server_ip, self.repo_server.port)
69        cmdlinerepoopts = ["--repofrompath=oe-testimage-repo-%s,%s%s" %(arch, deploy_url, arch) for arch in pkgarchs]
70
71        output = self.dnf(" ".join(cmdlinerepoopts) + " --nogpgcheck " + command)
72        return output
73
74    @OETestDepends(['dnf.DnfBasicTest.test_dnf_help'])
75    def test_dnf_makecache(self):
76        self.dnf_with_repo('makecache')
77
78    @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
79    def test_dnf_repoinfo(self):
80        self.dnf_with_repo('repoinfo')
81
82    @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
83    def test_dnf_install(self):
84        self.dnf_with_repo('remove -y dnf-test-*')
85        self.dnf_with_repo('install -y dnf-test-dep')
86
87    @OETestDepends(['dnf.DnfRepoTest.test_dnf_install'])
88    def test_dnf_install_dependency(self):
89        self.dnf_with_repo('remove -y dnf-test-*')
90        self.dnf_with_repo('install -y dnf-test-main')
91        output = self.dnf('list --installed dnf-test-*')
92        self.assertIn("dnf-test-main.", output)
93        self.assertIn("dnf-test-dep.", output)
94
95    @OETestDepends(['dnf.DnfRepoTest.test_dnf_install_dependency'])
96    def test_dnf_install_from_disk(self):
97        self.dnf_with_repo('remove -y dnf-test-dep')
98        self.dnf_with_repo('install -y --downloadonly dnf-test-dep')
99        status, output = self.target.run('find /var/cache/dnf -name dnf-test-dep*rpm')
100        self.assertEqual(status, 0, output)
101        self.dnf_with_repo('install -y %s' % output)
102
103    @OETestDepends(['dnf.DnfRepoTest.test_dnf_install_from_disk'])
104    def test_dnf_install_from_http(self):
105        output = subprocess.check_output('%s %s -name dnf-test-dep*' % (bb.utils.which(os.getenv('PATH'), "find"),
106                                                                           os.path.join(self.tc.td['WORKDIR'], 'oe-testimage-repo')), shell=True).decode("utf-8")
107        rpm_path = output.split("/")[-2] + "/" + output.split("/")[-1]
108        url = 'http://%s:%s/%s' %(self.target.server_ip, self.repo_server.port, rpm_path)
109        self.dnf_with_repo('remove -y dnf-test-dep')
110        self.dnf_with_repo('install -y %s' % url)
111
112    @OETestDepends(['dnf.DnfRepoTest.test_dnf_install'])
113    def test_dnf_reinstall(self):
114        self.dnf_with_repo('reinstall -y dnf-test-main')
115
116    @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
117    @skipIfInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when not enable usrmerge')
118    @OEHasPackage('busybox')
119    def test_dnf_installroot(self):
120        rootpath = '/home/root/chroot/test'
121        #Copy necessary files to avoid errors with not yet installed tools on
122        #installroot directory.
123        self.target.run('mkdir -p %s/etc' % rootpath, 1500)
124        self.target.run('mkdir -p %s/bin %s/sbin %s/usr/bin %s/usr/sbin' % (rootpath, rootpath, rootpath, rootpath), 1500)
125        self.target.run('mkdir -p %s/dev' % rootpath, 1500)
126        #Handle different architectures lib dirs
127        self.target.run('mkdir -p %s/lib' % rootpath, 1500)
128        self.target.run('mkdir -p %s/libx32' % rootpath, 1500)
129        self.target.run('mkdir -p %s/lib64' % rootpath, 1500)
130        self.target.run('cp /lib/libtinfo.so.5 %s/lib' % rootpath, 1500)
131        self.target.run('cp /libx32/libtinfo.so.5 %s/libx32' % rootpath, 1500)
132        self.target.run('cp /lib64/libtinfo.so.5 %s/lib64' % rootpath, 1500)
133        self.target.run('cp -r /etc/rpm %s/etc' % rootpath, 1500)
134        self.target.run('cp -r /etc/dnf %s/etc' % rootpath, 1500)
135        self.target.run('cp /bin/sh %s/bin' % rootpath, 1500)
136        self.target.run('mount -o bind /dev %s/dev/' % rootpath, 1500)
137        self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox' % rootpath)
138        status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath, 1500)
139        self.assertEqual(0, status, output)
140        status, output = self.target.run('test -e %s/bin/busybox' % rootpath, 1500)
141        self.assertEqual(0, status, output)
142
143    @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
144    @skipIfNotInDataVar('DISTRO_FEATURES', 'usrmerge', 'Test run when enable usrmerge')
145    @OEHasPackage('busybox')
146    def test_dnf_installroot_usrmerge(self):
147        rootpath = '/home/root/chroot/test'
148        #Copy necessary files to avoid errors with not yet installed tools on
149        #installroot directory.
150        self.target.run('mkdir -p %s/etc' % rootpath)
151        self.target.run('mkdir -p %s/usr/bin %s/usr/sbin' % (rootpath, rootpath))
152        self.target.run('ln -sf usr/bin %s/bin'  % (rootpath))
153        self.target.run('ln -sf usr/sbin %s/sbin'  % (rootpath))
154        self.target.run('mkdir -p %s/dev' % rootpath)
155        #Handle different architectures lib dirs
156        self.target.run("for l in /lib*; do mkdir -p %s/usr/$l; ln -s usr/$l %s/$l; done" % (rootpath, rootpath))
157        self.target.run('cp -r /etc/rpm %s/etc' % rootpath)
158        self.target.run('cp -r /etc/dnf %s/etc' % rootpath)
159        self.target.run('cp /bin/busybox %s/bin/sh' % rootpath)
160        self.target.run('mount -o bind /dev %s/dev/' % rootpath)
161        self.dnf_with_repo('install --installroot=%s -v -y --rpmverbosity=debug busybox' % rootpath)
162        status, output = self.target.run('test -e %s/var/cache/dnf' % rootpath)
163        self.assertEqual(0, status, output)
164        status, output = self.target.run('test -e %s/bin/busybox' % rootpath)
165        self.assertEqual(0, status, output)
166
167    @OETestDepends(['dnf.DnfRepoTest.test_dnf_makecache'])
168    def test_dnf_exclude(self):
169        self.dnf_with_repo('remove -y dnf-test-*')
170        self.dnf_with_repo('install -y --exclude=dnf-test-dep dnf-test-*')
171        output = self.dnf('list --installed dnf-test-*')
172        self.assertIn("dnf-test-main.", output)
173        self.assertNotIn("dnf-test-dev.", output)
174