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