From 8eb68d6a19292f62fe11392791545b1da463af54 Mon Sep 17 00:00:00 2001 From: "Daniel W. Anner" Date: Tue, 1 Aug 2023 11:46:04 -0400 Subject: [PATCH] Adding module file name checks as well (#1519) --- tests/definitions_test.py | 6 ++++-- tests/device_types.py | 8 +++++++- tests/generate-slug-list.py | 22 ++++++++++++++-------- tests/known-modules.pickle | Bin 0 -> 19519 bytes tests/test_configuration.py | 1 + 5 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 tests/known-modules.pickle diff --git a/tests/definitions_test.py b/tests/definitions_test.py index dce19f84a..ab5f61fab 100644 --- a/tests/definitions_test.py +++ b/tests/definitions_test.py @@ -1,4 +1,4 @@ -from test_configuration import COMPONENT_TYPES, IMAGE_FILETYPES, SCHEMAS, KNOWN_SLUGS, ROOT_DIR, USE_LOCAL_KNOWN_SLUGS, NETBOX_DT_LIBRARY_URL +from test_configuration import COMPONENT_TYPES, IMAGE_FILETYPES, SCHEMAS, KNOWN_SLUGS, ROOT_DIR, USE_LOCAL_KNOWN_SLUGS, NETBOX_DT_LIBRARY_URL, KNOWN_MODULES import pickle_operations from yaml_loader import DecimalSafeLoader from device_types import DeviceType, ModuleType, verify_filename, validate_components @@ -110,10 +110,12 @@ image_files = _get_image_files() if USE_LOCAL_KNOWN_SLUGS: KNOWN_SLUGS = pickle_operations.read_pickle_data(f'{ROOT_DIR}/tests/known-slugs.pickle') + KNOWN_MODULES = pickle_operations.read_pickle_data(f'{ROOT_DIR}/tests/known-modules.pickle') else: temp_dir = tempfile.TemporaryDirectory() repo = Repo.clone_from(url=NETBOX_DT_LIBRARY_URL, to_path=temp_dir.name) KNOWN_SLUGS = pickle_operations.read_pickle_data(f'{temp_dir.name}/tests/known-slugs.pickle') + KNOWN_MODULES = pickle_operations.read_pickle_data(f'{temp_dir.name}/tests/known-modules.pickle') @pytest.mark.parametrize(('file_path', 'schema'), definition_files) def test_definitions(file_path, schema): @@ -159,7 +161,7 @@ def test_definitions(file_path, schema): assert this_device.verify_slug(KNOWN_SLUGS), pytest.fail(this_device.failureMessage, False) # Verify the filename is valid. Must either be the model or part_number. - assert verify_filename(this_device), pytest.fail(this_device.failureMessage, False) + assert verify_filename(this_device, (KNOWN_MODULES if not this_device.isDevice else None)), pytest.fail(this_device.failureMessage, False) # Check for duplicate components within the definition assert validate_components(COMPONENT_TYPES, this_device), pytest.fail(this_device.failureMessage, False) diff --git a/tests/device_types.py b/tests/device_types.py index 7b58cd0e7..8b6b9321f 100644 --- a/tests/device_types.py +++ b/tests/device_types.py @@ -151,7 +151,7 @@ class ModuleType: slugified = slugified[:-1] return slugified -def verify_filename(device: (DeviceType or ModuleType)): +def verify_filename(device: (DeviceType or ModuleType), KNOWN_MODULES: (set or None)): head, tail = os.path.split(device.get_filepath()) filename = tail.rsplit(".", 1)[0].casefold() @@ -159,6 +159,12 @@ def verify_filename(device: (DeviceType or ModuleType)): device.failureMessage = f'{device.file_path} file name is invalid. Must be either the model "{device._slug_model}" or part_number "{device.part_number} / {device._slug_part_number}"' return False + if not device.isDevice: + matches = [file_name for file_name, file_path in KNOWN_MODULES if file_name.casefold() == filename.casefold()] + if len(matches) > 1: + device.failureMessage = f'{device.file_path} appears to be duplicated. Found {len(matches)} matches: {", ".join(matches)}' + return False + return True def validate_components(component_types, device_or_module): diff --git a/tests/generate-slug-list.py b/tests/generate-slug-list.py index 7cf3f1d0e..cb901c559 100644 --- a/tests/generate-slug-list.py +++ b/tests/generate-slug-list.py @@ -6,18 +6,18 @@ import decimal from yaml_loader import DecimalSafeLoader from jsonschema import Draft4Validator, RefResolver from jsonschema.exceptions import ValidationError -from test_configuration import SCHEMAS, KNOWN_SLUGS, ROOT_DIR +from test_configuration import SCHEMAS, KNOWN_SLUGS, ROOT_DIR, KNOWN_MODULES from urllib.request import urlopen import pickle_operations -def _get_device_type_files(): +def _get_type_files(device_or_module): """ Return a list of all definition files within the specified path. """ file_list = [] for path, schema in SCHEMAS: - if path == 'device-types': + if path == f'{device_or_module}-types': # Initialize the schema with open(f"{ROOT_DIR}/schema/{schema}") as schema_file: schema = json.loads(schema_file.read(), @@ -75,8 +75,8 @@ def load_file(file_path, schema): return (True, definition) -def _generate_known_slugs(): - all_files = _get_device_type_files() +def _generate_knowns(device_or_module): + all_files = _get_type_files(device_or_module) for file_path, schema in all_files: definition_status, definition = load_file(file_path, schema) @@ -84,7 +84,13 @@ def _generate_known_slugs(): print(definition) exit(1) - KNOWN_SLUGS.add((definition.get('slug'), file_path)) + if device_or_module == 'device': + KNOWN_SLUGS.add((definition.get('slug'), file_path)) + else: + KNOWN_MODULES.add((os.path.splitext(os.path.basename(file_path))[0], os.path.dirname(file_path))) -_generate_known_slugs() -pickle_operations.write_pickle_data(KNOWN_SLUGS, f'{ROOT_DIR}/tests/known-slugs.pickle') \ No newline at end of file +_generate_knowns('device') +pickle_operations.write_pickle_data(KNOWN_SLUGS, f'{ROOT_DIR}/tests/known-slugs.pickle') + +_generate_knowns('module') +pickle_operations.write_pickle_data(KNOWN_MODULES, f'{ROOT_DIR}/tests/known-modules.pickle') \ No newline at end of file diff --git a/tests/known-modules.pickle b/tests/known-modules.pickle new file mode 100644 index 0000000000000000000000000000000000000000..4fad73ab6d295e7e08b093f840608e9360d88aff GIT binary patch literal 19519 zcma)EO>-Mba`i!!NCM!8MskeT;RyNWORf70K;zhKph1uT)MSHXYicms$9)XaDDn|3Uuee}4YkkK@V67j|D* z#&95_ApH5`)#vqxZx0Lc^yinw*MGnGwpxB!JpTM|{2}nBqH9@(7{%A3Z;eG@o&Egr zQdvJ;e_GCI_2FO=_Gjj~>08w`gZa~XCD+8`u4#y?zPGVvw0c@R(3*d0xADZ=(L^}! z1|pche_Y-VRv(wE#m^uAqC9%={poS>dGThtc=}`g_~|SC>m%QG+lH7rSTlE<=Q#k7dT4*!Zq|?av>l%HR8o z2l+`yUgU`=ng~DgVR-hXTGO_Jce=aAD+!NX)(E_?bLU<4$Nq2C;|u4j58swg^iD70 zHY_pYEqxk{haw#N=67d2jLpc$Baf922qN0(xfk|2W)DVF{^*51{q@wtQQd}9F$hN^ zYcgD+g8WB&Z{kIHV*dbPa2nxzBybG)Ey;3Vrd z+m8nmOPD^ks$F_EFbo53SvB-@APwF0dmZ@27#{2LHqK1fag4jZ#&m<&A@_h$+*l6- zdqHH`@S?i+Zv_+K8K&iXzHv6Fp2c|a_hpI#h2ObaziUPz#f+Ic!8X@yA{0#P&KuUm z!Y?Y6nOY>#{2B|IlP3Net%%OR|1><{P9|Gr|{w1@ZUfeA1Bk;6Jg&M zrb%!Z;@ef6&+)K0J&R6n%%R3f2;8JNCZMGNtwww}e^|fq9-br~ANh+F(Am{ajr1T&oKZRB`Sc#=wy`uEU7zNcO3o z`px_0e*$%7DrkmcJR86*T`?T9R(uxuvq|+yzs=;6TE24`)8V=ZOeARL+m0kio|`g( zX;AX?#*fYfAtm6{@O;Ws%$BDY(+~;TAkQ|hZ}gCQO3$Cfj%x^$aw)w6%OzwEae(@& zZPOgm@MR(vW+1T1uS!Juzc21Ty$RRLmCR}f(b;#`9L}sAko+iiI))fpl1*6Oci|7u zFV0QZ;Cw)Zk#k!MBaJlM*{0d4`o5Cw8iUXiW(>Ozc^5^<6Z%Itp@0>c^E>bdt}FU3 zr5hEx3aYYCaPFSbE_I0B==+iA+8tLo{pyC^9vDOfYX=hl50+F}IMXWr*EFrr}0 zCgFvSGgp@bf6uI-x_eHs|Dx;;KHj&-b&n`{AtFY@xytDR@1ai@S>CPVpk+3qfv8uL z#pC?bQcRG8C}ZepUyjy2x5GthzNT$E+!`6{CimCl1m1vdIK+s^KMQWTjg79Wx3P4z zUXl-kJ8_P%Vmv9uxo{_(1Hy|DQYTWa6Z08Eg|EJ)_07te5TDeX;K9H&CaBwHfEASy zMSrf=59^PAQVub+cuHiyLhne3k`Z!0}apC1=?QEv2Fp{ z+snB_03JRhdKc}0p)atK(&H}3XeVhO6p(cbBICvmWW0%lihL27mgsBh))dihQAaX< zh^hlrGod3q*Hr9_yjTNd+36xRcJ-&5XCSi!W}xP@A_X-QrtN%p^rg(HeY%1>)bXc-q!bWi z8phdne2r&-VhI^CWtZvy1m+6lQF=ZH}ar@X6dTb;)O& zIYY1w&_KpUt&+kti`iwT@f0UQXOo~#02HlPW}i=IH!?-5N!9D$dK7}cs@xXTmUx#g zNoSRyvqNq@h==}fGygn5kg13kt-t)fPURXZ0NmKr@Q4$MQBar@#Zi0I75N-gUH3J~ z&Qi;i>|5tViqf`m>?NfwbD>_ZXLBy}Y&biEGNi^}szj)S5qVwr1E0-W^uc;*!!V`TY#1b6YZ&AUsc-I54|DaG&MJHT{>3GT zlj`+ZX8=__Nhf+CkN74ekH~W7^*QJHMc?jFn`WzpaYlyAxTBo=8O`MC5a6-GjR4jP;@r2?fHGP1Bqd~ z;q%CFEtiXo*5%^Quh6U);`+jAS06Q8tQKfZ$+9Lm?+bG>3p-=KA58*mxJ|5n7GB?- zR}UtQw8M-C%s$tju@VBBeo}$@jsXt9SpV=2r%p%i@ybWhR&z+9X7_5Oy%Wp03E4%t z?b{BkwjRL8pmm|LW4BQgZ@(t-7GFU0pZ|jVq6sI(nu!Dp!# zF{jW>q&v%rES-9n2wrAZL9@omKcj84kbIiCt!Zif_E54;V3f(5En{ma7WHiHj7EV@TzD`J$kRr#9OiD7tbk zPhVP7bfn^5*S35y;FnR;M)qtvmg7S6*GO-tuJQS^IA1@B=#TjqOiZkJj(aMba-P7P zfgvU#oV7}gl&)N29`MmbGvK=u+u6IWY$`G7TE45&Q0SIA!qp7om_&roN5ig)kNK3z z%MI*<*0C*VzlyG7DnVr_>a+>%-@*M?iP<~wm_ znAg=>dhp@n;(qNRVfV11f;?V819n;a|`{N+Ib}p%6a%9JpHF&N;ZHh-F4XT{GYjG&g7K!G`XNw}b z{hH`*P{~E}0$PzUn;&yD(nLy!jos!wUeI$*Vz`XICQWGrHr70|Trdv#y-L1lVbxY1 zw`Yg_9^6^=i>yvgO3n^=G?ikv$*2sUj*{iwU6&shNMK#*I|#|h8H#pNr}RD2QjrD5 z0uxS-36QeoklUD5#k7>1v1F&EGG}q!o~?!cWK;$u*{>ayNk^m*1=6RvH_TNIAa}5Q zkJ;bKd6krotqK@$Q^)l7tarT-31)j_=S-cftzqg#({+bF$!1ZgV>6`|r^PoAj?{@^ z_QdzD%{ag|+dsG2B{CV|TV+p}Ig?b9+~G^JW*r~_ERur+rKORyXLTobFzt3peX)6j zJuM~~hym&*87ewB##VIn{UiY-LOL5J(m>6#^P5|+J2ji6a$2=7I)Et|TazS^DFTQS z?VtxujI>!jrIm~%8nS}rO}9^-OIQ~n!M#$sN}JXdX$KKzxY6vhFm0#;ZK)HGQy0QV z-FRodFlpEFpV2C&AY_}bt{F;-0Y-JtZuC>@m0C|fVpnn&3*&PdXF1Go9&DIBuL(1n z((Bl)E_qbs>TXw)sxv(dKCDl`r2y9C^g>$Ds79q`0^)-4t)s+ANs%N4j9sTF1r#EB zrJ!6sN*=8P+%j#{jGo|oh?^i(G$W6R5OsD_GXP#51fBsY8S7NLaJsLMqd4%UTE`#6 zvdIHNw4oxFnAopiPWC`p-^K1XbYutJ1Z!47FdJ(ul}ft1Fr=7Rr~~zi$!YppW@iUp zw;$g2Czj|ym0&EL^n8d&*Y>sX=pJN2n6eZKK{sA85pL%xC^|viaA=0e2m&T*Gy4YGQ6p!gZo~uC$2Gf#0E`rKhLtY_wyRE4~Lc> z?9c9$OvYmdq&^gm<$feE+&~W2^hv7B8$4adez)l8$fmk~akTjE(2b41%~xohFRM^h zN-#xmI&91PaMJfMZz$xIB^9OeDRenQzzWjU+a@7@2j*2cf4cu&c)0nwTFuc7bRA;@ zL7~+pH-xIFyrI~ZP&w~xW(|3`&o*(t5ECuEm{?{kQ$7L;6WgqbU*@+i&5rg0)j@X0 z3_+}pRF{WJ_iis;7ofL2%!}SWe++6Lod(!+tS23{wdzJ~U(X(wU%rf&PYV%EC*j@T z%=fN0#@+Kl*1bu`zJPkZ{WD4xy35}hNis_<6)YrI4VLZ8tGK!hz)2yxU`;cq#)Gm> zNX>j_AuGvCc@J8>Y;Wo zyqNTP&lvca5ovq4IW_==sUJgZAn|nvVsh=_vR#GOmB4bZW5x#N#>s@Xz^nLAuo1VQDhjjhl~{5z&u!mt5LJuZe%UN=(+( zlU8EQo%A5IZ;!R+#Gx^E6B*h<8dv=V@$hjmm%mm~9$tROXS-+q$iJ+XlBsG~nx=Lz zvZ+3*^uls@KnZ__Uu5DAI2@8Vr_Lg~p)QT3(1DO+{HYj{{7^R}*+4JJx}-k7rt(wM zK8?@ml0${G>nDNJyBUrKu>gcJ7CJ&zk9ir(IL8mr;MYyKb;-bwBQP>abG8UMW<%2UFmzSVK%|yv z!zH$AiFAu~XaX<*!)nP@zQtPBk~PGmL||Akti;dpeR>Ek5`a`pb)|k9<{GWzIZB%? zefJ!j4id2xKh;xj({u(6bEs7pE@sdQWAMF|a*?gMGIyN)u!x+(p`MRgtEdx<^1=@F zTx;!{zoKiggfp8!OUg6N1X?=Sut5*=W)mQXXw8%^T(EA987ArzPj6$G_Km{wX@;r4 fd|cc=DZhVJ5q|mPlO{$7Dl&fThI@nm{p