From 7aebc735b5f7384702306e8d075f2e69019c818d Mon Sep 17 00:00:00 2001 From: Luz Marina Date: Fri, 9 Aug 2024 10:28:06 +0200 Subject: [PATCH 1/5] Replace bin in test_bashisms.py Also, creating a mock file to improve code cleanup of the test_bashisms.py file. --- test/mockdata/mock_bashisms.py | 11 +++++++++++ test/test_bashisms.py | 15 ++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 test/mockdata/mock_bashisms.py diff --git a/test/mockdata/mock_bashisms.py b/test/mockdata/mock_bashisms.py new file mode 100644 index 000000000..9c95a5b83 --- /dev/null +++ b/test/mockdata/mock_bashisms.py @@ -0,0 +1,11 @@ +from Testing import get_tested_mock_package + +BASHISMS = get_tested_mock_package( + files={ + '/bin/script1': {'content': """#!/bin/sh +xz $tmp/1 &> /dev/null +"""}, + '/bin/script2': {'content': """#!/bin/sh +do +"""} + }) diff --git a/test/test_bashisms.py b/test/test_bashisms.py index f790e629e..34ec4848b 100644 --- a/test/test_bashisms.py +++ b/test/test_bashisms.py @@ -1,8 +1,9 @@ +from mockdata.mock_bashisms import BASHISMS import pytest from rpmlint.checks.BashismsCheck import BashismsCheck from rpmlint.filter import Filter -from Testing import CONFIG, get_tested_package, HAS_CHECKBASHISMS, HAS_DASH +from Testing import CONFIG, HAS_CHECKBASHISMS, HAS_DASH @pytest.fixture(scope='function', autouse=True) @@ -15,10 +16,10 @@ def bashismscheck(): @pytest.mark.skipif(not HAS_CHECKBASHISMS, reason='Optional dependency checkbashisms not installed') @pytest.mark.skipif(not HAS_DASH, reason='Optional dependency dash not installed') -@pytest.mark.parametrize('package', ['binary/bashisms']) -def test_bashisms(tmp_path, package, bashismscheck): +@pytest.mark.parametrize('package', [BASHISMS]) +def test_bashisms(package, bashismscheck): output, test = bashismscheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'W: potential-bashisms /bin/script1' in out assert 'W: bin-sh-syntax-error /bin/script2' in out @@ -26,10 +27,10 @@ def test_bashisms(tmp_path, package, bashismscheck): @pytest.mark.skipif(not HAS_CHECKBASHISMS, reason='Optional dependency checkbashisms not installed') @pytest.mark.skipif(not HAS_DASH, reason='Optional dependency dash not installed') -@pytest.mark.parametrize('package', ['binary/bashisms']) -def test_bashisms_error(tmp_path, package, bashismscheck): +@pytest.mark.parametrize('package', [BASHISMS]) +def test_bashisms_error(package, bashismscheck): output, test = bashismscheck - package = get_tested_package(package, tmp_path) package.dirname = 'I-do-not-exist-for-sure' + with pytest.raises(FileNotFoundError): test.check(package) From 6f8a2041efeb51df63c9f8e11676ec0e7d90b7bd Mon Sep 17 00:00:00 2001 From: Luz Marina Date: Mon, 12 Aug 2024 12:02:54 +0200 Subject: [PATCH 2/5] Replace bin in test_icon_sizes.py Also, creating a mock file to improve code cleanup of the test_icon_sizes.py file. --- test/mockdata/mock_icon_sizes.py | 11 +++++++++++ test/test_icon_sizes.py | 9 +++++---- 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 test/mockdata/mock_icon_sizes.py diff --git a/test/mockdata/mock_icon_sizes.py b/test/mockdata/mock_icon_sizes.py new file mode 100644 index 000000000..31c37ff15 --- /dev/null +++ b/test/mockdata/mock_icon_sizes.py @@ -0,0 +1,11 @@ +from Testing import get_tested_mock_package + +ICONSIZES = get_tested_mock_package( + files={ + '/usr/share/tasque/icons/hicolor/16x16/status/tasque-note.png': { + 'metadata': { + 'magic': '22 x 22' + } + } + } +) diff --git a/test/test_icon_sizes.py b/test/test_icon_sizes.py index ad96ff853..7a0498300 100644 --- a/test/test_icon_sizes.py +++ b/test/test_icon_sizes.py @@ -1,8 +1,9 @@ +from mockdata.mock_icon_sizes import ICONSIZES import pytest from rpmlint.checks.IconSizesCheck import IconSizesCheck from rpmlint.filter import Filter -from Testing import CONFIG, get_tested_package +from Testing import CONFIG @pytest.fixture(scope='function', autouse=True) @@ -13,9 +14,9 @@ def iconsizescheck(): return output, test -@pytest.mark.parametrize('package', ['binary/tasque']) -def test_icon_sizes(tmp_path, package, iconsizescheck): +@pytest.mark.parametrize('package', [ICONSIZES]) +def test_icon_sizes(package, iconsizescheck): output, test = iconsizescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: wrong-icon-size /usr/share/tasque/icons/hicolor/16x16/status/tasque-note.png expected: 16x16 actual: 22x22' in out From b69168a52e6fd79092d2f6c534b5bcdb24ea1451 Mon Sep 17 00:00:00 2001 From: Luz Marina Date: Thu, 15 Aug 2024 18:09:10 +0200 Subject: [PATCH 3/5] Replace bin in test_shlib_policy.py Also, creating a mock file to improve code cleanup of the test_shlib_policy.py file. --- test/files/shlib_policy/libhello.so | Bin 0 -> 14328 bytes test/files/shlib_policy/libhello2.so | Bin 0 -> 14328 bytes test/files/shlib_policy/libtest.so.1.5.0 | Bin 0 -> 14328 bytes test/mockdata/mock_shlib_policy.py | 61 +++++++++++++++++++++++ test/test_shlib_policy.py | 21 ++++---- 5 files changed, 72 insertions(+), 10 deletions(-) create mode 100755 test/files/shlib_policy/libhello.so create mode 100755 test/files/shlib_policy/libhello2.so create mode 100755 test/files/shlib_policy/libtest.so.1.5.0 create mode 100644 test/mockdata/mock_shlib_policy.py diff --git a/test/files/shlib_policy/libhello.so b/test/files/shlib_policy/libhello.so new file mode 100755 index 0000000000000000000000000000000000000000..841520fcd6b6789423c81293633793c16fdee722 GIT binary patch literal 14328 zcmeHOU1$_n6uz4nO{ykav29F>PD6yWHDlB!q)2qDRmY;m+61XI9VgjMc5t(6cPE;N z#Xx95MDU?6^{w=!Z_?5Sp)V1Gl!8!c3-&EYZDWx(P+DRivOQ<+`POkvuze{M?hQNN zJwM;QXTH66!!mcz?m4ixDv?lV)oO=g>rhgAQWEIiA{~O1>Q;4hZB|WT?y?7=M|!s; z2vjmI&r!qKV#l#lN&+Iz?r=zp$<(ayTEQ>G1V(wwDK^)x6Xtpz#_lR@rv$-clX=S4 zags+j!5OI&SSw+!kzW`$j;)dhCoQ%fMdSm)dxLmkotpO8D`Y<`^DU)I zQuF}I?S}WZmS(A@*S^>L)Q8iz`ge`ze!6|K<+B?{zgxH6op_Ur;P?tbt~Gqm38Rhc z=4p6r=*|7g{VY=!`p3^+Izyo)8{e0;Nc1TA)-2-Zd8|eJo0jnJC4b8z`F-SDqgJcB zCw1^y0VrJMc1({;+!QHt+KGW+B zq%{9|<_GGCHFNi`v(3g8NfE ze%P#(^Zry&RsP1AoUXkVCYL*Jle@g}N4hp_NKudNEXVH7l&Nj}oa~{C7}>edbCVp- zg_^G!UY-x0qM=W6pN6h0&ope9;M{A1l>c#<-+77Q`32|PoOAWpozB(yYA12sxw#Om zr2+QH0JY_rp@t2wKHzix6FvPDR--TWIg>pt+;z^~3067hdv=g9`xaF>o2JY4nohD4 z{WN!Fe&*jjMZrGeP%-!FmAb+O&aNS6*z0E{Dmqn^;Uv?H0!9I&fKk9GU=%P47zK<1 zMggOMQNSqh|4_i;Cx)A>BZXov{T!8?Xs+JgO32UTl5^#9im-!_zwzHEoFL@J&wjZj zP9Ii@v1Foo)r#7S^nj1K{Ot3q-^yi+P}L{*);GS^u<}&xgxcA({e^9}T%V^m>=(3ZJ3AQlI>wYWM2pM`!|0FwH1n6fg=H1&jhl0i%FXz$jo8FbWt2 z{+R-DjuYoLaVFCfHa-3f+i}5Ff;cF;TI@C%XPwwMFWM|NzNncRKPRzD(lB znSs$^rKV^1T~>A}TMCMSH=yi%A;{Rn`B8gd)X$~c{j>_LtXIk^ zJ3XE+jgM#yiaK&KQ!M#~{6mIIv0^6YF+qAKa)Gk_yiZr^+QS9v1er0q(&=cQk_u@r z@RXg&x3mSf|ws}{+&X!e*8ZI z;{O!#z*cQmuJQRlqDYkAZRu3tnF>>P zpc~wuP={;eJ;V+FfAKq>cs^|4W#Tl@3w->4o|oT8A&&Dl!L z@Xb-<{lg7BypKilaSHhOoyg2)&Q{6_uMaNZ1E(nz<*StBc4)N31b_#;L4hdWO6g2X x_{fX%VSh^<&O!ZcDIIBBg3ohB+buHUK8}O`xb+jQJv#0Ing8dgllt+w{s!quqQU?G literal 0 HcmV?d00001 diff --git a/test/files/shlib_policy/libhello2.so b/test/files/shlib_policy/libhello2.so new file mode 100755 index 0000000000000000000000000000000000000000..3e6b86695f0a3d21c7a614f7488d910d4864ad3a GIT binary patch literal 14328 zcmeHOU2GIp6u#S1Xa(Appw`yF*p#Fy9SYc{h7?v17zh|3ZHPu3rrl|G!gd#Tr?fN( zHH{{SB)rO-@j-ktF+Px(m=cgEiHTrL@NHux7DKd&(G(xLo-=d4WfqhVFXukq{nn{{?`{6*zsJdZJtf9(SP9prDBC%=z;E7WpT z_h=Y=3OTktG@Q@bMc*m-wyo@4y?gDnTX2WGqVE=Z_ioGPb8fHGpLN67{1JO#%&`Z( zoRjs&T{Y}@Id!z)<@`aF_4)_QV&3fHUdGL4^Bc%)UvF+OH>#a`c5U5eZ=il>P*3<~ zR*};D=a3KUV5G^bWA#r;-Pj*k&r0rVR`w12Q!;>&3W@N;E^P_@{Qj}lXwwltuMxDF zh#za4W3v%|bPYA8LME@V@a{reU$p{S0j+>mKr5gX&N$99Hew@YPeYd$4=@Ek_A&h}g< zhjq5*8p8{-{$n)sG49jQb>&jS>Iu%hEJ*nu1o@rk8J?N5PS04Ee%)eSnyt1HSFP)F z{z@8Py9`iUE)6!Ue(4^c>!0X3L}4}ZT%R@B)52Zr^eumxb*5)C8Pl&&mD6duT&?LO zJ8_8SuFTK;+oKfhBMudFr(UUxT;TKyat6IatVBhpiZYy}n^r(8pcT*xXa%$aS^=$q zRzNGD70?Q31^yojSp39rt#L44$flpBk`v9o5b`(vyMz;j-1ylq zx5W4Xl^9DVnwKr9Jx34tn9I*Tzxu6QHV9RHaz}mR?uMnKwG(Pf)23%PwzjaF`Sdkj zO;H}68M2?buhHubnk#sQ`eJ?ZovLli7aybvI6*h9fL1^&pcT*xXa%$aS^=$qRzNGD z75HZg$T?1&+r*hnN7(fEGiXNymkHva=yI{!WSl3(#(B|ZvGHB4No<@O4ZhQn5Aj73 zKP-ng|ClT1*>z5Aob@~`heUA>_@cxg5&pY^O9dMRg{D+0bO=o$j_M(@m>wbr_XC~jYi(fvBJsOoSL&4U{xiUN_Sl47v2(q# z!^Iu#9p+efm)-TenRfd}hSb;N(X6jbFXz#fy5>-xI=(wbS2`W-QBpqb z_>MB&j6GOzhFv?8ra@qZRNE;OoZ}$_eVV};_6BJByw4+3alttK#bQtro!O?_%z8O& zjF?{k*5q{>J+r*f?*lL{_6h73>hRvcddB_%c1R+4ShuiOQT$I@d*EZg0b3W~i(9o( zhwlM=>_;H>2iM4JAM<0MaDBYy!N>jvVn0(#(6E1CcTrn&9&gpU*&i z4pU0dPzUS*>O}bl_B#-Xg5t*TDi`CYBmszeF$`?rXpE2F8v(xuQ4sUP{br1h|3^Ul zpF)28{wIZx_fHv;DTwtW-ur&Lz`ir|V*S8R8e~udwuWZq8lV4tibVO{MwkjbQDKH1 z=mz(P)ZrR=4{^i)U;K_Io(~)N32_?e1wQ^i&&uzkkjGA@)LxCvYNQIe( x@R1ki!~TvsoP+w?QemWR0Y1+aZ8yn?`#28%!`4r<_UO2KWd5I{PU^?!`WuW2q#*zR literal 0 HcmV?d00001 diff --git a/test/files/shlib_policy/libtest.so.1.5.0 b/test/files/shlib_policy/libtest.so.1.5.0 new file mode 100755 index 0000000000000000000000000000000000000000..15e0647768710c703d0d8d04926f450771331edd GIT binary patch literal 14328 zcmeHOU2GIp7`@w4DMH(oAlBB%NQ$Y14h3yfLMkg*7z`LBZAgqbOuN(W$aWWZr_dsX zCJh=wh`dVT1M$T-qw#^n2TLGCO*A$ph8L5@h?azCUoiEh>-Ww5PMHpE)E5(zdy}1W zzn^n|&fYtl&D=TLb6{^(Dy2}W)$@w2Luu{FNT6$*R0uMvORb`7vucWRSKJRhP`f2T zpptgEj~dPvJBe*FBp~AKj+(TXOvQ?>3;3Csz&P(Aip{p^gxT)J*j1(Nj39VyGEdn$ zPV(p?I4$D@)=HSi$RD(u#1_c|axRxcx5F&g(-vC~BJzRYy+XWboSOExSIB-?`ddzy zwCDkp=|*!~N4-?jXWz?x%KqYm$-4TlriOOjeec^hd)~eB$@VCf<0~bP#~OX-gz>`T z=5Ck(y}7r19M>HhE*9K!=#@g(Rqp=YgKpL@`9ncD^h>=5_vDKOzt`)}`#QFC#2py*+`*vW z<%83{8uo&MI#CJ=;h@R~{R4KnXm@fg^vfX|+eX#C1N(RHaktys?G8N@{Y6$qDznxp zfoO6?5 zRpmQp;zsTDg~Uq7PZX+b`kAf`8!}X5JIC=m(-kV4J|%nb5(v)4?kRFO7i+#|*fAGA zO3k0-IyJwlGTpFYoO7=WQvQ`FzvD8)GxN^*S?AhsyPRut)lTZBGc_NsqXv4Uf!fOS zV8ezN@AJpIJqoFjt$of!_tRW;&fgB#I2XEilQDCYMmUqB%gve{WT%dzU*Mg$DA-3F z8pv$DQdfC!GwaD2)sC_fkw%MD;UrUx0!9I&fKk9GU=%P47zK<1MggOMQNSqh|53p4 z^ZDWy>qxPb&pt)NPBmBWY$4=la_QMhB}3Rw$p8575snjb;b*^GQl}5A)Mz@@yk=$X zC3?WeTz>ZXMX2i2d+QrtYFK@$c3kah+PV4JmW}LYKK+eXlaz;NhU{nVYxEhW zzM^NSFVv^ssoGQb&=Kl@6HGA*7zK<1MggOMQNSo*6fg=H1&jhlfq$leoa4l~O`OT} zgiVh?qjFqujUWz+)`{IB?L00v&WkpSjsI#*V&mLs^q-D=h_8_NF*&?>Z@yAw*CnxW z*7KMg62&>-s}g@$_~!&y3pNT0O{t7_2u&f5|FL|2l*?lp)T9gy{zkDe?vEso4$Vdd z?af#8_~)c!dXOB=2RhT=+Q|Mz;(v<0FivUjKLea+PjuLsIM*9LTx@sP?QPraj<$At zw5!wYe9q4L{Ubx_jUP6jPxbL2D0u>^ES`GJJ8XR;utEz{h?B zVt?=$dF`Wr>=PazuX*sXzk%4#loA!}AJ|<~;k^Yu_7f2IG0Ycvz#iiBUWJYQ3bdr7 z$@#x7{N2(Z?l(Z_#QgR2N%C{#V@+^B#QhnF`xvD}1>=A{ zK$SS(!hQ!LQBd4yUKJAjj3fXtUNi$6cq+li`$oVi5Czdc+;1oN_&oyRzKs0j{3nEu z?@w8hDTwtW-bL>&uR778z84E!teTCi{P%B5{6~rBi`t7MQvM-QfO^Dm+Hs zLtOCti}!ev`LKZ>6Q_Yb;N$msPTr3~9=FW}Ht=)u@!A7_;k_uEvz40W$x-3`!v#Ei zk0tVP3ixh($ literal 0 HcmV?d00001 diff --git a/test/mockdata/mock_shlib_policy.py b/test/mockdata/mock_shlib_policy.py new file mode 100644 index 000000000..3d88a3bc4 --- /dev/null +++ b/test/mockdata/mock_shlib_policy.py @@ -0,0 +1,61 @@ +from Testing import get_tested_mock_package + +SHLIBPOLICY = get_tested_mock_package( + name='libtest1', + files={ + '/usr/lib64/libtest.so.1.5.0': {'content-path': 'files/shlib_policy/libtest.so.1.5.0'} + }, + header={ + 'requires': [ + '/sbin/ldconfig', + 'libc.so.6()(64bit)', + 'libc.so.6(GLIBC_2.2.5)(64bit)', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1', + ] + } +) + +SHLIBPOLICY2 = get_tested_mock_package( + name='libslp-missing-suffix', + files={ + '/usr/lib64/hello': {'is_dir': True}, + '/usr/lib64/hello/libhello2.so': {'content-path': 'files/shlib_policy/libhello2.so'}, + '/usr/lib64/libhello.so': {'content-path': 'files/shlib_policy/libhello.so'}, + '/usr/lib64/libhello2.so': {'content-path': 'files/shlib_policy/libhello2.so'} + }, + header={ + 'requires': [ + 'libc.so.6()(64bit)', + 'libc.so.6(GLIBC_2.2.5)(64bit)', + 'libsparta.so.2', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsZstd) <= 5.4.18-1' + ] + } +) + +SHLIBPOLICY3 = get_tested_mock_package( + name='libslp1234', + files={ + '/usr/lib64/hello': {'is_dir': True}, + '/usr/lib64/hello/libhello2.so': {'content-path': 'files/shlib_policy/libhello2.so'}, + '/usr/lib64/libhello.so': {'content-path': 'files/shlib_policy/libhello.so'}, + '/usr/lib64/libhello2.so': {'content-path': 'files/shlib_policy/libhello2.so'} + }, + header={ + 'requires': [ + 'libc.so.6()(64bit)', + 'libc.so.6(GLIBC_2.2.5)(64bit)', + 'libsparta.so.2 = 1.23', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsZstd) <= 5.4.18-1' + ] + } +) diff --git a/test/test_shlib_policy.py b/test/test_shlib_policy.py index 3538922a9..e4f806dc2 100644 --- a/test/test_shlib_policy.py +++ b/test/test_shlib_policy.py @@ -1,8 +1,9 @@ +from mockdata.mock_shlib_policy import SHLIBPOLICY, SHLIBPOLICY2, SHLIBPOLICY3 import pytest from rpmlint.checks.SharedLibraryPolicyCheck import SharedLibraryPolicyCheck from rpmlint.filter import Filter -from Testing import CONFIG, get_tested_package +from Testing import CONFIG @pytest.fixture(scope='function', autouse=True) @@ -13,25 +14,25 @@ def slpcheck(): return output, test -@pytest.mark.parametrize('package', ['binary/libtest1']) -def test_shlib_policy_wrong_name(tmp_path, package, slpcheck): +@pytest.mark.parametrize('package', [SHLIBPOLICY]) +def test_shlib_policy_wrong_name(package, slpcheck): output, test = slpcheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'W: shlib-unversioned-lib libtest.so.1x' in out -@pytest.mark.parametrize('package', ['binary/libslp-missing-suffix']) -def test_shlib_policy_missing_suffix(tmp_path, package, slpcheck): +@pytest.mark.parametrize('package', [SHLIBPOLICY2]) +def test_shlib_policy_missing_suffix(package, slpcheck): output, test = slpcheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: shlib-policy-excessive-dependency libsparta.so.2' in out -@pytest.mark.parametrize('package', ['binary/libslp1234']) -def test_shlib_policy_errors(tmp_path, package, slpcheck): +@pytest.mark.parametrize('package', [SHLIBPOLICY3]) +def test_shlib_policy_errors(package, slpcheck): output, test = slpcheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'W: shlib-fixed-dependency libsparta.so.2 = 1.23' in out From 21d68e721a1b11fcacbbbf37470cbb2d1305cace Mon Sep 17 00:00:00 2001 From: Luz Marina Date: Tue, 20 Aug 2024 12:46:17 +0200 Subject: [PATCH 4/5] Replace bin in test_files.py Also, creating a mock file to improve code cleanup of the test_files.py file. --- rpmlint/pkg.py | 27 +- test/files/README1.gz | Bin 0 -> 43 bytes test/files/README2.bz2 | Bin 0 -> 53 bytes test/files/netmask/errors.c | 106 ++++++ test/files/netmask/errors.h | 45 +++ test/files/netmask/main.c | 372 +++++++++++++++++++ test/files/netmask/netmask.c | 593 ++++++++++++++++++++++++++++++ test/files/netmask/netmask.h | 25 ++ test/files/shlib2/libfoo-2.so | Bin 0 -> 15360 bytes test/files/shlib2/libfoo-2.so.foo | 1 + test/files/shlib2/libfoo.so | 1 + test/files/shlib2/libfoo.so.1 | Bin 0 -> 14056 bytes test/files/x.typelib | 0 test/mockdata/mock_files.py | 536 +++++++++++++++++++++++++++ test/test_files.py | 207 ++++------- 15 files changed, 1770 insertions(+), 143 deletions(-) create mode 100644 test/files/README1.gz create mode 100644 test/files/README2.bz2 create mode 100644 test/files/netmask/errors.c create mode 100644 test/files/netmask/errors.h create mode 100644 test/files/netmask/main.c create mode 100644 test/files/netmask/netmask.c create mode 100644 test/files/netmask/netmask.h create mode 100755 test/files/shlib2/libfoo-2.so create mode 100644 test/files/shlib2/libfoo-2.so.foo create mode 120000 test/files/shlib2/libfoo.so create mode 100755 test/files/shlib2/libfoo.so.1 create mode 100644 test/files/x.typelib create mode 100644 test/mockdata/mock_files.py diff --git a/rpmlint/pkg.py b/rpmlint/pkg.py index 641a35fcb..b5136857c 100644 --- a/rpmlint/pkg.py +++ b/rpmlint/pkg.py @@ -494,6 +494,17 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): self.cleanup() + def check_versioned_dep(self, name, version): + # try to match name%_isa as well (e.g. 'foo(x86-64)', 'foo(x86-32)') + name_re = re.compile(r'^%s(\(\w+-\d+\))?$' % re.escape(name)) + for d in self.requires + self.prereq: + if name_re.match(d[0]): + if d[1] & rpm.RPMSENSE_EQUAL != rpm.RPMSENSE_EQUAL \ + or d[2][1] != version: + return False + return True + return False + class Pkg(AbstractPkg): _magic_from_compressed_re = re.compile(r'\([^)]+\s+compressed\s+data\b') @@ -715,17 +726,6 @@ def readlink(self, pkgfile): result = self.files.get(linkpath) return result - def check_versioned_dep(self, name, version): - # try to match name%_isa as well (e.g. 'foo(x86-64)', 'foo(x86-32)') - name_re = re.compile(r'^%s(\(\w+-\d+\))?$' % re.escape(name)) - for d in self.requires + self.prereq: - if name_re.match(d[0]): - if d[1] & rpm.RPMSENSE_EQUAL != rpm.RPMSENSE_EQUAL \ - or d[2][1] != version: - return False - return True - return False - def get_installed_pkgs(name): """Get list of installed package objects by name.""" @@ -877,14 +877,15 @@ def create_files(self, files): self._mock_file(path, file) def add_dir(self, path, metadata=None): - pkgdir = PkgFile(path) + name = path + pkgdir = PkgFile(name) pkgdir.magic = 'directory' path = os.path.join(self.dir_name(), path.lstrip('/')) os.makedirs(Path(path), exist_ok=True) pkgdir.path = path - self.files[path] = pkgdir + self.files[name] = pkgdir if metadata: for k, v in metadata.items(): diff --git a/test/files/README1.gz b/test/files/README1.gz new file mode 100644 index 0000000000000000000000000000000000000000..b7d45a7874b815cbbedca99cb8e192f66297d1aa GIT binary patch literal 43 ycmb2|=HNI#At{!DImp$~#n;u4;rIXk#)S=yjf$cj-HkK2I~d~}^_oQ(7#ILaI}Sns literal 0 HcmV?d00001 diff --git a/test/files/README2.bz2 b/test/files/README2.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..b5f29b0ddba9d164d31381a0cc4ed3bcfb1a476b GIT binary patch literal 53 zcmZ>Y%CIzaj8qGboWaKRnt_4)WWxag0R|=p4+aLt1q@0?W(%B|bQq$p>ecBz=_**L JXuu + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include "errors.h" +#include "config.h" + + +/* compatibility section */ +#ifdef HAVE_SYSLOG_H +# include +#else /* HAVE_SYSLOG_H */ +#warning no syslog facility? Errors will go to stderr. +# define syslog(x,y,z) +# define LOG_DEBUG 7 +# define LOG_WARNING 4 +# define LOG_ERR 3 +#endif + +#ifndef HAVE_VPRINTF +#error no vprintf? not ANSI C3.159-1989 (``ANSI C'') compliant? +#endif + +#ifndef HAVE_STRERROR +#define strerror(x) "system error" +#endif +/* end compatibility section */ + +static char *progname = NULL; + +static int show_status = 0; +static int use_syslog = 0; + +static int message(int, const char *); + +int initerrors(char *pn, int type, int stat) { +#ifdef HAVE_SYSLOG_H + if(type == 0 || type == 1) use_syslog = type; +#endif /* HAVE_SYSLOG_H */ + if(pn != NULL) progname = pn; + if(stat == 0 || stat == 1) show_status = stat; + return(0); +} + +int status(const char *fmt, ...) { + static char buf[1024]; + va_list args; + + if(!show_status) return(0); + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + return(message(LOG_DEBUG, buf)); +} + +int warn(const char *fmt, ...) { + static char buf[1024]; + va_list args; + + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + return(message(LOG_WARNING, buf)); +} + +int panic(const char *fmt, ...) { + static char buf[1024]; + va_list args; + + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + message(LOG_ERR, buf); + exit(1); +} + +int message(int priority, const char *msg) { + char buf[1024]; + + /* only handle errno if this is not an informational message */ + if(errno && priority < 5) { + sprintf(buf, "%s: %s", msg, strerror(errno)); + errno = 0; + } else strcpy(buf, msg); + if(use_syslog) syslog(priority, "%s", buf); + else fprintf(stderr, "%s: %s\n", progname, buf); + return(0); +} diff --git a/test/files/netmask/errors.h b/test/files/netmask/errors.h new file mode 100644 index 000000000..c85d6f9d5 --- /dev/null +++ b/test/files/netmask/errors.h @@ -0,0 +1,45 @@ +/* errors.h -- error message handlers. + Copyright (C) 1998 Robert Stone + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _HAVE_ERRORS_H +#define _HAVE_ERRORS_H + +/* call initerrors before using these other functions + * + * these functions seem pretty straightforward to me, the messaging + * functions take sprintf formatted strings and have a limit of + * 1024 byte long error messages. + * progname should be set to argv[0] + * if progname is NULL, it is unchanged + * type == 0 for stderr + * type == 1 for syslog + * otherwise type is unchanged + * stat == 0 to skip status reporting + * stat == 1 to print status messages + * otherwise stat is unchanged + * defaults: progname = NULL, type = 0, stat = 0 */ +int initerrors(char *progname, int type, int stat); + +int status(const char *fmt, ...); + /* print a status message */ + +int warn(const char *fmt, ...); + /* print a warning message */ + +int panic(const char *fmt, ...); + /* print an error and exit */ +#endif diff --git a/test/files/netmask/main.c b/test/files/netmask/main.c new file mode 100644 index 000000000..84638ac71 --- /dev/null +++ b/test/files/netmask/main.c @@ -0,0 +1,372 @@ +/* main.c - a netmask generator + * + * Copyright (c) 2013 Robert Stone , + * Tom Lear + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "netmask.h" +#include "errors.h" +#include "config.h" + +struct addrmask { + u_int32_t neta; + u_int32_t mask; + struct addrmask *next; + struct addrmask *prev; +}; + +struct option longopts[] = { + { "version", 0, 0, 'v' }, + { "help", 0, 0, 'h' }, + { "debug", 0, 0, 'd' }, + { "standard", 0, 0, 's' }, + { "cidr", 0, 0, 'c' }, + { "cisco", 0, 0, 'i' }, + { "range", 0, 0, 'r' }, + { "hex", 0, 0, 'x' }, + { "octal", 0, 0, 'o' }, + { "binary", 0, 0, 'b' }, + { "nodns", 0, 0, 'n' }, + { "files", 0, 0, 'f' }, +// { "max", 1, 0, 'M' }, +// { "min", 1, 0, 'm' }, + { NULL, 0, 0, 0 } +}; + +typedef enum { + OUT_STD, OUT_CIDR, OUT_CISCO, OUT_RANGE, OUT_HEX, OUT_OCTAL, OUT_BINARY +} output_t; + +char version[] = "netmask, version "VERSION; +char vversion[] = __DATE__" "__TIME__; +char usage[] = "Try `%s --help' for more information.\n"; +char *progname = NULL; + +void disp_std(int domain, nm_addr *n, nm_addr *m) { + char nb[INET6_ADDRSTRLEN + 1], + mb[INET6_ADDRSTRLEN + 1]; + + inet_ntop(domain, n, nb, INET6_ADDRSTRLEN); + inet_ntop(domain, m, mb, INET6_ADDRSTRLEN); + printf("%15s/%-15s\n", nb, mb); +} +static void disp_cidr(int domain, nm_addr *n, nm_addr *m) { + char nb[INET6_ADDRSTRLEN + 1]; + int cidr = 0; + + inet_ntop(domain, n, nb, INET6_ADDRSTRLEN); + if(domain == AF_INET) { + uint32_t mask; + for(mask = ntohl(m->s.s_addr); mask; mask <<= 1) + cidr++; + } else { + uint8_t i, c; + for(i = 0; i < 16; i++) + for(c = m->s6.s6_addr[i]; c; c <<= 1) + cidr++; + } + printf("%15s/%d\n", nb, cidr); +} + +static void disp_cisco(int domain, nm_addr *n, nm_addr *m) { + char nb[INET6_ADDRSTRLEN + 1], + mb[INET6_ADDRSTRLEN + 1]; + int i; + + if(domain == AF_INET6) + for(i = 0; i < 16; i++) + m->s6.s6_addr[i] = ~m->s6.s6_addr[i]; + else + m->s.s_addr = ~m->s.s_addr; + + inet_ntop(domain, n, nb, INET6_ADDRSTRLEN); + inet_ntop(domain, m, mb, INET6_ADDRSTRLEN); + printf("%15s %-15s\n", nb, mb); +} + +static void range_num(char *dst, uint8_t *src) { + /* roughly we must convert a 17 digit base 256 number + * to a 39 digit base 10 number. */ + char digits[41] = { 0 }; /* ceil(17 * log(256) / log(10)) == 41 */ + int i, j, z, overflow; + + for(i = 0; i < 17; i++) { + overflow = 0; + for(j = sizeof(digits) - 1; j >= 0; j--) { + int tmp = digits[j] * 256 + overflow; + digits[j] = tmp % 10; + overflow = tmp / 10; + } + + overflow = src[i]; + for(j = sizeof(digits) - 1; j >= 0; j--) { + if(!overflow) + break; + int sum = digits[j] + overflow; + digits[j] = sum % 10; + overflow = sum / 10; + } + } + /* convert to string */ + z = 1; + for(i = 0; i < sizeof(digits); i++) { + if(z && digits[i] == 0) + continue; + z = 0; + *dst++ = '0' + digits[i]; + } + /* special case for zero */ + if(z) + *dst++ = '0'; + *dst++ = '\0'; +} + +static void disp_range(int domain, nm_addr *n, nm_addr *m) { + char nb[INET6_ADDRSTRLEN + 1], + mb[INET6_ADDRSTRLEN + 1], + ns[42]; + uint64_t over = 1; + uint8_t ra[17] = { 0 }; + int i; + + if(domain == AF_INET6) { + for(i = 15; i >= 0; i--) { + m->s6.s6_addr[i] = ~m->s6.s6_addr[i]; + over += m->s6.s6_addr[i]; + m->s6.s6_addr[i] |= n->s6.s6_addr[i]; + ra[i + 1] = over & 0xff; + over >>= 8; + } + ra[0] = over; + } else { + over += htonl(~m->s.s_addr); + for(i = 16; i > 11; i--) { + ra[i] = over & 0xff; + over >>= 8; + } + m->s.s_addr = n->s.s_addr | ~m->s.s_addr; + } + range_num(ns, ra); + inet_ntop(domain, n, nb, INET6_ADDRSTRLEN); + inet_ntop(domain, m, mb, INET6_ADDRSTRLEN); + printf("%15s-%-15s (%s)\n", nb, mb, ns); +} + +static void disp_hex(int domain, nm_addr *n, nm_addr *m) { + if(domain == AF_INET) { + printf("0x%08x/0x%08x\n", htonl(n->s.s_addr), htonl(m->s.s_addr)); + } else { + printf("0x%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x/" + "0x%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x\n", + n->s6.s6_addr[0], n->s6.s6_addr[1], n->s6.s6_addr[2], n->s6.s6_addr[3], + n->s6.s6_addr[4], n->s6.s6_addr[5], n->s6.s6_addr[6], n->s6.s6_addr[7], + n->s6.s6_addr[8], n->s6.s6_addr[9], n->s6.s6_addr[10], n->s6.s6_addr[11], + n->s6.s6_addr[12], n->s6.s6_addr[13], n->s6.s6_addr[14], n->s6.s6_addr[15], + + m->s6.s6_addr[0], m->s6.s6_addr[1], m->s6.s6_addr[2], m->s6.s6_addr[3], + m->s6.s6_addr[4], m->s6.s6_addr[5], m->s6.s6_addr[6], m->s6.s6_addr[7], + m->s6.s6_addr[8], m->s6.s6_addr[9], m->s6.s6_addr[10], m->s6.s6_addr[11], + m->s6.s6_addr[12], m->s6.s6_addr[13], m->s6.s6_addr[14], m->s6.s6_addr[15]); + } +} + +static void disp_octal(int domain, nm_addr *n, nm_addr *m) { + if(domain == AF_INET) { + printf("0%10o/0%10o\n", htonl(n->s.s_addr), htonl(m->s.s_addr)); + } else { + printf("0%03x%03x%03x%03x%03x%03x%03x%03x" + "%03x%03x%03x%03x%03x%03x%03x%03x/" + "0%03x%03x%03x%03x%03x%03x%03x%03x" + "%03x%03x%03x%03x%03x%03x%03x%03x\n", + n->s6.s6_addr[0], n->s6.s6_addr[1], n->s6.s6_addr[2], n->s6.s6_addr[3], + n->s6.s6_addr[4], n->s6.s6_addr[5], n->s6.s6_addr[6], n->s6.s6_addr[7], + n->s6.s6_addr[8], n->s6.s6_addr[9], n->s6.s6_addr[10], n->s6.s6_addr[11], + n->s6.s6_addr[12], n->s6.s6_addr[13], n->s6.s6_addr[14], n->s6.s6_addr[15], + + m->s6.s6_addr[0], m->s6.s6_addr[1], m->s6.s6_addr[2], m->s6.s6_addr[3], + m->s6.s6_addr[4], m->s6.s6_addr[5], m->s6.s6_addr[6], m->s6.s6_addr[7], + m->s6.s6_addr[8], m->s6.s6_addr[9], m->s6.s6_addr[10], m->s6.s6_addr[11], + m->s6.s6_addr[12], m->s6.s6_addr[13], m->s6.s6_addr[14], m->s6.s6_addr[15]); + } +} + +static void bin_str(char *dst, uint8_t *src, int len) { + int i; + int j; + for(i = 0; i < len; i++) { + for(j = 7; j >= 0; j--) { + *dst++ = src[i] & (1 << j) ? '1' : '0'; + } + *dst++ = ' '; + } + /* replace the last space with a string terminator */ + dst[-1] = '\0'; +} + +static void disp_binary(int domain, nm_addr *n, nm_addr *m) { + char ns[144], + ms[144]; + uint8_t bits[16]; + + if(domain == AF_INET) { + unsigned long l; + l = htonl(n->s.s_addr); + bits[0] = 0xff & (l >> 24); + bits[1] = 0xff & (l >> 16); + bits[2] = 0xff & (l >> 8); + bits[3] = 0xff & (l >> 0); + bin_str(ns, bits, 4); + l = htonl(m->s.s_addr); + bits[0] = 0xff & (l >> 24); + bits[1] = 0xff & (l >> 16); + bits[2] = 0xff & (l >> 8); + bits[3] = 0xff & (l >> 0); + bin_str(ms, bits, 4); + } else { + bin_str(ns, n->s6.s6_addr, 16); + bin_str(ms, m->s6.s6_addr, 16); + } + printf("%s / %s\n", ns, ms); +} + +void display(NM nm, output_t style) { + void (*disp)(int, nm_addr *, nm_addr *) = NULL; + + switch(style) { + case OUT_STD: disp = &disp_std; break; + case OUT_CIDR: disp = &disp_cidr; break; + case OUT_CISCO: disp = &disp_cisco; break; + case OUT_RANGE: disp = &disp_range; break; + case OUT_HEX: disp = &disp_hex; break; + case OUT_OCTAL: disp = &disp_octal; break; + case OUT_BINARY: disp = &disp_binary; break; + default: return; + } + nm_walk(nm, disp); +} + +static inline void add_entry(NM *nm, const char *str, int dns) { + NM new = nm_new_str(str, dns); + if(new) + *nm = nm_merge(*nm, new); + else + warn("parse error \"%s\"", str); +} + +int main(int argc, char *argv[]) { + int optc, h = 0, v = 0, f = 0, dns = NM_USE_DNS, lose = 0; +// u_int32_t min = ~0, max = 0; + output_t output = OUT_CIDR; + + progname = argv[0]; + initerrors(progname, 0, 0); /* stderr, nostatus */ + while((optc = getopt_long(argc, argv, "shoxdrvbincM:m:f", longopts, + (int *) NULL)) != EOF) switch(optc) { + case 'h': h = 1; break; + case 'v': v++; break; + case 'n': dns = 0; break; + case 'f': f = 1; break; +// case 'M': max = mspectou32(optarg); break; +// case 'm': min = mspectou32(optarg); break; + case 'd': + initerrors(NULL, -1, 1); /* showstatus */ + break; + case 's': output = OUT_STD; break; + case 'c': output = OUT_CIDR; break; + case 'i': output = OUT_CISCO; break; + case 'r': output = OUT_RANGE; break; + case 'x': output = OUT_HEX; break; + case 'o': output = OUT_OCTAL; break; + case 'b': output = OUT_BINARY; break; + default: lose = 1; break; + } + if(v) { + if(v == 1) fprintf(stderr, "%s\n", version); + else fprintf(stderr, "%s, %s\n", version, vversion); + if(!h) exit(0); + } + if(h) { + fprintf(stderr, + "This is netmask, an address netmask generation utility\n" + "Usage: %s spec [spec ...]\n" + " -h, --help\t\t\tPrint a summary of the options\n" + " -v, --version\t\t\tPrint the version number\n" + " -d, --debug\t\t\tPrint status/progress information\n" + " -s, --standard\t\tOutput address/netmask pairs\n" + " -c, --cidr\t\t\tOutput CIDR format address lists\n" + " -i, --cisco\t\t\tOutput Cisco style address lists\n" + " -r, --range\t\t\tOutput ip address ranges\n" + " -x, --hex\t\t\tOutput address/netmask pairs in hex\n" + " -o, --octal\t\t\tOutput address/netmask pairs in octal\n" + " -b, --binary\t\t\tOutput address/netmask pairs in binary\n" + " -n, --nodns\t\t\tDisable DNS lookups for addresses\n" + " -f, --files\t\t\tTreat arguments as input files\n" +// " -M, --max mask\t\tLimit maximum mask size\n" +// " -m, --min mask\t\tLimit minimum mask size (drop small ranges)\n" + "Definitions:\n" + " a spec can be any of:\n" + " address\n" + " address:address\n" + " address:+address\n" + " address/mask\n" + " an address can be any of:\n" + " N\t\tdecimal number\n" + " 0N\t\toctal number\n" + " 0xN\t\thex number\n" + " N.N.N.N\tdotted quad\n" + " hostname\tdns domain name\n" + " a mask is the number of bits set to one from the left\n", progname); + exit(0); + } + if(lose || optind == argc) { + fprintf(stderr, usage, progname); + exit(1); + } + NM nm = NULL; + for(;optind < argc; optind++) { + if(f) { + char buf[1024]; + FILE *fp = strncmp(argv[optind], "-", 2) ? + fopen(argv[optind], "r") : stdin; + if(!fp) { + fprintf(stderr, "fopen: %s: %s\n", + argv[optind], strerror(errno)); + continue; + } + while(fscanf(fp, "%1023s", buf) != EOF) + add_entry(&nm, buf, dns); + } else + add_entry(&nm, argv[optind], dns); + } + display(nm, output); + return(0); +} + diff --git a/test/files/netmask/netmask.c b/test/files/netmask/netmask.c new file mode 100644 index 000000000..e2705c440 --- /dev/null +++ b/test/files/netmask/netmask.c @@ -0,0 +1,593 @@ +/* netmask.c - a netmask generator + * + * Copyright (c) 2013 Robert Stone , + * Tom Lear + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include + +#include + +#include "errors.h" +#include "netmask.h" + +typedef struct { + uint64_t h; + uint64_t l; +} u128_t; + +static inline u128_t u128_add(u128_t x, u128_t y, int *carry) { + /* this relies on the sum being greater than both terms of the + * addition, otherwise an overflow must have occurred. */ + u128_t rv; + rv.l = x.l + y.l; + if(rv.l < x.l || rv.l < y.l) + rv.h = 1; + else + rv.h = 0; + rv.h += x.h + y.h; + if(carry) { + if(rv.h < x.h || rv.h < y.h) + *carry = 1; + else + *carry = 0; + } + return rv; +} + +static inline u128_t u128_and(u128_t x, u128_t y) { + u128_t rv; + rv.h = x.h & y.h; + rv.l = x.l & y.l; + return rv; +} + +static inline u128_t u128_or(u128_t x, u128_t y) { + u128_t rv; + rv.h = x.h | y.h; + rv.l = x.l | y.l; + return rv; +} + +static inline u128_t u128_xor(u128_t x, u128_t y) { + u128_t rv; + rv.h = x.h ^ y.h; + rv.l = x.l ^ y.l; + return rv; +} + +static inline u128_t u128_neg(u128_t v) { + u128_t rv; + rv.h = ~v.h; + rv.l = ~v.l; + return rv; +} + +static inline u128_t u128_lsh(u128_t v, uint8_t d) { + u128_t rv; + rv.h = v.h << 1 | v.l >> 63; + rv.l = v.l << 1; + return rv; +} + +static inline int u128_cmp(u128_t x, u128_t y) { + /* return -1, 0, 1 on sort order */ + if(x.h < y.h) + return -1; + if(x.h > y.h) + return 1; + if(x.l < y.l) + return -1; + if(x.l > y.l) + return 1; + return 0; +} + +static inline u128_t u128_of_s6(struct in6_addr *s6) { + u128_t rv; + rv.h = (((uint64_t)s6->s6_addr[0]) << 56) | + (((uint64_t)s6->s6_addr[1]) << 48) | + (((uint64_t)s6->s6_addr[2]) << 40) | + (((uint64_t)s6->s6_addr[3]) << 32) | + (((uint64_t)s6->s6_addr[4]) << 24) | + (((uint64_t)s6->s6_addr[5]) << 16) | + (((uint64_t)s6->s6_addr[6]) << 8) | + (((uint64_t)s6->s6_addr[7]) << 0); + rv.l = (((uint64_t)s6->s6_addr[8]) << 56) | + (((uint64_t)s6->s6_addr[9]) << 48) | + (((uint64_t)s6->s6_addr[10]) << 40) | + (((uint64_t)s6->s6_addr[11]) << 32) | + (((uint64_t)s6->s6_addr[12]) << 24) | + (((uint64_t)s6->s6_addr[13]) << 16) | + (((uint64_t)s6->s6_addr[14]) << 8) | + (((uint64_t)s6->s6_addr[15]) << 0); + return rv; +} +static inline struct in6_addr s6_of_u128(u128_t v) { + struct in6_addr s6; + s6.s6_addr[0] = 0xff & (v.h >> 56); + s6.s6_addr[1] = 0xff & (v.h >> 48); + s6.s6_addr[2] = 0xff & (v.h >> 40); + s6.s6_addr[3] = 0xff & (v.h >> 32); + s6.s6_addr[4] = 0xff & (v.h >> 24); + s6.s6_addr[5] = 0xff & (v.h >> 16); + s6.s6_addr[6] = 0xff & (v.h >> 8); + s6.s6_addr[7] = 0xff & (v.h >> 0); + s6.s6_addr[8] = 0xff & (v.l >> 56); + s6.s6_addr[9] = 0xff & (v.l >> 48); + s6.s6_addr[10] = 0xff & (v.l >> 40); + s6.s6_addr[11] = 0xff & (v.l >> 32); + s6.s6_addr[12] = 0xff & (v.l >> 24); + s6.s6_addr[13] = 0xff & (v.l >> 16); + s6.s6_addr[14] = 0xff & (v.l >> 8); + s6.s6_addr[15] = 0xff & (v.l >> 0); + return s6; +} + +static inline u128_t u128_lit(uint64_t h, uint64_t l) { + u128_t rv; + rv.h = h; + rv.l = l; + return rv; +} + +static inline u128_t u128_cidr(uint8_t n) { + u128_t rv; + if(n <= 0) { + rv.h = 0; + rv.l = 0; + } else if(n <= 64) { + rv.h = ~0ULL << (64 - n); + rv.l = 0; + } else if(n <= 128) { + rv.h = ~0ULL; + rv.l = ~0ULL << (128 - n); + } else { + rv.h = ~0ULL; + rv.l = ~0ULL; + } + return rv; +} +static inline int cidr(u128_t u) { + uint64_t v; + int n = 0; + for(v = u.l; v > 0; v <<= 1) n++; + for(v = u.h; v > 0; v <<= 1) n++; + return n; +} + +static inline int chkmask(u128_t v) { + /* this is sort of specialized */ + int i; + u128_t m = u128_lit(~0ULL, ~0ULL); + + for(i = 0; i < 129; i++) { + if(u128_cmp(v, m) == 0) + return 1; + m = u128_lsh(m, 1); + } + return 0; +} + +struct nm { + u128_t neta; + u128_t mask; + int domain; + NM next; +}; + +NM nm_new_v4(struct in_addr *s) { + NM self; + union { + struct in6_addr s6; + uint32_t u32[4]; + } v; + + v.u32[0] = 0; + v.u32[1] = 0; + v.u32[2] = htonl(0x0000ffff); + v.u32[3] = s->s_addr; + self = nm_new_v6(&v.s6); + self->domain = AF_INET; + return self; +} + +NM nm_new_v6(struct in6_addr *s6) { + NM self = (NM)malloc(sizeof(struct nm)); + self->neta = u128_of_s6(s6); + self->mask = u128_cidr(128); + self->domain = AF_INET6; + self->next = (NM)0; + return self; +} + +/* is "a" a subset of "b"? */ +static inline int subset_of(NM a, NM b) { + return( + u128_cmp(a->mask, b->mask) >= 0 && + u128_cmp(b->neta, u128_and(a->neta, b->mask)) == 0 + ); +} +/* are "a" and "b" a joinable pair? */ +static inline int joinable_pair(NM a, NM b) { + return( + /* nets have the same mask */ + u128_cmp(a->mask, b->mask) == 0 && + /* but are distinct */ + u128_cmp(a->neta, b->neta) != 0 && + /* and would both be subsets of the same mask << 1 */ + u128_cmp(u128_lit(0, 0), u128_and( + u128_xor(a->neta, b->neta), + u128_lsh(a->mask, 1) + )) == 0 + ); +} + +/* this is slightly complicated because an NM can outgrow it's initial + * v4 state, but if it doesn't, we want to retain the fact that it + * was and remained v4. */ +static inline int is_v4(NM self) { + struct nm v4map; + + v4map.neta = u128_lit(0, 0x0000ffff00000000ULL); + v4map.mask = u128_cidr(96); + + return(self->domain == AF_INET && subset_of(self, &v4map)); +} + +NM nm_new_ai(struct addrinfo *ai) { + NM self = NULL; + struct addrinfo *cur; + + for(cur = ai; cur; cur = cur->ai_next) { + switch(cur->ai_family) { + case AF_INET: + self = nm_merge(self, nm_new_v4(&( + (struct sockaddr_in *)cur->ai_addr + )->sin_addr)); + break; + case AF_INET6: + self = nm_merge(self, nm_new_v6(&( + (struct sockaddr_in6 *)cur->ai_addr + )->sin6_addr)); + break; + default: + panic("unknown ai_family %d in struct addrinfo", + cur->ai_family); + } + } + return self; +} + +static inline NM parse_addr(const char *str, int flags) { + struct in6_addr s6; + struct in_addr s; + + if(inet_pton(AF_INET6, str, &s6)) + return nm_new_v6(&s6); + + if(inet_aton(str, &s)) + return nm_new_v4(&s); + + if(NM_USE_DNS & flags) { + struct addrinfo in, *out; + + memset(&in, 0, sizeof(struct addrinfo)); + in.ai_family = AF_UNSPEC; + if(getaddrinfo(str, NULL, &in, &out) == 0) { + NM self = nm_new_ai(out); + freeaddrinfo(out); + return self; + } + } + return NULL; +} + +static inline int parse_mask(NM self, const char *str, int flags) { + char *p; + uint32_t v; + struct in6_addr s6; + struct in_addr s; + + v = strtoul(str, &p, 0); + if(*p == '\0') { + /* read it as a CIDR value */ + if(is_v4(self)) { + if(v < 0 || v > 32) return 0; + v += 96; + } else { + if(v < 0 || v > 128) return 0; + } + self->mask = u128_cidr(v); + } else if(inet_pton(AF_INET6, str, &s6)) { + self->mask = u128_of_s6(&s6); + /* flip cisco style masks */ + if(u128_cmp( + u128_lit(0, 0), + u128_and( + u128_lit(1ULL << 63, 1), + u128_xor(u128_lit(0, 1), self->mask) + ) + ) == 0) { + self->mask = u128_neg(self->mask); + } + self->domain = AF_INET6; + } else if(self->domain == AF_INET && inet_aton(str, &s)) { + v = htonl(s.s_addr); + if(v & 1 && ~v >> 31) /* flip cisco style masks */ + v = ~v; + /* since mask is currently all 1s, mask ^ ~m will + * set the low 32. */ + self->mask = u128_xor(self->mask, u128_lit(0, ~v)); + } else { + return 0; + } + if(!chkmask(self->mask)) + return 0; + /* apply mask to neta */ + self->neta = u128_and(self->neta, self->mask); + return 1; +} + +/* widen the mask as much as possible without including addresses below + * neta or above max. return one if more ranges are needed to complete + * the span or zero if this nm includes max. */ +static inline int nm_widen(NM self, u128_t max, u128_t *last) { + u128_t mask, neta, bcst; + int cmp = u128_cmp(self->neta, max); + + while(cmp < 0) { + /* attempt widening by one bit */ + mask = u128_lsh(self->mask, 1); + neta = u128_and(self->neta, mask); + bcst = u128_or(self->neta, u128_neg(mask)); + /* check ranges */ + if(u128_cmp(neta, self->neta) < 0) + break; + cmp = u128_cmp(bcst, max); + if(cmp > 0) + break; + /* successful attempt */ + self->mask = mask; + *last = bcst; + status("widen %016llx %016llx/%d", self->neta.h, self->neta.l, cidr(self->mask)); + if(cmp == 0) + break; + } + return cmp; +} + +static inline void nm_order(NM *low, NM *high) { + if(u128_cmp((*low)->neta, (*high)->neta) > 0) { + NM tmp = *low; + *low = *high; + *high = tmp; + } +} + +/* convert first and last into a list from first to last. (both these + * should be single addresses, not lists.) */ +static inline NM nm_seq(NM first, NM last) { + /* if first is higher than last, swap them (legacy) */ + nm_order(&first, &last); + NM cur = first; + u128_t pos = cur->neta; + u128_t one = u128_lit(0, 1); + u128_t max = last->neta; + int domain = is_v4(first) && is_v4(last) ? AF_INET : AF_INET6; + + free(last); + while(nm_widen(cur, max, &pos)) { + cur->next = (NM)malloc(sizeof(struct nm)); + cur = cur->next; + cur->neta = u128_add(pos, one, NULL); + cur->mask = u128_cidr(128); + cur->domain = domain; + cur->next = NULL; + } + return first; +} + +NM nm_new_str(const char *str, int flags) { + char *p, buf[2048]; + NM self; + + if((p = strchr(str, '/'))) { /* mask separator */ + strncpy(buf, str, p - str); + buf[p - str] = '\0'; + self = parse_addr(buf, flags); + if(!self) + return NULL; + if(!parse_mask(self, p + 1, flags)) { + free(self); + return NULL; + } + return self; + } else if((p = strchr(str, ','))) { /* new range character */ + NM top; + int add; + + strncpy(buf, str, p - str); + buf[p - str] = '\0'; + self = parse_addr(buf, flags); + if(!self) + return NULL; + if(p[1] == '+') + add = 1; + else + add = 0; + top = parse_addr(p + add + 1, flags); + if(!top) { + free(self); + return NULL; + } + if(add) { + int carry; + if(is_v4(top)) + top->neta.l &= 0xffffffffULL; + top->neta = u128_add(self->neta, top->neta, &carry); + if(carry) { + free(self); + free(top); + return NULL; + } + } + return nm_seq(self, top); + } else if((self = parse_addr(str, flags))) { + return self; + } else if((p = strchr(str, ':'))) { /* old range character (sloppy) */ + NM top; + int add; + strncpy(buf, str, p - str); + buf[p - str] = '\0'; + self = parse_addr(buf, flags); + if(!self) + return NULL; + if(p[1] == '+') { + add = 1; + if(p[2] == '-') { + /* this is a pretty special reverse compatibility + * situation. N:+-5" would actually emit the range from + * N-5 to N because strtoul() hilariously accepts + * negative numbers and the original code never detected + * overflow and things just happened to work out. */ + struct in_addr s; + char *endp; + uint32_t v = self->neta.l + strtoul(p + 2, &endp, 0); + if(*endp == '\0') { + s.s_addr = htonl(v); + top = nm_new_v4(&s); + if(!top) { + free(self); + return NULL; + } + return nm_seq(self, top); + } + } + } else { + add = 0; + } + + top = parse_addr(p + add + 1, flags); + if(!top) { + free(self); + return NULL; + } + if(add) { + int carry; + if(is_v4(top)) + top->neta.l &= 0xffffffffULL; + top->neta = u128_add(self->neta, top->neta, &carry); + if(carry) { + free(self); + free(top); + return NULL; + } + } + return nm_seq(self, top); + } else { + return NULL; + } +} + +NM nm_merge(NM dst, NM src) { + /* both lists are ordered and non-overlapping. Knit them into a + * single ordered, non-overlapping list. */ + NM tmp; + NM *pos = &dst; /* double indirect pointer simplifies list insertion + logic. */ + while(src) { + if(*pos == NULL) { + /* remains of src go to tail of dst */ + tmp = src; + src = *pos; + *pos = tmp; + } else if(subset_of(src, *pos)) { + status("found %016llx %016llx/%d a subset of %016llx %016llx/%d", src->neta.h, src->neta.l, cidr(src->mask), (*pos)->neta.h, (*pos)->neta.l, cidr((*pos)->mask)); + /* drop src elt on the floor */ + if(src->domain != AF_INET) /* may need to promote domain */ + (*pos)->domain = src->domain; + tmp = src; + src = src->next; + free(tmp); + } else if(subset_of(*pos, src)) { + /* src seems larger, merge the other direction instead */ + tmp = src; + src = *pos; + *pos = tmp; + } else if(joinable_pair(src, *pos)) { + status("joinable %016llx %016llx/%d and %016llx %016llx/%d", src->neta.h, src->neta.l, cidr(src->mask), (*pos)->neta.h, (*pos)->neta.l, cidr((*pos)->mask)); + /* pull the dst elt */ + tmp = *pos; + *pos = (*pos)->next; + if(src->domain == AF_INET) + src->domain = tmp->domain; + free(tmp); + /* widen the src elt */ + src->mask = u128_lsh(src->mask, 1); + src->neta = u128_and(src->neta, src->mask); + /* and merge it back into the src tail */ + tmp = src->next; + src->next = NULL; + src = nm_merge(src, tmp); + /* now the dst scan needs to start over to find preceding + * join candidates. */ + pos = &dst; + /* TODO: there should be a cheaper way to do this than an + * effective double recursion, but the possibility of joins + * cascading backwards makes this difficult */ + } else if(u128_cmp(src->neta, (*pos)->neta) < 0) { + /* src elt goes here in dst list. if top src elt were + * spliced into dst, it may duplicate later elts in dst. + * swap tails instead because src is well formed. */ + tmp = src; + src = *pos; + *pos = tmp; + } else { + /* move down the dst list */ + pos = &(*pos)->next; + } + } + return dst; +} + +void nm_walk(NM self, void (*cb)(int, nm_addr *, nm_addr *)) { + int domain; + nm_addr neta, mask; + + while(self) { + neta.s6 = s6_of_u128(self->neta); + mask.s6 = s6_of_u128(self->mask); + if(is_v4(self)) { + domain = AF_INET; + neta.s.s_addr = htonl( + neta.s6.s6_addr[12] << 24 | + neta.s6.s6_addr[13] << 16 | + neta.s6.s6_addr[14] << 8 | + neta.s6.s6_addr[15] << 0); + mask.s.s_addr = htonl( + mask.s6.s6_addr[12] << 24 | + mask.s6.s6_addr[13] << 16 | + mask.s6.s6_addr[14] << 8 | + mask.s6.s6_addr[15] << 0); + } else { + domain = AF_INET6; + } + cb(domain, &neta, &mask); + self = self->next; + } +} diff --git a/test/files/netmask/netmask.h b/test/files/netmask/netmask.h new file mode 100644 index 000000000..cd0a30467 --- /dev/null +++ b/test/files/netmask/netmask.h @@ -0,0 +1,25 @@ + +#include +#include + +typedef struct nm *NM; + +NM nm_new_v4(struct in_addr *); + +NM nm_new_v6(struct in6_addr *); + +NM nm_new_ai(struct addrinfo *); + +#define NM_USE_DNS 1 + +NM nm_new_str(const char *, int flags); + +NM nm_merge(NM, NM); + +typedef union { + struct in6_addr s6; + struct in_addr s; +} nm_addr; + +void nm_walk(NM, void (*)(int domain, nm_addr *neta, nm_addr *mask)); + diff --git a/test/files/shlib2/libfoo-2.so b/test/files/shlib2/libfoo-2.so new file mode 100755 index 0000000000000000000000000000000000000000..b8a948511f20b21089f8f011e3ea34be5ac9b889 GIT binary patch literal 15360 zcmeHOU1%It6u!Hgw25u9sjW7)Vulhy#co4OG*Z%T+9aLUq}7;01?$ZuyU8x>PuQJc z(uxLZA4(}iT0{^*M5GqMz6c`zv{s6b)(5H3hafFf@FxmN`e4U%X6`qco!yA|AS(C5 z&N=5h=es{=?(Uu4z4yhwf&OSDB2Z#thhQt&;vq>m9)UtW(Ipz`+A7w&v2{zXD(#SR zLJCzcw^7g0$_~pW)g?&y8Fs5Qm`ufRufBX$nUF!=3i6F4ynvA%mGXjW?+Ycti&7Z# zCKYc|@qDS`CzWjQs&)Iw{p{ijYRGmE7Le|k2z%m&opNc|(m066xV~*U>9RuRZ$@ig$-kpLt`JbmaQ)Dzv8PC)B9nd3YI|^H3|E+pmQmB>YZshY)K>p~7)) zk#ZtmEXcBLm24@6+&erdQ|VHAB3ri8rQyNdxndzbY>np9p0Bn?j!j!~JX^4G*&}H& zUM!AUC6UXHlD2tkqFfZ1x0q)O>PBYNyaaw;;jKxpd%$7O@APoau|EdVZw7ERb=|;) z0M7RjWifzbF2bj!&VbH<&VbH<&VbH<&VbH<&VbIqzbgagvF{tqll4Dr5yCuv!Hzm# zn#VqGxa4=z>HL;l&i&Wv8gEOIc8;|1IRu!ey1!xWsrs*2Jho`xMb*8+I#t)`%*Wei zIrfs06#tGJ-}xqs2XC7v7R-x3?ldnh#>~iN^U7^|9aS)>Drj)#$K!3iOZ?gHEV;zg zmV@T8?)z9ZPu#FqngJ$g z)UHoobOv+=bOv+=bOv+=bOv+=bOv+=bOv+=bO!!68Hj9*ZEvU1@PB&7g5xAfc96`F z6hAx8EK4f_=@@UFYw7TvmI+-v{2L>^il-_8w(p-|I$Y<2&RAWn=#Tb zs3iEe9IroqJ<9)23G8DJw}*YgVH`GpSC7&@=%m_b44lWo_+$vbTj7`oi06IT5&Ct& zNO}l<1K953ae@2ld4(7yh3m(>0$yo^S=^bAux|C@#^uiKSu95Ba{aZZxkIh@#^{G#aHLY!>jY@;Z5QJ zgSE;M6V>y9BVwX@UU_)+eDLr!0{i9JMu{zZzt)QIJYh~OFwarPFQn8uPjHKH13>}V zKyQ#*_@-s>9n0Wi>1=|u^Ky(&CzOShsiK_7(W!%+OxeX!Sz1%mVyu{-%%$ygD)H#H zuFl#)d}tvnty0OFk?De6ni1nAE1#CBseFEhC;>}Sq+JmzW&cpmV4v*U-^)iQdY|6k zGq`s*vFO+YK$$8RWyUI`_y7ghKyEsCBKu55HhYJJ+Y2H03>?_iGawK2_dnG)EQfn` z4fIJIrjV6KEZlP%wa;Sw*$Ixy!yY10p2^$RC`r5I$qckY(M~5O3R8*EscbH_Ihzu$ zm9fehkx0!Hi0MhYBod``&SFp`+z}=wb9Q2)Xp4lMo~A43SR~RJmCa0wD6l+=msT$l zI@M?8vt!h5(dHVdIm@<0VzgWiOsv1D@_Ni`UR3e%IR(kT4+jg@V_;iJ;WZfi5v4%# z`oIM|tf#Q~Sk`Z}hJufE9TM#$9(=b_x^&Tt*L3i)?nBP0K<*>GmHg)ltlvq(yfu#$ zD)=0Q%y_VW@G~)<|L~lP^LXKS*pM$1Hy+^Qc`3th3@V88tR)-x z>*V0MgZA+}has~M!sbV`kiFvM2 ze>~v7M~)yL>u#&!BQDH`{XQuigZ>*y&tojZ=eB}{ZQT1H4*peDF+czETta^^E}oxg eJIG($=2?TG21BNM46zo!uhZjy7_5}^F#iu19nPBo literal 0 HcmV?d00001 diff --git a/test/files/shlib2/libfoo-2.so.foo b/test/files/shlib2/libfoo-2.so.foo new file mode 100644 index 000000000..323fae03f --- /dev/null +++ b/test/files/shlib2/libfoo-2.so.foo @@ -0,0 +1 @@ +foobar diff --git a/test/files/shlib2/libfoo.so b/test/files/shlib2/libfoo.so new file mode 120000 index 000000000..a1d0edfb7 --- /dev/null +++ b/test/files/shlib2/libfoo.so @@ -0,0 +1 @@ +libfoo.so.1 \ No newline at end of file diff --git a/test/files/shlib2/libfoo.so.1 b/test/files/shlib2/libfoo.so.1 new file mode 100755 index 0000000000000000000000000000000000000000..7d40b18a3068210b744e057f8dec1f05c9befac0 GIT binary patch literal 14056 zcmeHOPiz!b7=KHt6e+YClmbd8Sd(I8*luZeD=DlZFp^dU+GwI=JMGSPCvJC}-Kn;C zumn92(xfM1yl6~FkQ0d)6A#d!#DfR*B=OQ1h?w}N9yEB6@%v`J-!cp((Th>@zGUb3 zzCXYB-u(8>Zg%I*8~XKo>}6ZSNLCV^UD6=Ps*GAq#|`Sipmyc0)E%uC zB?(m0FOSj4)#Ar-txO4sJcolW4JMNr!Lg2SiwlhM?xEa>85WG}z8x>hc%KP^w}Q%; zHz~YH;nh*k3Sx+QAb5v}$MgKF2H6kG zcz4s~JvlERsaC1g>SyQGWjXbh4VZwuID!R z)C`Q}3D!Z(=Q{AHnMKWok*j}5>9Vk&qQ)|r$L|tn9hR%-@t2DaQ~Z8)uTu9>gN*9} z%jL!=D&<_wv#VY%r*h8>4d(Jr)fsndo>Ltf+*_)YogsU)lW*5N#4k!tV_htOS~-`P7iVTi+jR2Yg|7EYG04UW$6Zm zOOZIgkFXn&IMyO^8npsi0j+>mKr5gX&lm3&NY6;(09XofVw-)ZR&2dzu3|~ z%e9vTss4kYzUO_0Z8xoxOV+|qd#r^U4OZf^_2o@(J#{cB9W?oig_icGZ}DgQT}r8` z9mCd%{w>_JPG0kxtyBF6$+>>i_xxAeZmL!?tQ}OJTiP_pE2N;r>3_VeP+t+GE&J@GTD{N7%x?wSKXRh zDI1yYLT^uRdZ&}l3y+B0D#+SH#t;f~R`6_0zQ;cU-V=4h>^%(2SEgj4q7 z^89U|*A1@?Syp#E7r_6cL=Ec}v8~kLwF*AgGm!VUvw??o2Y(CYextPpKGr`Fald|V$uYzW~w^8YyCW1S}{#%mmWTyMZ4<)RkKV7uJ`9ptYNTpzhxPUnS6-uyv;CC8fC2%ry>qne70#nrB z?+$!U;`;#4t;Fl$1CJB8CBnz|MNyvXK^>I@1|K*_QC>S3AD^4`=Ysg;$nbpv9^Qum z%5e$!c>ZFMb}6wL!SU7seBfzHMfoZ#waE~%&LvvE{=k2i5>Y-r-`j+bx;P*H8ESA1 s=5J)fjByt}j}^6ZnZU0xtgefA4QBEt(%e#Ka2*c4IaXO0*wDn-~a#s literal 0 HcmV?d00001 diff --git a/test/files/x.typelib b/test/files/x.typelib new file mode 100644 index 000000000..e69de29bb diff --git a/test/mockdata/mock_files.py b/test/mockdata/mock_files.py new file mode 100644 index 000000000..de63f29b3 --- /dev/null +++ b/test/mockdata/mock_files.py @@ -0,0 +1,536 @@ +import stat + +import rpm + +from Testing import get_tested_mock_package + +FILES = get_tested_mock_package( + files={ + '/%{unexpanded}/test': {}, + '/usr/bin/unexpanded-macro-files': {'is_dir': True}, + '/usr/share/licenses/unexpanded-macro-files': {'is_dir': True}, + '/usr/share/licenses/unexpanded-macro-files/LICENSE': {} + }, + header={ + 'requires': [""" + /bin/bash + bash + rpmlib(CompressedFileNames) <= 3.0.4-1 + rpmlib(FileDigests) <= 4.6.0-1 + rpmlib(PayloadFilesHavePrefix) <= 4.0-1 + rpmlib(PayloadIsZstd) <= 5.4.18-1 + """]} +) + +FILES2 = get_tested_mock_package( + name='python3-power', + files={ + '/usr/lib/python3.3/site-packages/power/__init__.py': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/darwin.cpython-33.pyc': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/darwin.cpython-33.pyo': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/common.py': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/darwin.py': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/linux.py': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/tests.py': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/win32.py': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/darwin/IOPSKeys_h/index.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/darwin/IOPSKeys_h/toc.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/darwin/IOPowerSources_h/index.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/darwin/IOPowerSources_h/toc.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/linux/power_supply.h': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/linux/power_supply_class.txt': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/CallNtPowerInformation.htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/GetSystemPowerStatus .htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/Power Setting GUIDs.htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/PowerSettingRegisterNotification.htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/PowerSettingUnregisterNotification.htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/SYSTEM_BATTERY_STATE.htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/python3-power-1.1/win32/SYSTEM_POWER_STATUS.htm': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/__init__.cpython-33.pyc': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/__init__.cpython-33.pyo': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/common.cpython-33.pyc': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/common.cpython-33.pyo': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/linux.cpython-33.pyc': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/linux.cpython-33.pyo': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/tests.cpython-33.pyc': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/tests.cpython-33.pyo': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/win32.cpython-33.pyc': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/lib/python3.3/site-packages/power/__pycache__/win32.cpython-33.pyo': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}} + }, + header={ + 'requires': [ + 'python(abi) = 3.3', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PartialHardlinkSets) <= 4.0.4-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1' + ] + } +) + +FILES3 = get_tested_mock_package( + name='testdocumentation', + files={ + 'usr/share/doc/packages/testdocumentation': {'is_dir': True, 'metadata': {'mode': 0o755 | stat.S_IFDIR, 'user': 'root', 'group': 'root', 'flags': 0}}, + '/usr/share/doc/packages/testdocumentation/README1.gz': {'content-path': 'files/README1.gz', 'create_dirs': True, 'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 2 | rpm.RPMFILE_DOC}}, + '/usr/share/doc/packages/testdocumentation/README2.bz2': {'content-path': 'files/README2.bz2', 'create_dirs': True, 'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 2 | rpm.RPMFILE_DOC}}, + '/usr/share/doc/packages/testdocumentation/README3.xz': {'content-path': 'files/README3.xz', 'create_dirs': True, 'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 2 | rpm.RPMFILE_DOC}}, + }, + header={ + 'requires': { + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1' + } + } +) + +FILES4 = get_tested_mock_package( + name='netmask-debugsource', + files={ + '/usr/src/debug/netmask-2.4.3-5.fc27.x86_64/errors.c': {'content-path': 'files/netmask/errors.c', 'metadata': {'mode': 0o644 | stat.S_IFREG}}, + '/usr/src/debug/netmask-2.4.3-5.fc27.x86_64/errors.h': {'content-path': 'files/netmask/errors.h', 'metadata': {'mode': 0o644 | stat.S_IFREG}}, + '/usr/src/debug/netmask-2.4.3-5.fc27.x86_64/main.c': {'content-path': 'files/netmask/main.c', 'metadata': {'mode': 0o644 | stat.S_IFREG}}, + '/usr/src/debug/netmask-2.4.3-5.fc27.x86_64/netmask.c': {'content-path': 'files/netmask/netmask.c', 'metadata': {'mode': 0o644 | stat.S_IFREG}}, + '/usr/src/debug/netmask-2.4.3-5.fc27.x86_64/netmask.h': {'content-path': 'files/netmask/netmask.h', 'metadata': {'mode': 0o644 | stat.S_IFREG}}, + }, + header={ + 'version': '2.4.3', + 'release': '5.fc27', + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1', + ] + } +) + +FILES5 = get_tested_mock_package( + files={ + '/usr/share/CMakeLists.txt': {}, + '/usr/share/Makefile.am': {'metadata': {'flags': rpm.RPMFILE_DOC}}, + '/usr/share/Makefile.in': {}, + '/usr/share/selinux': {'is_dir': True}, + '/usr/share/selinux/Makefile': {}, + '/usr/src/foo': {'is_dir': True}, + '/usr/src/foo/Makefile': {} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsZstd) <= 5.4.18-1' + ] + } +) + +FILES6 = get_tested_mock_package( + files={ + '/usr/lib64/python3.7/site-packages/greenlet-0.4.15-py3.7.egg-info': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 0 | stat.S_IFREG}}, + '/usr/lib64/python3.7/site-packages/greenlet.cpython-37m-x86_64-linux-gnu.so': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o755, 'flags': 0 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/AUTHORS': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/NEWS': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/README.rst': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_sources/greenlet.txt': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_sources/index.txt': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/basic.css': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/classic.css': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/default.css': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/doctools.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/documentation_options.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/file.png': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/jquery-3.2.1.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/jquery.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/language_data.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/minus.png': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/plus.png': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/pygments.css': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/searchtools.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/sidebar.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/underscore-1.3.1.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/_static/underscore.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/genindex.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/greenlet.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/index.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/objects.inv': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/search.html': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/doc/packages/python3-greenlet/html/searchindex.js': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 2 | stat.S_IFREG}}, + '/usr/share/licenses/python3-greenlet/LICENSE': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 128 | stat.S_IFREG}}, + '/usr/share/licenses/python3-greenlet/LICENSE.PSF': {'metadata': {'user': 'root', 'group': 'root', 'mode': 0o644, 'flags': 128 | stat.S_IFREG}}, + }, + header={ + 'requires': [ + 'libc.so.6()(64bit)', + 'libc.so.6(GLIBC_2.14)(64bit)', + 'libc.so.6(GLIBC_2.2.5)(64bit)', + 'libc.so.6(GLIBC_2.4)(64bit)', + 'libpython3.7m.so.1.0()(64bit)', + 'python(abi) = 3.7', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1', + ] + } +) + +FILES7 = get_tested_mock_package( + files={ + '/.gitignore': {}, + '/.htaccess': {}, + '/bin/foo/bar': {}, + '/etc/systemd/system/foo': {}, + '/etc/tmpfiles.d/foo': {}, + '/etc/udev/rules.d/foo': {}, + '/run/foo': {}, + '/site_perl/foo': {}, + '/usr/info/dir': {}, + '/usr/share/doc/perl-foo/MANIFEST': {}, + '/~backup.rej': {} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1', + ] + } +) + +FILES8 = get_tested_mock_package( + files={ + '/usr/lib64/tcl/pkgIndex.tcl': {} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1', + ] + } +) + +FILES9 = get_tested_mock_package( + files={ + '/etc/bar.rs': {'content': '#![allow(box_pointers)]', 'metadata': {'mode': 0o755}}, + '/etc/foo.rs': { + 'content': '#![allow(box_pointers)]', + 'metadata': {'mode': 0o755 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': rpm.RPMFILE_DOC} + }, + }, + header={ + 'requires': [ + 'insserv', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1', + 'xinetd', + ] + } +) + +FILES10 = get_tested_mock_package( + files={ + '/etc/ngircd.conf': {}, + '/etc/pam.d/ngircd': {}, + '/usr/lib/systemd/system/ngircd.service': {}, + '/usr/sbin/ngircd': {}, + '/usr/share/doc/ngircd': {'is_dir': True}, + '/usr/share/doc/ngircd/AUTHORS': {}, + '/usr/share/doc/ngircd/Bopm.txt': {}, + '/usr/share/doc/ngircd/COPYING': {}, + '/usr/share/doc/ngircd/Capabilities.txt': {}, + '/usr/share/doc/ngircd/ChangeLog': {}, + '/usr/share/doc/ngircd/Commands.txt': {}, + '/usr/share/doc/ngircd/Contributing.txt': {}, + '/usr/share/doc/ngircd/FAQ.txt': {}, + '/usr/share/doc/ngircd/GIT.txt': {}, + '/usr/share/doc/ngircd/HowToRelease.txt': {}, + '/usr/share/doc/ngircd/Modes.txt': {}, + '/usr/share/doc/ngircd/NEWS': {}, + '/usr/share/doc/ngircd/PAM.txt': {}, + '/usr/share/doc/ngircd/Platforms.txt': {}, + '/usr/share/doc/ngircd/Protocol.txt': {}, + '/usr/share/doc/ngircd/README': {}, + '/usr/share/doc/ngircd/README-AUX.txt': {}, + '/usr/share/doc/ngircd/README-BeOS.txt': {}, + '/usr/share/doc/ngircd/README-Interix.txt': {}, + '/usr/share/doc/ngircd/RFC.txt': {}, + '/usr/share/doc/ngircd/SSL.txt': {}, + '/usr/share/doc/ngircd/Services.txt': {}, + '/usr/share/doc/ngircd/sample-ngircd.conf': {}, + '/usr/share/doc/ngircd/sample-ngircd.conf.tmpl': {}, + '/usr/share/man/man5/ngircd.conf.5.gz': {}, + '/usr/share/man/man8/ngircd.8.gz': {}, + '/var/run/ngircd': {} + }, + header={ + 'requires': [""" + /bin/sh + /bin/sh + /bin/sh + /bin/sh + config(ngircd) = 22-2.fc22 + libc.so.6()(64bit) + libc.so.6(GLIBC_2.14)(64bit) + libc.so.6(GLIBC_2.15)(64bit) + libc.so.6(GLIBC_2.2.5)(64bit) + libc.so.6(GLIBC_2.3)(64bit) + libc.so.6(GLIBC_2.3.2)(64bit) + libc.so.6(GLIBC_2.3.4)(64bit) + libc.so.6(GLIBC_2.4)(64bit) + libgnutls.so.28()(64bit) + libgnutls.so.28(GNUTLS_1_4)(64bit) + libident.so.0()(64bit) + libpam.so.0()(64bit) + libpam.so.0(LIBPAM_1.0)(64bit) + libwrap.so.0()(64bit) + libz.so.1()(64bit) + rpmlib(CompressedFileNames) <= 3.0.4-1 + rpmlib(FileDigests) <= 4.6.0-1 + rpmlib(PayloadFilesHavePrefix) <= 4.0-1 + rpmlib(PayloadIsXz) <= 5.2-1 + rtld(GNU_HASH) + shadow-utils + systemd + systemd + systemd"""] + } +) + +FILES11 = get_tested_mock_package( + name='my-package-devel', + files={ + '/usr/x.typelib': {'content-path': 'files/x.typelib', 'metadata': {'mode': 0o644 | stat.S_IFREG, 'size': 100, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1' + ] + } +) + +FILES12 = get_tested_mock_package( + name='shlib1', + files={ + '/usr/lib/libfoo-2.so': {'content-path': 'files/shlib2/libfoo-2.so', 'metadata': {'mode': 0o755 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}}, + '/usr/lib/libfoo-2.so.foo': {'content-path': 'files/shlib2/libfoo-2.so.foo', 'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}}, + '/usr/lib/libfoo.so': {'content-path': 'files/shlib2/libfoo.so', 'metadata': {'mode': 0o777 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}, 'linkto': 'libfoo.so.1'}, + '/usr/lib/libfoo.so.1': {'content-path': 'files/shlib2/libfoo.so.1', 'metadata': {'mode': 0o755 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1' + ] + } +) + +FILES13 = get_tested_mock_package( + name='shlib2-devel', + files={ + '/usr/lib/libfoo-2.so': {'content-path': 'files/shlib2/libfoo-2.so', 'metadata': {'mode': 0o755 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}}, + '/usr/lib/libfoo-2.so.foo': {'content-path': 'files/shlib2/libfoo-2.so.foo', 'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}}, + '/usr/lib/libfoo.so': {'content-path': 'files/shlib2/libfoo.so', 'metadata': {'mode': 0o777 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}, 'linkto': 'libfoo.so.1'}, + '/usr/lib/libfoo.so.1': {'content-path': 'files/shlib2/libfoo.so.1', 'metadata': {'mode': 0o755 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0 | rpm.RPMFILE_DOC}} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsXz) <= 5.2-1' + ]} +) + +FILES14 = get_tested_mock_package( + files={ + '/etc/security/console.apps': {'is_dir': True, 'metadata': {'mode': 0o755, 'flags': 0 | rpm.RPMFILE_GHOST | stat.S_IFDIR, 'user': 'root', 'group': 'root', 'size': 4096}}, + '/etc/security/console.apps/myapp': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 100, 'flags': 1}}, + '/usr/lib/.nosearch': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'flags': 0}}, + '/usr/lib/emptyfile': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 0, 'flags': 0}}, # Tamaño 0 para activar la verificación + '/usr/lib/nonemptyfile': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 100, 'flags': 0}}, # Tamaño no 0 + '/usr/lib/python': {'is_dir': True, 'metadata': {'flags': rpm.RPMFILE_GHOST | stat.S_IFDIR | 0, 'size': 4096, 'mode': 0o755 | stat.S_IFDIR, 'user': 'root', 'group': 'root'}}, + '/usr/lib/python/__init__.py': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 0, 'flags': 0}}, # Tamaño 0 pero será ignorado por normal_zero_length_regex + '/usr/lib/python/py.typed': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 0, 'flags': 0}}, # Tamaño 0 pero será ignorado por normal_zero_length_regex + '/usr/lib/python/pypackagefromwheel-0.0.0.dist-info/REQUESTED': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 0, 'flags': 0}}, # Tamaño 0 pero será ignorado + '/usr/lib/ruby/gem.build_complete': {'metadata': {'mode': 0o644 | stat.S_IFREG, 'user': 'root', 'group': 'root', 'size': 0, 'flags': 0}}, # Tamaño 0 pero será ignorado + }, + header={ + 'requires': [ + 'config(file-zero-length) = 1.1-0', + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsZstd) <= 5.4.18-1' + ] + } +) + +FILES15 = get_tested_mock_package( + files={ + '/usr/share/man/man0p': {'is_dir': True}, + '/usr/share/man/man0p/foo.3.gz': {}, + '/usr/share/man/man1': {'is_dir': True}, + '/usr/share/man/man1/test.1.zst': {}, + '/usr/share/man/man3': {'is_dir': True}, + '/usr/share/man/man3/foo': {'is_dir': True}, + '/usr/share/man/man3/foo/bar': {'is_dir': True}, + '/usr/share/man/man3/foo/bar/baz.3.gz': {}, + '/usr/share/man/man3/some.3pm.gz': {} + }, + header={ + 'requires': [ + 'rpmlib(CompressedFileNames) <= 3.0.4-1', + 'rpmlib(FileDigests) <= 4.6.0-1', + 'rpmlib(PayloadFilesHavePrefix) <= 4.0-1', + 'rpmlib(PayloadIsZstd) <= 5.4.18-1' + ] + } +) + +FILES16 = get_tested_mock_package( + files={ + '/usr/share/package/bin.py': { + 'content': '#!/usr/bin/python3\nprint("python required")', + 'metadata': {'mode': 0o755 | stat.S_IFREG}, + }, + '/usr/bin/testlink': { + 'linkto': '../share/package/bin.py', + }, + }, + header={}, +) + +FILES17 = get_tested_mock_package( + files={ + '/usr/share/package/bin.py': { + 'content': '#!/usr/bin/python3\nprint("python required")', + 'metadata': {'mode': 0o755 | stat.S_IFREG}, + }, + '/usr/bin/testlink': { + 'linkto': '../share/package/bin.py', + }, + }, + header={ + 'requires': ['/usr/bin/python3'], + }, +) + +FILES18 = get_tested_mock_package( + header={'requires': []}, + files={ + '/etc/raddb/mods-config/sql/moonshot-targeted-ids/mysql': { + 'is_dir': True, + 'metadata': {'mode': 0o640 | stat.S_IFDIR}, + }, + '/etc/raddb/mods-config/sql/moonshot-targeted-ids/postgresql': { + 'is_dir': True, + 'metadata': {'mode': 0o640 | stat.S_IFDIR}, + }, + '/etc/raddb/mods-config/sql/moonshot-targeted-ids/sqlite': { + 'is_dir': True, + 'metadata': {'mode': 0o640 | stat.S_IFDIR}, + }, + }, +) + +FILES19 = get_tested_mock_package( + header={'requires': []}, + files={ + '/etc/raddb': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/etc/raddb/certs': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/etc/raddb/mods-available': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/etc/raddb/mods-config': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/etc/raddb/policy.d': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/etc/raddb/sites-available': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/etc/raddb/sites-enabled': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/usr/lib64/freeradius': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + '/usr/share/freeradius': { + 'is_dir': True, + 'metadata': { + 'mode': 0o640 | stat.S_IFDIR + }, + }, + } +) + +FILES20 = get_tested_mock_package( + header={'requires': []}, + files={ + '/var/lib/pipewire': {'is_dir': True, 'metadata': {'mode': 0o000 | stat.S_IFDIR}}, + '/var/lib/dir_read': {'is_dir': True, 'metadata': {'mode': 0o755 | stat.S_IFDIR}}, + '/var/lib/pipewire/ghost_file': {'metadata': {'mode': 0o000, 'flags': rpm.RPMFILE_GHOST}}, + '/var/lib/pipewire/ghost_file_read': {'metadata': {'mode': 0o644, 'flags': rpm.RPMFILE_GHOST}}, + '/var/lib/pipewire/normal_file': {'metadata': {'mode': 0o000}}, + '/var/lib/pipewire/normal_file_read': {'metadata': {'mode': 0o644}}, + }, +) + +FILES21 = get_tested_mock_package( + header={'requires': []}, + files={ + '/run/netconfig/resolv.conf': {'metadata': {'mode': 0o000, 'flags': rpm.RPMFILE_GHOST}}, + '/run/netconfig/yp.conf': {'metadata': {'mode': 0o644, 'flags': rpm.RPMFILE_GHOST}}, + '/run/netconfig': {'is_dir': True, 'metadata': {'mode': 0o000, 'flags': rpm.RPMFILE_GHOST | stat.S_IFDIR}}, + '/usr/lib/tmpfiles.d/netconfig.conf': { + 'content': """ +d /run/netconfig 0755 root group - +f /run/netconfig/resolv.conf 0644 root root - +f /run/netconfig/yp.conf 0644 root root - +""" + }, + }, +) diff --git a/test/test_files.py b/test/test_files.py index 65a7705b0..28513b887 100644 --- a/test/test_files.py +++ b/test/test_files.py @@ -1,15 +1,36 @@ import re -import stat +from mockdata.mock_files import ( + FILES, + FILES10, + FILES11, + FILES12, + FILES13, + FILES14, + FILES15, + FILES16, + FILES17, + FILES18, + FILES19, + FILES2, + FILES20, + FILES21, + FILES3, + FILES4, + FILES5, + FILES6, + FILES7, + FILES8, + FILES9 +) import pytest -import rpm from rpmlint.checks.FilesCheck import FilesCheck from rpmlint.checks.FilesCheck import pyc_magic_from_chunk, pyc_mtime_from_chunk from rpmlint.checks.FilesCheck import python_bytecode_to_script as pbts from rpmlint.checks.FilesCheck import script_interpreter as se from rpmlint.filter import Filter -from Testing import CONFIG, get_tested_mock_package, get_tested_package, get_tested_path +from Testing import CONFIG, get_tested_path @pytest.fixture(scope='function', autouse=True) @@ -55,27 +76,27 @@ def chunk_from_pyc(version, size=16): return f.read(size) -@pytest.mark.parametrize('package', ['binary/unexpanded-macro-files']) -def test_unexpanded_macros(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES]) +def test_unexpanded_macros(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'unexpanded-macro' in out -@pytest.mark.parametrize('package', ['binary/python3-power']) -def test_python_bytecode_magic(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES2]) +def test_python_bytecode_magic(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) assert not output.results out = output.print_results(output.results) assert 'python-bytecode-wrong-magic-value' not in out -@pytest.mark.parametrize('package', ['binary/testdocumentation']) -def test_file_not_utf8_for_compression_algorithms(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES3]) +def test_file_not_utf8_for_compression_algorithms(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'file-not-utf8 /usr/share/doc/packages/testdocumentation/README1.gz' in out assert 'file-not-utf8 /usr/share/doc/packages/testdocumentation/README2.bz2' in out @@ -94,10 +115,10 @@ def test_pyc_mtime_from_chunk(version, mtime): assert pyc_mtime_from_chunk(chunk) == mtime -@pytest.mark.parametrize('package', ['binary/netmask-debugsource']) -def test_devel_files(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES4]) +def test_devel_files(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) assert len(output.results) == 5 out = output.print_results(output.results) assert 'devel-file-in-non-devel-package' not in out @@ -105,26 +126,26 @@ def test_devel_files(tmp_path, package, filescheck): assert 'no-documentation' in out -@pytest.mark.parametrize('package', ['binary/makefile-junk']) -def test_makefile_junk(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES5]) +def test_makefile_junk(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'W: makefile-junk /usr/share/Makefile.am' in out assert out.count('W: makefile-junk') == 1 -@pytest.mark.parametrize('package', ['binary/python3-greenlet']) -def test_sphinx_inv_files(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES6]) +def test_sphinx_inv_files(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) assert not len(output.results) -@pytest.mark.parametrize('package', ['binary/filechecks']) -def test_invalid_package(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES7]) +def test_invalid_package(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'W: non-ghost-in-run /run/foo' in out assert 'W: systemd-unit-in-etc /etc/systemd/system/foo' in out @@ -139,10 +160,10 @@ def test_invalid_package(tmp_path, package, filescheck): assert 'E: info-dir-file /usr/info/dir' in out -@pytest.mark.parametrize('package', ['binary/tclpackage']) -def test_tcl_package(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES8]) +def test_tcl_package(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: tcl-extension-file /usr/lib64/tcl/pkgIndex.tcl' in out @@ -184,54 +205,54 @@ def test_lib_regex(): '/usr/lib64/rsocket/binary',)) -@pytest.mark.parametrize('package', ['binary/rust']) -def test_rust_files(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES9]) +def test_rust_files(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: wrong-script-interpreter /etc/foo.rs' in out assert 'E: wrong-script-interpreter /etc/bar.rs' not in out -@pytest.mark.parametrize('package', ['binary/ngircd']) -def test_distribution_tags(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES10]) +def test_distribution_tags(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'manpage-not-compressed' in out assert 'no-manual-page-for-binary' not in out assert 'This manual page is not compressed with the bz2 compression' in out -@pytest.mark.parametrize('package', ['binary/development']) -def test_provides_devel(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES11]) +def test_provides_devel(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: non-devel-file-in-devel-package /usr/x.typelib' in out -@pytest.mark.parametrize('package', ['binary/shlib1']) -def test_shlib1(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES12]) +def test_shlib1(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'library-without-ldconfig-postin' in out assert 'library-without-ldconfig-postun' in out assert 'devel-file-in-non-devel-package' in out -@pytest.mark.parametrize('package', ['binary/shlib2-devel']) -def test_shlib2_devel(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES13]) +def test_shlib2_devel(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'library-without-ldconfig-postin' in out assert 'library-without-ldconfig-postun' in out assert 'non-devel-file-in-devel-package' in out -@pytest.mark.parametrize('package', ['binary/file-zero-length']) +@pytest.mark.parametrize('package', [FILES14]) @pytest.mark.parametrize( 'filename, show', [('/usr/lib/emptyfile', True), @@ -242,19 +263,19 @@ def test_shlib2_devel(tmp_path, package, filescheck): ('/usr/lib/python/py.typed', False), ('/usr/lib/python/pypackagefromwheel-0.0.0.dist-info/REQUESTED', False), ('/usr/lib/ruby/gem.build_complete', False)]) -def test_zero_length_ignore(tmp_path, package, filescheck, filename, show): +def test_zero_length_ignore(package, filescheck, filename, show): output, test = filescheck - pkg = get_tested_package(package, tmp_path) + pkg = package test.check(pkg) out = output.print_results(output.results) assert filename in pkg.files assert (f'zero-length {filename}' in out) == show -@pytest.mark.parametrize('package', ['binary/manual-pages']) -def test_manual_pages(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES15]) +def test_manual_pages(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: manual-page-in-subfolder /usr/share/man/man3/foo/bar/baz.3.gz' in out assert 'W: manpage-not-compressed bz2 /usr/share/man/man1/test.1.zst' in out @@ -262,94 +283,36 @@ def test_manual_pages(tmp_path, package, filescheck): assert 'bad-manual-page-folder /usr/share/man/man3/some.3pm.gz' not in out -@pytest.mark.parametrize('package', [ - get_tested_mock_package( - files={ - '/usr/share/package/bin.py': { - 'content': '#!/usr/bin/python3\nprint("python required")', - 'metadata': {'mode': 0o755 | stat.S_IFREG}, - }, - '/usr/bin/testlink': { - 'linkto': '../share/package/bin.py', - }, - }, - header={}, - ), -]) +@pytest.mark.parametrize('package', [FILES16]) def test_shebang(package, output, test): test.check(package) out = output.print_results(output.results) assert 'W: symlink-to-binary-with-shebang /usr/bin/testlink' in out -@pytest.mark.parametrize('package', [ - get_tested_mock_package( - files={ - '/usr/share/package/bin.py': { - 'content': '#!/usr/bin/python3\nprint("python required")', - 'metadata': {'mode': 0o755 | stat.S_IFREG}, - }, - '/usr/bin/testlink': { - 'linkto': '../share/package/bin.py', - }, - }, - header={ - 'requires': ['/usr/bin/python3'], - }, - ), -]) +@pytest.mark.parametrize('package', [FILES17]) def test_shebang_ok(package, output, test): test.check(package) out = output.print_results(output.results) assert 'W: symlink-to-binary-with-shebang /usr/bin/testlink' not in out -@pytest.mark.parametrize('package', [ - get_tested_mock_package( - header={'requires': []}, - files={ - '/etc/raddb/mods-config/sql/moonshot-targeted-ids/mysql': { - 'is_dir': True, - 'metadata': {'mode': 0o640 | stat.S_IFDIR}, - }, - '/etc/raddb/mods-config/sql/moonshot-targeted-ids/postgresql': { - 'is_dir': True, - 'metadata': {'mode': 0o640 | stat.S_IFDIR}, - }, - '/etc/raddb/mods-config/sql/moonshot-targeted-ids/sqlite': { - 'is_dir': True, - 'metadata': {'mode': 0o640 | stat.S_IFDIR}, - }, - }, - ), -]) +@pytest.mark.parametrize('package', [FILES18]) def test_directory_without_x_permission(package, output, test): test.check(package) out = output.print_results(output.results) assert 'E: non-standard-dir-perm' in out -@pytest.mark.parametrize('package', ['binary/freeradius-server']) -def test_directory_without_x_permission2(tmp_path, package, filescheck): +@pytest.mark.parametrize('package', [FILES19]) +def test_directory_without_x_permission2(package, filescheck): output, test = filescheck - test.check(get_tested_package(package, tmp_path)) + test.check(package) out = output.print_results(output.results) assert 'E: non-standard-dir-perm' in out -@pytest.mark.parametrize('package', [ - get_tested_mock_package( - header={'requires': []}, - files={ - '/var/lib/pipewire': {'is_dir': True, 'metadata': {'mode': 0o000 | stat.S_IFDIR}}, - '/var/lib/dir_read': {'is_dir': True, 'metadata': {'mode': 0o755 | stat.S_IFDIR}}, - '/var/lib/pipewire/ghost_file': {'metadata': {'mode': 0o000, 'flags': rpm.RPMFILE_GHOST}}, - '/var/lib/pipewire/ghost_file_read': {'metadata': {'mode': 0o644, 'flags': rpm.RPMFILE_GHOST}}, - '/var/lib/pipewire/normal_file': {'metadata': {'mode': 0o000}}, - '/var/lib/pipewire/normal_file_read': {'metadata': {'mode': 0o644}}, - }, - ), -]) +@pytest.mark.parametrize('package', [FILES20]) def test_files_without_perms(package, output, test): test.check(package) out = output.print_results(output.results) @@ -361,23 +324,7 @@ def test_files_without_perms(package, output, test): assert not re.findall('W: zero-perms-ghost .*ghost_file_read', out) -@pytest.mark.parametrize('package', [ - get_tested_mock_package( - header={'requires': []}, - files={ - '/run/netconfig/resolv.conf': {'metadata': {'mode': 0o000, 'flags': rpm.RPMFILE_GHOST}}, - '/run/netconfig/yp.conf': {'metadata': {'mode': 0o644, 'flags': rpm.RPMFILE_GHOST}}, - '/run/netconfig': {'is_dir': True, 'metadata': {'mode': 0o000, 'flags': rpm.RPMFILE_GHOST | stat.S_IFDIR}}, - '/usr/lib/tmpfiles.d/netconfig.conf': { - 'content': """ -d /run/netconfig 0755 root group - -f /run/netconfig/resolv.conf 0644 root root - -f /run/netconfig/yp.conf 0644 root root - -""" - }, - }, - ), -]) +@pytest.mark.parametrize('package', [FILES21]) def test_files_without_perms_tmpfiles(package, output, test): test.check(package) out = output.print_results(output.results) From ee4287596d1fd7e31e58897e88d14e236981eae9 Mon Sep 17 00:00:00 2001 From: Daniel Garcia Moreno Date: Wed, 21 Aug 2024 10:41:59 +0200 Subject: [PATCH 5/5] Test: Add missing test file for test_files.py --- test/files/README3.xz | Bin 0 -> 80 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/files/README3.xz diff --git a/test/files/README3.xz b/test/files/README3.xz new file mode 100644 index 0000000000000000000000000000000000000000..8154cdd300a8791bf1d9b8d0e66bdea601c843c8 GIT binary patch literal 80 zcmexsUKJ6=z`*kC+7>q^21Q0O1_p)_{ill`Fo-h<$1>FKuMuCDuI% kU#uAzz9q>_+9DC;z`&?4At3rqQGVO!T1KEg2A0Su0C2t=2mk;8 literal 0 HcmV?d00001