From 473bc1460bf39e5ce8e5023b13484156bda1dbff Mon Sep 17 00:00:00 2001 From: Yuming Zhu Date: Wed, 29 Aug 2018 19:04:58 +0800 Subject: [PATCH] hub: [getRPMFile] add strict behavior --- hub/kojihub.py | 24 +++++- tests/test_hub/test_getRPMFile.py | 80 ++++++++++++++++++ .../data/rpms/test-files-1-1.fc27.noarch.rpm | Bin 0 -> 6644 bytes tests/test_lib/data/specs/test-files._spec | 20 +++++ 4 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 tests/test_hub/test_getRPMFile.py create mode 100644 tests/test_lib/data/rpms/test-files-1-1.fc27.noarch.rpm create mode 100644 tests/test_lib/data/specs/test-files._spec diff --git a/hub/kojihub.py b/hub/kojihub.py index aab3ba49..721835b3 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -74,6 +74,7 @@ from koji.util import multi_fnmatch from koji.util import safer_move from koji.util import to_list from six.moves import range + logger = logging.getLogger('koji.hub') @@ -10627,7 +10628,7 @@ class RootExports(object): return _applyQueryOpts(results, queryOpts) - def getRPMFile(self, rpmID, filename): + def getRPMFile(self, rpmID, filename, strict=False): """ Get info about the file in the given RPM with the given filename. A map will be returned with the following keys: @@ -10643,14 +10644,26 @@ class RootExports(object): - mtime - mode - If no such file exists, an empty map will be returned. + If there is no *internal* RPM with the given ID, or no RPM file found, + an empty map will be returned, unless strict is True in which case a + GenericError is raised. + If no such file exists, an empty map will be returned, unless strict is + True in which case a GenericError is raised. """ - rpm_info = get_rpm(rpmID) - if not rpm_info or not rpm_info['build_id']: + rpm_info = get_rpm(rpmID, strict=strict) + if not rpm_info: + return {} + if rpm_info and not rpm_info['build_id']: + if strict: + raise koji.GenericError("Can not get RPM file," + " because RPM: %s is not internal" % rpmID) return {} build_info = get_build(rpm_info['build_id']) rpm_path = joinpath(koji.pathinfo.build(build_info), koji.pathinfo.rpm(rpm_info)) if not os.path.exists(rpm_path): + if strict: + raise koji.GenericError( + "RPM package file of %s doesn't exist" % rpmID) return {} hdr = koji.get_rpm_header(rpm_path) @@ -10668,6 +10681,9 @@ class RootExports(object): 'user': fields['fileusername'][i], 'group': fields['filegroupname'][i], 'mtime': fields['filemtimes'][i], 'mode': fields['filemodes'][i]} i += 1 + if strict: + raise koji.GenericError( + "No file: %s found in RPM: %s" % (filename, rpmID)) return {} def getRPMHeaders(self, rpmID=None, taskID=None, filepath=None, headers=None): diff --git a/tests/test_hub/test_getRPMFile.py b/tests/test_hub/test_getRPMFile.py new file mode 100644 index 00000000..98d1b2f6 --- /dev/null +++ b/tests/test_hub/test_getRPMFile.py @@ -0,0 +1,80 @@ +from __future__ import absolute_import + +import os + +import mock + +try: + import unittest2 as unittest +except ImportError: + import unittest +import koji +import kojihub + + +class TestGetRPMFile(unittest.TestCase): + + @mock.patch('kojihub.get_rpm') + def test_getRPMFile_no_rpminfo(self, get_rpm): + def mock_get_rpm(rpmID, strict=False): + if strict: + raise koji.GenericError('msg') + else: + return None + + get_rpm.side_effect = mock_get_rpm + re = kojihub.RootExports().getRPMFile(1, 'filename') + self.assertEquals(re, {}) + with self.assertRaises(koji.GenericError) as cm: + kojihub.RootExports().getRPMFile(1, 'filename', strict=True) + self.assertEquals(cm.exception.args[0], 'msg') + + @mock.patch('kojihub.get_rpm', return_value={'id': 1, 'build_id': None}) + def test_getRPMFile_external_rpm(self, get_rpm): + re = kojihub.RootExports().getRPMFile(1, 'filename') + self.assertEquals(re, {}) + with self.assertRaises(koji.GenericError) as cm: + kojihub.RootExports().getRPMFile(1, 'filename', strict=True) + self.assertEquals(cm.exception.args[0], + 'Can not get RPM file,' + ' because RPM: 1 is not internal') + + @mock.patch('kojihub.get_rpm', return_value={'id': 1, 'build_id': 1}) + @mock.patch('kojihub.get_build', return_value={'id': 1}) + @mock.patch('koji.pathinfo.build', return_value='fakebuildpath') + @mock.patch('koji.pathinfo.rpm', return_value='fakerpmrelpath') + @mock.patch('os.path.exists', return_value=False) + def test_getRPMFile_no_rpmfile(self, ope, pr, pb, get_build, get_rpm): + re = kojihub.RootExports().getRPMFile(1, 'filename') + self.assertEquals(re, {}) + with self.assertRaises(koji.GenericError) as cm: + kojihub.RootExports().getRPMFile(1, 'filename', strict=True) + self.assertEquals(cm.exception.args[0], + "RPM package file of 1 doesn't exist") + + @mock.patch('kojihub.get_rpm', return_value={'id': 1, 'build_id': 1}) + @mock.patch('kojihub.get_build') + @mock.patch('koji.pathinfo') + def test_getRPMFile(self, pi, build, rpm): + pi.build.return_value = os.path.join(os.path.dirname(__file__), + '../test_lib/data/rpms') + pi.rpm.return_value = 'test-files-1-1.fc27.noarch.rpm' + getRPMFile = kojihub.RootExports().getRPMFile + res = getRPMFile(1, '/fileA') + self.assertDictEqual(res, {'digest_algo': 'sha256', + 'user': 'root', + 'mtime': int(1535536271), + 'digest': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + 'size': 0, + 'group': 'root', + 'name': '/fileA', + 'rpm_id': 1, + 'flags': 0, + 'mode': int(0o100755), + 'md5': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'}) + res = getRPMFile(1, '/fileB') + self.assertEquals(res, {}) + with self.assertRaises(koji.GenericError) as cm: + res = getRPMFile(1, '/fileB', strict=True) + self.assertEquals(cm.exception.args[0], + 'No file: /fileB found in RPM: 1') diff --git a/tests/test_lib/data/rpms/test-files-1-1.fc27.noarch.rpm b/tests/test_lib/data/rpms/test-files-1-1.fc27.noarch.rpm new file mode 100644 index 0000000000000000000000000000000000000000..b486a9ca0b52dd524db8cd4d03e78137ca7f8055 GIT binary patch literal 6644 zcmeHMYitx%6u#SC5ef*1C=w)VFcFa1o#*b3TD7zkY6z{AYRf~IxpQZCWOrtrnT59a zqa=uuK#_niBpM&lL?LQI2u5Rw5={K%BOyEkCW=%ZY7~P3tmo`rT0)G`_|v_~nQy*( z9{1dH@9rjN&%Sf+NR+@B2w4ycwv%UpAPG{!rg9qR|ILVy>#jBL+j%O&=dLGY>@Ik} z4+P)e031t5WHjI~5FB6|83%}bdWA<%0meY`oSy*%e^LYi|LBi^sP6><|L9MEs9y`} zxMVP0S7lLWW=fH4QP&kIrKGJ)+7K;GlG7QRi82!jHC36Vn3b{Zj7V)Ot;)z`*)VLA z8ls}flBJkwOH)z`OH;*?Di)LrP&; zRee+|P_00<0@VssD^RUKwF1=&R4Y)eK(zwZ3REjlt-$}i0_C2_z`(#WPzdO05OP)D zM1}T72Ta`$0)36xTtKw3K!$_hz`h6eNw9BH!+AgF*k3{Y51fzT9Q!CEKyK#zEax)k z=K!&<(#kpZSup-W&VL3({c_HK14KRMh3j1a#P|;9mjO{<;`|TJS66rpW1*}Cfjz{~ z7F$yrILBDXu|}w`1w{L;oR0*=dTi%>RE0;TaE^5V`$!xR{jm;UADPBE))YDJAN4l@ zLJpC80bxI}34rL2XMy@#0MULqAnGRqqCQ{2*sXx5e}eN#oFC^L*Twi30nxvy!fPOQ zna=@)cr_Ro*PF|EobzTth+l(oP>*?`{Y*fN*U9xF=S#RA_k;FJxxSI}M>)syM!g9L z`PHBw#j3`I-JFMjkYDr*K#Y&~0Qo`AR|3L*q9*`xy&gcg z@6nTha5m$&0HXbcihlflK#YHh^KSvcKL)YUfBbiVU>|El-av->n?xeKzqt^4o{pQ1 zm)oB495XED17Ue9Ab+PLWbvBwPn$klC0GpeE)Ump8EJQeBBKrju}I!=OI^hE44>w% z7y+(1yQUZE;&u5=AkQ5L|u8BHVqIRIu;8NTO*XN0vPr?Z#q1Z{ESve!*Amj|+ zVlJ};N~M2bZn&;zI&Q_fkW%A9AuPG9E(V7!)~%-%7hL3zS?s6 z^oK{j?(SWV-)L}_rO*~KBtvb*kTfb&$&@VB5-mw&sxGA!O)?BaRTNQD#f&Q3sx76U z>#s4($mkhOwG>U4X(bjs%fG_|1DE!~``F9ro{mLu*T1eU)@d*nu#oVw?!nI|Fv z>0C-Cjy@JM<=;yqdtckvEjVqDZ~pk@&4=sm?E8M#wr5ZEf7aQy;P9{`tKIB_AFvUHG2!|U-;#=bq_sv_tZnD_r5(4dvDvBzV2Z!9{iwj#w$nP+UYEYRp5ti z#tmEV$sIVll}y^*{^{#-#O?|v*Y=O7|KzSQ``1s|Ln0d^zru|^|L#i<@9sZ7xqP{6 HI~V;4L{tZ~ literal 0 HcmV?d00001 diff --git a/tests/test_lib/data/specs/test-files._spec b/tests/test_lib/data/specs/test-files._spec new file mode 100644 index 00000000..664e4e6e --- /dev/null +++ b/tests/test_lib/data/specs/test-files._spec @@ -0,0 +1,20 @@ +Name: test-files +Version: 1 +Release: 1%{?dist} +Summary: Testing files header fields + +License: none + +%description +Testing files header fields + +%install +rm -rf $RPM_BUILD_ROOT +install -d $RPM_BUILD_ROOT/foo/bar +install -pm 0755 fileA $RPM_BUILD_ROOT +install -pm 0600 foo/bar/fileB $RPM_BUILD_ROOT/foo/bar + +%files +%defattr(-,root,root) +/fileA +/foo/bar/fileB