From 8f04e9b0384322b685176fb82d0883aeff8c5a74 Mon Sep 17 00:00:00 2001 From: nkongenely Date: Mon, 16 Sep 2024 09:52:52 +0300 Subject: [PATCH 01/12] Testing --- .python-version | 1 + delivery/handlers/staging_handlers.py | 2 +- delivery/services/delivery_service.py | 4 ++++ delivery/services/organise_service.py | 8 ++++++-- delivery/services/staging_service.py | 11 +++++++++-- tests/integration_tests/base.py | 4 +++- tests/integration_tests/test_integration.py | 1 + .../integration_tests/test_integration_dds.py | 12 ++++++------ tests/resources/readme/README.md | Bin 985 -> 1024 bytes .../MD5/checksums.md5 | 0 .../Projects/XYZ_123/test_file | Bin 0 -> 1024 bytes .../ABC_123/test_file | Bin 0 -> 1024 bytes .../ABC_123/test_file | Bin 0 -> 1024 bytes .../test_file | Bin 0 -> 1024 bytes 14 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 .python-version create mode 100644 tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/MD5/checksums.md5 create mode 100644 tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/Projects/XYZ_123/test_file create mode 100644 tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_z2l4kn_0/Projects/ABC_123/160930_ST-E00216_0555_BH37CWALXX_z2l4kn_0/ABC_123/test_file create mode 100644 tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_be6y0p1m/Projects/ABC_123/160930_ST-E00216_0556_BH37CWALXX_be6y0p1m/ABC_123/test_file create mode 100644 tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_jugr4wkp/Projects/XYZ_123/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/test_file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..66fa45e --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +arteria_delivery diff --git a/delivery/handlers/staging_handlers.py b/delivery/handlers/staging_handlers.py index 877d4a2..efada52 100644 --- a/delivery/handlers/staging_handlers.py +++ b/delivery/handlers/staging_handlers.py @@ -30,7 +30,7 @@ def _construct_response_from_project_and_status(self, staging_order_projects_and return link_results, id_results - + class StagingProjectRunfoldersHandler(BaseStagingHandler): """ Handler class for handling how to start staging of runfolders belonging to a project. Polling for status, diff --git a/delivery/services/delivery_service.py b/delivery/services/delivery_service.py index d09c968..9a398d4 100644 --- a/delivery/services/delivery_service.py +++ b/delivery/services/delivery_service.py @@ -71,6 +71,9 @@ def _create_links_area_for_project_runfolders(self, project_name, projects, batc :param batch_nbr: which batch of deliveries of this project this corresponds to :return: the path to the dir created """ + path = os.path.join(self.project_links_directory, project_name) + list_dir = [(x[0], os.listdir(x[0])) for x in os.walk(path)] + print(f"logging... delivery_service _create_links_area_for_project_runfolders path = {path}...list= {list_dir} ") project_dir = os.path.join(self.project_links_directory, project_name, str(batch_nbr)) try: @@ -184,6 +187,7 @@ def deliver_all_runfolders_for_project(self, project_name, mode): batch_nbr=batch_nbr) self.delivery_sources_repo.add_source(source) + print(f"logging... delivery_service deliver_all_runfolders_for_project path = {source}...project_name= {project_name},.. source_name= {project_name}/batch{batch_nbr}, links_directory= {links_directory} ") stage_order = self.staging_service.create_new_stage_order(path=source.path, project_name=project_name) self.staging_service.stage_order(stage_order) diff --git a/delivery/services/organise_service.py b/delivery/services/organise_service.py index 49f927b..b39a951 100644 --- a/delivery/services/organise_service.py +++ b/delivery/services/organise_service.py @@ -29,7 +29,7 @@ def __init__(self, runfolder_service, file_system_service=FileSystemService()): """ self.runfolder_service = runfolder_service self.file_system_service = file_system_service - + def organise_runfolder(self, runfolder_id, lanes, projects, force): """ Organise a runfolder in preparation for delivery. This will create separate subdirectories for each of the @@ -116,6 +116,7 @@ def organise_project( organised_project_runfolder_path, lanes)) # symlink the project files + organised_project_files = [] if project.project_files: for project_file in project.project_files: @@ -147,7 +148,7 @@ def organise_project_file(self, project_file, organised_project_path): before organisation :param organised_project_path: path where the project will be organised """ - + # the relative path from the project file base to the project file (e.g. plots/filename.png) relpath = self.file_system_service.relpath( project_file.file_path, @@ -162,6 +163,9 @@ def organise_project_file(self, project_file, organised_project_path): # copy the source file to the organised file destination self.file_system_service.copy(project_file.file_path, destination) + print(f"logging... organise_project_file destination = {destination}") + log.info(f"logging... organise_project_file destination = {destination}") + breakpoint() # return a new RunFolder file object representing the organised file at its new location return RunfolderFile( diff --git a/delivery/services/staging_service.py b/delivery/services/staging_service.py index 0052487..848a3ef 100644 --- a/delivery/services/staging_service.py +++ b/delivery/services/staging_service.py @@ -88,6 +88,8 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi staging_order = staging_repo.get_staging_order_by_id(staging_order_id, session) try: staging_source_with_trailing_slash = staging_order.source + "/" + # runfolders_for_projects = + # print(f"logging... _copy_dir os.readlink = {os.readlink(staging_source_with_trailing_slash)}") cmd = ['rsync', '--stats', '-r', '--copy-links', '--times', staging_source_with_trailing_slash, staging_order.staging_target] log.debug("Running rsync with command: {}".format(" ".join(cmd))) @@ -99,6 +101,10 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi execution_result = yield external_program_service.wait_for_execution(execution) log.debug("Execution result: {}".format(execution_result)) + staging_target = [(x[0], os.listdir(x[0])) for x in os.walk(staging_order.staging_target)] + print(f"logging... _copy_dir os.walk staging_order.staging_source_with_trailing_slash = {staging_source_with_trailing_slash}") + log.info(f"logging... _copy_dir os.walk staging_order.staging_target = {staging_target}") + breakpoint() if execution_result.status_code == 0: # Parse the file size from the output of rsync stats: @@ -149,10 +155,10 @@ def stage_order(self, stage_order): "external_program_service": self.external_program_service, "staging_repo": self.staging_repo, "session_factory": self.session_factory} - + print(f"logging... staging_service stage_order stage_order.staging_target before = {stage_order.staging_target}") if not self.file_system_service.exists(stage_order.staging_target): self.file_system_service.makedirs(stage_order.staging_target) - + print(f"logging... staging_service stage_order stage_order.staging_target after = {stage_order.staging_target}") yield StagingService._copy_dir(**args_for_copy_dir) # TODO Better error handling @@ -162,6 +168,7 @@ def stage_order(self, stage_order): raise e def create_new_stage_order(self, path, project_name): + print(f"logging... staging_service create_new_stage_order path = {path}......staging_dir = {self.staging_dir}") staging_order = self.staging_repo.create_staging_order(source=path, status=StagingStatus.pending, staging_target_dir=self.staging_dir, diff --git a/tests/integration_tests/base.py b/tests/integration_tests/base.py index 13cbbcf..835469d 100644 --- a/tests/integration_tests/base.py +++ b/tests/integration_tests/base.py @@ -30,8 +30,10 @@ def __init__(self, *args): # Default duration of mock delivery self.mock_duration = 0.1 - def _create_projects_dir_with_random_data(self, base_dir, proj_name='ABC_123'): + def _create_projects_dir_with_random_data(self, base_dir, proj_name='ABC_123', runfolder_name=None): tmp_proj_dir = os.path.join(base_dir, 'Projects', proj_name) + if runfolder_name: + tmp_proj_dir = os.path.join(tmp_proj_dir, runfolder_name, proj_name) os.makedirs(tmp_proj_dir) with open(os.path.join(tmp_proj_dir, 'test_file'), 'wb') as f: f.write(os.urandom(1024)) diff --git a/tests/integration_tests/test_integration.py b/tests/integration_tests/test_integration.py index a5ec4d9..4b5ed3a 100644 --- a/tests/integration_tests/test_integration.py +++ b/tests/integration_tests/test_integration.py @@ -52,6 +52,7 @@ def test_can_return_projects(self): def test_can_organise_project(self): runfolder = unorganised_runfolder() + breakpoint() with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix="{}_".format(runfolder.name)) as runfolder_path: runfolder = unorganised_runfolder( diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 7234440..bcd3952 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -174,14 +174,14 @@ def test_can_stage_and_deliver_batch_flowcells(self): @gen_test def test_can_stage_and_deliver_force_flowcells(self): with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', - prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ + prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: - self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123') - self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123') - + self._create_projects_dir_with_random_data(tmpdir1, 'ABC_123', ("").join(tmpdir1.split("/")[-1])) + self._create_projects_dir_with_random_data(tmpdir2, 'ABC_123', ("").join(tmpdir2.split("/")[-1])) + # breakpoint() # First just stage it - url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'XYZ_123']) + url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'ABC_123']) payload = {'delivery_mode': 'BATCH'} response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) self.assertEqual(response.code, 202) @@ -204,7 +204,7 @@ def test_can_stage_and_deliver_force_flowcells(self): time.sleep(1) for project, link in staging_status_links.items(): - self.assertEqual(project, 'XYZ_123') + self.assertEqual(project, 'ABC_123') status_response = yield self.http_client.fetch(link) self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) diff --git a/tests/resources/readme/README.md b/tests/resources/readme/README.md index a31412e28f296002568453f83f42b4041a83042a..646621891922500045bce0033f520e09700230f5 100644 GIT binary patch literal 1024 zcmV+b1poV&nSvKSPSEtb+5Ew*wr?`X^mEdjt6p`(N7`YewP|L@TDbEt1}2BphO2G+ zkDM)0)h61z$X@y7B)%$|WZt$NUt8{{dapJ_c7Ue8-+g4lBWmT%#2~o#aE9>G#7P4y z+qExQmCM(%Q&};O-Y23(NH)%McW3SO@mz|HYYZy;UrmZ;YX-; zU6bRE4Wgw0^3!%|pirk1eke6V5HSnecZd$bqP3kW>D38xz%u@?x%^Zo|Fu4MfG#>b zu6`eyEjEdL5C7y0QPyjENRta{$Ox+uDmHpw2cM*j_OgM#x`3b3m5!x4BVJVfsDOzY zo3TMS{+%4ZZUji)_d4ZF(0=%O$6*FKMo1ES{0uX#Idd*=bbcD# zeZqLk?k}vhc>z;YyR}N$gXqxIVgfV>7EbPmDv{~Urp%C?{_~=L6}DY3VgKPt;!zgb zYzpN$?3(>Nef!%{8O<^%|GJI+*=<&qXG0W>xwJIbC{}{i)0Es+SWGbYV;Yy0L756M zq+tvf?Q;pUTY#+wZ_x!iVifor+JTul9J&y`NQ~4KQI6}lR*L*wYHF>4IL=H&r^LCU z^@!S9+%g*MeCyFe!CUr#+waMvODzU&pNcw|P$?IGvn~(R44Ar^+nNHt7x}X^_w6Z# zQBPnFTVz~%-Xbju(WWcROm_C`)fgDozJ@v4B58DZ$wwed6Fc`mHlwg&yPO=oJmHf! z`Pr=MMPV`JAs|sZ{rXWY)F(XPF&Vi7rhG-^i^yF|+iR!}R4+z`n&W%kMX24*+rT?j zND{15dar8ClgJ8OQv3kYpo!KRi*Ms0yH^?>DGv@SBA5KA93|@c@&7-ZVXyzY+4av7_#s2Gw1!d0j zp=&#&lP6Iigrxlz36A)?u{87d*ov25x;}uB#|w8V2KE#*=jV6ZUcGX9@<#l<%yvDI zDymCUh;OWo=pSA^lg?ZqG5*1Awx`z^{ ze;&9H>yoSO#vHMFxlqb}?1L)cr%eGRWPoSfQwX#G literal 985 zcmbu7%W8u_7=`yf#Sek5Qb_{cln{_a(}0&mZJ{eO9VgY+Q8Sm`R(%MUeY!kJ$C!ph z+7wz5hVgjL|IJ}KFfr}fjp^TlXMtq|;R39gZ3bZZo&)Z5c78pd2Zn8Q!z&X4cYYR_ z3kc2emFwBw^cLo}5n7(_Xj+)09Ac8CPlUZfn&V8ygaapQNphU#_Yfn2l(3t#Di}qg z3kbNR6e$lQWx)hsMvx#eJf|W7M`j{jjJtpnf*;kN98exB6E4bEC{`d60vypYQ%gdK z0LhhCg)0_Xo0amSrt6?-oeoUC0J&fi3(1JKTrRa?$%+Sp#Yo#!)uwt^FASN?S49>R zHqt;no9bhy_@*&&Or6H9?|ViiU9_}d%NW#%I_6I;^ucznoV(`p}bM9C=HZ6TNRPBjww{ixUL>np^?TEBnWW;X%*{(cD< q90kDlbc54$ga6X~7;sG29PjdQIk+fIk?v_!_rIt=2DDJ?`}_&VYh`x; diff --git a/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/MD5/checksums.md5 b/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/MD5/checksums.md5 new file mode 100644 index 0000000..e69de29 diff --git a/tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/Projects/XYZ_123/test_file b/tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/Projects/XYZ_123/test_file new file mode 100644 index 0000000000000000000000000000000000000000..465c233907d512cafc0f023dbbb5f7d0eec7cc2f GIT binary patch literal 1024 zcmV+b1poV5%Xr=?i9Ou8nBAuUhcFoILTw`zlLK~bzY0KtEG$&vZ4Qn{=96+>IChOr zLZJgTb)y^hx-%GtoTuIhC5Ki#H0PA%Jl%BfOYSvZ_$Z?P;4w zXc+G!j{v#LPC|53ycNR|4J0#FmJiPOGvJY6I()8v`F5VCTcYnAJuvVZ)`QlUrxB8p zr8gCz$LTeNT)qI3@-ZN`ot|kYVOZiRk;LSkxU#UgBq2Vzo~RlXdkmz9#(HJ;C3t|C$TF&`Us~d4}%yC&d_Ib1s(h z=c8HLNY$svw}_1;w1cD^nx~RF#EBuqSJZoxI8Nvn4>*iX^@z)9C8TC5NiFc<_0*(e zIRsaJ;;T36y_#DZbpskBY3)AbR_S2Jv|5koLC>V8)DHp2;9t>Q7QJ<~7Tk61YDW zD-68^?uE)#fw3hA)Jcj2>|HTCEUlzkTN725gS7~-Y9b~frVrAZWx*M^5jJep)}5Lg zt9!+^QvD&+*DCTa@Z+CliABoqu564IZ=Y>dO1A5pdrvo{DA0O|fK-;*PF85XQU7_u zuMusCcut~%yMbIR<1*4JO>#-d0=k5Ee^GQvgysB7IkN+zzFckl7dYF2jNdfvxg8w~ zo=J!1gQG=|ocyC^C>=z~MeSm`RO0v8Df-zaf&iAa*}Q^f(tSYTWJ}V**iVf_8{0xU zuAEVKIG&>lJ=l_;DyZ?5*$Ix(tgK2|fk3dO2;fN}H3>S!V|c1Y(a`Z%ONmx8Sm4+l zrGEvVratU>H*l!naMMpz*%?}mNYj(k{CNP9VQ^UA9N&(7H>Bo<5&f<4rm3?|q@C=p zWNtkCq*TZ1xK`YF*MvV&h1YdlPD|R0zF#_u+Y@78Si_dD(9+k2xx#J%Yy0CTX8^hD zevLg^jTu6XYg6KlFS&G?E?~kC1p9hJOVVJo5eiFT(%AFXm^_oVx~Y(|M4o&~?k?k{ zL*sEi(dVDTaqifHY;!s5R^3aS5DY9W5>m!iMtk}qT(0B5rKSjafptQvrX)Tc)JXe? zRdC3|<{#mgt$Xg6D2*PAG%%1^oxz#ngQuH8xLaFXc#FX&n=S(WpH9HDG@wJ)wa(d( u&|E>cmcd6>Qwo3Zt26>0uB{6rMx_|Wnn2wHaAuA_e>#t3t!1q zWk2V{haQ~5Wde)J2arOkKPr^!myG2`EzUwTjkh35yG3*y_DAa&Hk;Ka$8 zNrOFI*HYIKs*?}(e%2j%EPCJoDI3A=j@CLk1x-czTQx*nO8r#W2*-=XLM;qoywme* z%_i2Z4F%hVwg=MtSw0K8J9X+wvohFhbiYL$1F9-R5E;5LCieLh7bYbR+WtC?z+_NA+p%$>+s-*kiptPR%|>(O{CKT}Z7U!5MqL+yJMDZ1`o_w;aI zfv+VGGA;J^jl|%)=Scc1-@ff_srv^deDE61)>|dP{JjGVfYw!13rl&f`vGO3*pDd&-7@&PWR664Zvf?1Cf6pC=M%6r<`^B8{57?64h!>G3M zERKqlR|k+!AjrzRMkza-&?@!xe)iFsLxhaq;>%lk^ggJ(+vF`lI@d0FhjXks771GDJWEEf;0yta%^n#A>8se*F)5w_!^Xkf$-Sd;|LBsuC4!Dm zYOqMlNMX|W;3!FoETg}kH|<&wjR*u(#Ags=s!Nh4gL5HO~`3A8`^4rAIf2%H-sQF#}JU0bnOCVfA|U5mw& uQ4L@xgV6&`cRpp zc-Pp(LH;FmXeULAiT(5cTRWq%KiTrk1~7R*KQDJ6P5|d{*%6Zm^m1tW%L$Uz^hupw z$a+4}TwR>r*@X8PXJ`1qOohvqe2}v78UJ?_s>3FN6mM)sh2-gf%nJ-P2EJd*L$isw z^Mg!c7W<&@?aZ=%?CL76Qfo>A0$@Uz2+{BsFLfT#dgyUCIHMn_pa90lRtn-umC{*2 zj>swfe))lkNQs|Cj^QL9V-fkkUNoc4y-=hqRs+oTSW>Uu+XPLqUfeV|iCVeUvnpMf zQ3Doh9nFvlGXbrTqh`lAo2l&+iyLYu`OtO3llK@Z7{H49IDbn}hDA2{Qrqd0EdUKAM0F@Z+MMm=g*Inf-sVr5c$jPsziJnUqX6fR97qal=b2fiTj#<;M z-}DV{V#YcXg#1jr+Mdzp)aOJAQfuVssIk5W3E2(e&J8JpMd4Led5&eOP+GQ?ZJj^T z#_vHu)XHu9wIDPJH;DGwq-c3aYUo$k29D+|cy>brD5)lT`B8`Pp1a_~>gq>4qRF|J^+Pus41nZ3wxIYu_SIp{UE9*RlsV9!W z3N>PY{U^pagedOwvHlzNd8c_bq*tcvD-nfQzS)Lc`<`3JG{G%eXE*?f1s?LH$4wNb zo{%QWN4vGzJiWh)b%0oT5G@T?uj%hQ8fxAqq(BzOrmzCY_sg~aA4g0N)dQ>EoyQb) z+xIfBAa|2r9lHDUT-Q({n8jQ}H}#T0(MtjZzMi!?GZDOP-WmOEH63>F88(z`&Q4q z*gN^Lhgl5eI$u8U;J=4=G|4DKnsT->X?vHdIIo`P811POclkIq5zOmtC4h$koVuV| z3T)*dMj$vq@vvV{hM+n?JeP+{X$|_!sDdA4b+=Vvhgm}$j|EV|6%pYZ0tj8c u;m?=7WRad;U0vf_;LB{xtOwwU=e*FgzJdsm+P6!7beQk?2%>|1vtfq~u?bQD literal 0 HcmV?d00001 diff --git a/tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_jugr4wkp/Projects/XYZ_123/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/test_file b/tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_jugr4wkp/Projects/XYZ_123/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/test_file new file mode 100644 index 0000000000000000000000000000000000000000..3ca11ad27424173268d9389d5c8e5f99b5c3d1db GIT binary patch literal 1024 zcmV+b1poV{$1nIS;ajH4o(FZM)NjnRoeZp%)%V zqAo}#J3@S{WO)K{_kli#n+C#!tn41mFaj71q9q3+^l6!)-yQ0|Q()+|KI65km=tG zU+fNAoo(CYl(0UOUF#^%XL?lk32UM`G?iVd>g*AY1eP?0IRnN=;3U12_%JUYGexa? zZ`y2svJ<`38#SV-YYa5CX#MO;u{+2(l_-kJfVm1)i9n}XhqfoEjXCYe+9F6|n$#tfc^5Idb}d-D`=Raa=IuEuAr+<)`=*t{Pj z`e|J)=v{9y&9ZF4Oljp9Xa%M5D=RO`wWbtBvjd5e+Z2L>M|;_@ zvRNM-?;^;O5Q3^>i}+|+l*I4+dj|fttt%I>TYTLM*B;m!(>%_=%+Y6sGEGQ{=yrmaWtRut{3-2bXi3z0> z+JL>la0cDH?!XyB1 z4;Bgx`?q%4I_P2&O$9#PPr-`OX{-7>u9QAePs;wqq!&@*GXfi uG(9qc#=Qvj>`(8u@rGagBB(_RnX Date: Mon, 16 Sep 2024 14:25:27 +0200 Subject: [PATCH 02/12] DATAOPS-467:Removed_extra_runfolder --- .python-version | 1 - delivery/services/delivery_service.py | 15 +++++++------ delivery/services/organise_service.py | 3 --- delivery/services/staging_service.py | 20 +++++------------- tests/integration_tests/base.py | 2 +- tests/integration_tests/test_integration.py | 2 +- .../integration_tests/test_integration_dds.py | 12 ++++++----- .../MD5/checksums.md5 | 0 .../Projects/ABC_123/test_file | 1 - .../Projects/XYZ_123/test_file | Bin 1024 -> 0 bytes .../ABC_123/test_file | Bin 1024 -> 0 bytes .../ABC_123/test_file | Bin 1024 -> 0 bytes .../test_file | Bin 1024 -> 0 bytes 13 files changed, 22 insertions(+), 34 deletions(-) delete mode 100644 .python-version delete mode 100644 tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/MD5/checksums.md5 delete mode 100644 tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file delete mode 100644 tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/Projects/XYZ_123/test_file delete mode 100644 tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_z2l4kn_0/Projects/ABC_123/160930_ST-E00216_0555_BH37CWALXX_z2l4kn_0/ABC_123/test_file delete mode 100644 tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_be6y0p1m/Projects/ABC_123/160930_ST-E00216_0556_BH37CWALXX_be6y0p1m/ABC_123/test_file delete mode 100644 tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_jugr4wkp/Projects/XYZ_123/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/test_file diff --git a/.python-version b/.python-version deleted file mode 100644 index 66fa45e..0000000 --- a/.python-version +++ /dev/null @@ -1 +0,0 @@ -arteria_delivery diff --git a/delivery/services/delivery_service.py b/delivery/services/delivery_service.py index 9a398d4..f720878 100644 --- a/delivery/services/delivery_service.py +++ b/delivery/services/delivery_service.py @@ -71,9 +71,6 @@ def _create_links_area_for_project_runfolders(self, project_name, projects, batc :param batch_nbr: which batch of deliveries of this project this corresponds to :return: the path to the dir created """ - path = os.path.join(self.project_links_directory, project_name) - list_dir = [(x[0], os.listdir(x[0])) for x in os.walk(path)] - print(f"logging... delivery_service _create_links_area_for_project_runfolders path = {path}...list= {list_dir} ") project_dir = os.path.join(self.project_links_directory, project_name, str(batch_nbr)) try: @@ -85,7 +82,13 @@ def _create_links_area_for_project_runfolders(self, project_name, projects, batc for project in projects: try: link_name = os.path.join(project_dir, project.runfolder_name) - self.file_system_service.symlink(project.path, link_name) + project_path = project.path + if ( + os.path.exists(runfolder_path := os.path.join(project.path, project.runfolder_name)) and + len(os.listdir(project_path)) == 1 + ): + project_path = runfolder_path + self.file_system_service.symlink(project_path, link_name) except FileExistsError as e: log.error("Project link: {} already exists".format(project_dir)) raise e @@ -132,7 +135,7 @@ def _get_projects_to_deliver(self, projects, mode, batch_nbr): raise NotImplementedError("This is not a valid state, delivery mode needs to be CLEAN/" "BATCH/FORCE.") - def deliver_all_runfolders_for_project(self, project_name, mode): + def deliver_all_runfolders_for_project(self, project_name, mode, request_url=None): """ This method will attempt to deliver all runfolders for the specified project. @@ -187,8 +190,6 @@ def deliver_all_runfolders_for_project(self, project_name, mode): batch_nbr=batch_nbr) self.delivery_sources_repo.add_source(source) - print(f"logging... delivery_service deliver_all_runfolders_for_project path = {source}...project_name= {project_name},.. source_name= {project_name}/batch{batch_nbr}, links_directory= {links_directory} ") - stage_order = self.staging_service.create_new_stage_order(path=source.path, project_name=project_name) self.staging_service.stage_order(stage_order) return {source.project_name: stage_order.id}, projects_to_deliver diff --git a/delivery/services/organise_service.py b/delivery/services/organise_service.py index b39a951..7754e0a 100644 --- a/delivery/services/organise_service.py +++ b/delivery/services/organise_service.py @@ -163,9 +163,6 @@ def organise_project_file(self, project_file, organised_project_path): # copy the source file to the organised file destination self.file_system_service.copy(project_file.file_path, destination) - print(f"logging... organise_project_file destination = {destination}") - log.info(f"logging... organise_project_file destination = {destination}") - breakpoint() # return a new RunFolder file object representing the organised file at its new location return RunfolderFile( diff --git a/delivery/services/staging_service.py b/delivery/services/staging_service.py index 848a3ef..bd5ebfd 100644 --- a/delivery/services/staging_service.py +++ b/delivery/services/staging_service.py @@ -88,30 +88,22 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi staging_order = staging_repo.get_staging_order_by_id(staging_order_id, session) try: staging_source_with_trailing_slash = staging_order.source + "/" - # runfolders_for_projects = - # print(f"logging... _copy_dir os.readlink = {os.readlink(staging_source_with_trailing_slash)}") cmd = ['rsync', '--stats', '-r', '--copy-links', '--times', staging_source_with_trailing_slash, staging_order.staging_target] - log.debug("Running rsync with command: {}".format(" ".join(cmd))) - execution = external_program_service.run(cmd) staging_order.pid = execution.pid session.commit() execution_result = yield external_program_service.wait_for_execution(execution) - log.debug("Execution result: {}".format(execution_result)) - staging_target = [(x[0], os.listdir(x[0])) for x in os.walk(staging_order.staging_target)] - print(f"logging... _copy_dir os.walk staging_order.staging_source_with_trailing_slash = {staging_source_with_trailing_slash}") - log.info(f"logging... _copy_dir os.walk staging_order.staging_target = {staging_target}") - breakpoint() + if execution_result.status_code == 0: # Parse the file size from the output of rsync stats: # Total file size: 207,707,566 bytes match = re.search(r'Total file size: ([\d,]+) bytes', - execution_result.stdout, - re.MULTILINE) + execution_result.stdout, + re.MULTILINE) size_of_transfer = match.group(1) size_of_transfer = int(size_of_transfer.replace(",", "")) staging_order.size = size_of_transfer @@ -121,7 +113,7 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi else: staging_order.status = StagingStatus.staging_failed log.error("Failed in staging: {} because rsync returned exit code: {}". - format(staging_order, execution_result.status_code)) + format(staging_order, execution_result.status_code)) # TODO Better exception handling here... except Exception as e: @@ -155,10 +147,9 @@ def stage_order(self, stage_order): "external_program_service": self.external_program_service, "staging_repo": self.staging_repo, "session_factory": self.session_factory} - print(f"logging... staging_service stage_order stage_order.staging_target before = {stage_order.staging_target}") if not self.file_system_service.exists(stage_order.staging_target): self.file_system_service.makedirs(stage_order.staging_target) - print(f"logging... staging_service stage_order stage_order.staging_target after = {stage_order.staging_target}") + yield StagingService._copy_dir(**args_for_copy_dir) # TODO Better error handling @@ -168,7 +159,6 @@ def stage_order(self, stage_order): raise e def create_new_stage_order(self, path, project_name): - print(f"logging... staging_service create_new_stage_order path = {path}......staging_dir = {self.staging_dir}") staging_order = self.staging_repo.create_staging_order(source=path, status=StagingStatus.pending, staging_target_dir=self.staging_dir, diff --git a/tests/integration_tests/base.py b/tests/integration_tests/base.py index 835469d..f2942f2 100644 --- a/tests/integration_tests/base.py +++ b/tests/integration_tests/base.py @@ -33,7 +33,7 @@ def __init__(self, *args): def _create_projects_dir_with_random_data(self, base_dir, proj_name='ABC_123', runfolder_name=None): tmp_proj_dir = os.path.join(base_dir, 'Projects', proj_name) if runfolder_name: - tmp_proj_dir = os.path.join(tmp_proj_dir, runfolder_name, proj_name) + tmp_proj_dir = os.path.join(tmp_proj_dir, runfolder_name) os.makedirs(tmp_proj_dir) with open(os.path.join(tmp_proj_dir, 'test_file'), 'wb') as f: f.write(os.urandom(1024)) diff --git a/tests/integration_tests/test_integration.py b/tests/integration_tests/test_integration.py index 4b5ed3a..277fb0a 100644 --- a/tests/integration_tests/test_integration.py +++ b/tests/integration_tests/test_integration.py @@ -52,7 +52,7 @@ def test_can_return_projects(self): def test_can_organise_project(self): runfolder = unorganised_runfolder() - breakpoint() + with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix="{}_".format(runfolder.name)) as runfolder_path: runfolder = unorganised_runfolder( diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index bcd3952..033d24c 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -1,3 +1,4 @@ +import os import json import time import tempfile @@ -177,11 +178,12 @@ def test_can_stage_and_deliver_force_flowcells(self): prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: - self._create_projects_dir_with_random_data(tmpdir1, 'ABC_123', ("").join(tmpdir1.split("/")[-1])) - self._create_projects_dir_with_random_data(tmpdir2, 'ABC_123', ("").join(tmpdir2.split("/")[-1])) - # breakpoint() + + self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123', os.path.basename(tmpdir1)) + self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123', os.path.basename(tmpdir2)) + # First just stage it - url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'ABC_123']) + url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'XYZ_123']) payload = {'delivery_mode': 'BATCH'} response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) self.assertEqual(response.code, 202) @@ -204,7 +206,7 @@ def test_can_stage_and_deliver_force_flowcells(self): time.sleep(1) for project, link in staging_status_links.items(): - self.assertEqual(project, 'ABC_123') + self.assertEqual(project, 'XYZ_123') status_response = yield self.http_client.fetch(link) self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) diff --git a/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/MD5/checksums.md5 b/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/MD5/checksums.md5 deleted file mode 100644 index e69de29..0000000 diff --git a/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file b/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file deleted file mode 100644 index db11c83..0000000 --- a/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file +++ /dev/null @@ -1 +0,0 @@ -Test content... \ No newline at end of file diff --git a/tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/Projects/XYZ_123/test_file b/tests/resources/runfolders/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/Projects/XYZ_123/test_file deleted file mode 100644 index 465c233907d512cafc0f023dbbb5f7d0eec7cc2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 zcmV+b1poV5%Xr=?i9Ou8nBAuUhcFoILTw`zlLK~bzY0KtEG$&vZ4Qn{=96+>IChOr zLZJgTb)y^hx-%GtoTuIhC5Ki#H0PA%Jl%BfOYSvZ_$Z?P;4w zXc+G!j{v#LPC|53ycNR|4J0#FmJiPOGvJY6I()8v`F5VCTcYnAJuvVZ)`QlUrxB8p zr8gCz$LTeNT)qI3@-ZN`ot|kYVOZiRk;LSkxU#UgBq2Vzo~RlXdkmz9#(HJ;C3t|C$TF&`Us~d4}%yC&d_Ib1s(h z=c8HLNY$svw}_1;w1cD^nx~RF#EBuqSJZoxI8Nvn4>*iX^@z)9C8TC5NiFc<_0*(e zIRsaJ;;T36y_#DZbpskBY3)AbR_S2Jv|5koLC>V8)DHp2;9t>Q7QJ<~7Tk61YDW zD-68^?uE)#fw3hA)Jcj2>|HTCEUlzkTN725gS7~-Y9b~frVrAZWx*M^5jJep)}5Lg zt9!+^QvD&+*DCTa@Z+CliABoqu564IZ=Y>dO1A5pdrvo{DA0O|fK-;*PF85XQU7_u zuMusCcut~%yMbIR<1*4JO>#-d0=k5Ee^GQvgysB7IkN+zzFckl7dYF2jNdfvxg8w~ zo=J!1gQG=|ocyC^C>=z~MeSm`RO0v8Df-zaf&iAa*}Q^f(tSYTWJ}V**iVf_8{0xU zuAEVKIG&>lJ=l_;DyZ?5*$Ix(tgK2|fk3dO2;fN}H3>S!V|c1Y(a`Z%ONmx8Sm4+l zrGEvVratU>H*l!naMMpz*%?}mNYj(k{CNP9VQ^UA9N&(7H>Bo<5&f<4rm3?|q@C=p zWNtkCq*TZ1xK`YF*MvV&h1YdlPD|R0zF#_u+Y@78Si_dD(9+k2xx#J%Yy0CTX8^hD zevLg^jTu6XYg6KlFS&G?E?~kC1p9hJOVVJo5eiFT(%AFXm^_oVx~Y(|M4o&~?k?k{ zL*sEi(dVDTaqifHY;!s5R^3aS5DY9W5>m!iMtk}qT(0B5rKSjafptQvrX)Tc)JXe? zRdC3|<{#mgt$Xg6D2*PAG%%1^oxz#ngQuH8xLaFXc#FX&n=S(WpH9HDG@wJ)wa(d( u&|E>cmcd6>Qwo3Zt26>0uB{6rMx_|Wnn2wHaAuA_e>#t3t!1q zWk2V{haQ~5Wde)J2arOkKPr^!myG2`EzUwTjkh35yG3*y_DAa&Hk;Ka$8 zNrOFI*HYIKs*?}(e%2j%EPCJoDI3A=j@CLk1x-czTQx*nO8r#W2*-=XLM;qoywme* z%_i2Z4F%hVwg=MtSw0K8J9X+wvohFhbiYL$1F9-R5E;5LCieLh7bYbR+WtC?z+_NA+p%$>+s-*kiptPR%|>(O{CKT}Z7U!5MqL+yJMDZ1`o_w;aI zfv+VGGA;J^jl|%)=Scc1-@ff_srv^deDE61)>|dP{JjGVfYw!13rl&f`vGO3*pDd&-7@&PWR664Zvf?1Cf6pC=M%6r<`^B8{57?64h!>G3M zERKqlR|k+!AjrzRMkza-&?@!xe)iFsLxhaq;>%lk^ggJ(+vF`lI@d0FhjXks771GDJWEEf;0yta%^n#A>8se*F)5w_!^Xkf$-Sd;|LBsuC4!Dm zYOqMlNMX|W;3!FoETg}kH|<&wjR*u(#Ags=s!Nh4gL5HO~`3A8`^4rAIf2%H-sQF#}JU0bnOCVfA|U5mw& uQ4L@xgV6&`cRpp zc-Pp(LH;FmXeULAiT(5cTRWq%KiTrk1~7R*KQDJ6P5|d{*%6Zm^m1tW%L$Uz^hupw z$a+4}TwR>r*@X8PXJ`1qOohvqe2}v78UJ?_s>3FN6mM)sh2-gf%nJ-P2EJd*L$isw z^Mg!c7W<&@?aZ=%?CL76Qfo>A0$@Uz2+{BsFLfT#dgyUCIHMn_pa90lRtn-umC{*2 zj>swfe))lkNQs|Cj^QL9V-fkkUNoc4y-=hqRs+oTSW>Uu+XPLqUfeV|iCVeUvnpMf zQ3Doh9nFvlGXbrTqh`lAo2l&+iyLYu`OtO3llK@Z7{H49IDbn}hDA2{Qrqd0EdUKAM0F@Z+MMm=g*Inf-sVr5c$jPsziJnUqX6fR97qal=b2fiTj#<;M z-}DV{V#YcXg#1jr+Mdzp)aOJAQfuVssIk5W3E2(e&J8JpMd4Led5&eOP+GQ?ZJj^T z#_vHu)XHu9wIDPJH;DGwq-c3aYUo$k29D+|cy>brD5)lT`B8`Pp1a_~>gq>4qRF|J^+Pus41nZ3wxIYu_SIp{UE9*RlsV9!W z3N>PY{U^pagedOwvHlzNd8c_bq*tcvD-nfQzS)Lc`<`3JG{G%eXE*?f1s?LH$4wNb zo{%QWN4vGzJiWh)b%0oT5G@T?uj%hQ8fxAqq(BzOrmzCY_sg~aA4g0N)dQ>EoyQb) z+xIfBAa|2r9lHDUT-Q({n8jQ}H}#T0(MtjZzMi!?GZDOP-WmOEH63>F88(z`&Q4q z*gN^Lhgl5eI$u8U;J=4=G|4DKnsT->X?vHdIIo`P811POclkIq5zOmtC4h$koVuV| z3T)*dMj$vq@vvV{hM+n?JeP+{X$|_!sDdA4b+=Vvhgm}$j|EV|6%pYZ0tj8c u;m?=7WRad;U0vf_;LB{xtOwwU=e*FgzJdsm+P6!7beQk?2%>|1vtfq~u?bQD diff --git a/tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_jugr4wkp/Projects/XYZ_123/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/test_file b/tests/resources/runfolders/160930_ST-E00216_0556_BH37CWALXX_jugr4wkp/Projects/XYZ_123/160930_ST-E00216_0555_BH37CWALXX_tfez43vf/test_file deleted file mode 100644 index 3ca11ad27424173268d9389d5c8e5f99b5c3d1db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 zcmV+b1poV{$1nIS;ajH4o(FZM)NjnRoeZp%)%V zqAo}#J3@S{WO)K{_kli#n+C#!tn41mFaj71q9q3+^l6!)-yQ0|Q()+|KI65km=tG zU+fNAoo(CYl(0UOUF#^%XL?lk32UM`G?iVd>g*AY1eP?0IRnN=;3U12_%JUYGexa? zZ`y2svJ<`38#SV-YYa5CX#MO;u{+2(l_-kJfVm1)i9n}XhqfoEjXCYe+9F6|n$#tfc^5Idb}d-D`=Raa=IuEuAr+<)`=*t{Pj z`e|J)=v{9y&9ZF4Oljp9Xa%M5D=RO`wWbtBvjd5e+Z2L>M|;_@ zvRNM-?;^;O5Q3^>i}+|+l*I4+dj|fttt%I>TYTLM*B;m!(>%_=%+Y6sGEGQ{=yrmaWtRut{3-2bXi3z0> z+JL>la0cDH?!XyB1 z4;Bgx`?q%4I_P2&O$9#PPr-`OX{-7>u9QAePs;wqq!&@*GXfi uG(9qc#=Qvj>`(8u@rGagBB(_RnX Date: Mon, 16 Sep 2024 14:34:46 +0200 Subject: [PATCH 03/12] Removed unwanted code and cleaned u files --- delivery/handlers/staging_handlers.py | 1 - delivery/services/delivery_service.py | 2 +- delivery/services/organise_service.py | 2 -- delivery/services/staging_service.py | 10 +++++----- tests/integration_tests/test_integration.py | 1 - tests/integration_tests/test_integration_dds.py | 3 +-- tests/resources/readme/README.md | Bin 1024 -> 0 bytes 7 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 tests/resources/readme/README.md diff --git a/delivery/handlers/staging_handlers.py b/delivery/handlers/staging_handlers.py index efada52..7c5529c 100644 --- a/delivery/handlers/staging_handlers.py +++ b/delivery/handlers/staging_handlers.py @@ -30,7 +30,6 @@ def _construct_response_from_project_and_status(self, staging_order_projects_and return link_results, id_results - class StagingProjectRunfoldersHandler(BaseStagingHandler): """ Handler class for handling how to start staging of runfolders belonging to a project. Polling for status, diff --git a/delivery/services/delivery_service.py b/delivery/services/delivery_service.py index f720878..5a8f72c 100644 --- a/delivery/services/delivery_service.py +++ b/delivery/services/delivery_service.py @@ -135,7 +135,7 @@ def _get_projects_to_deliver(self, projects, mode, batch_nbr): raise NotImplementedError("This is not a valid state, delivery mode needs to be CLEAN/" "BATCH/FORCE.") - def deliver_all_runfolders_for_project(self, project_name, mode, request_url=None): + def deliver_all_runfolders_for_project(self, project_name, mode): """ This method will attempt to deliver all runfolders for the specified project. diff --git a/delivery/services/organise_service.py b/delivery/services/organise_service.py index 7754e0a..71ebd66 100644 --- a/delivery/services/organise_service.py +++ b/delivery/services/organise_service.py @@ -29,7 +29,6 @@ def __init__(self, runfolder_service, file_system_service=FileSystemService()): """ self.runfolder_service = runfolder_service self.file_system_service = file_system_service - def organise_runfolder(self, runfolder_id, lanes, projects, force): """ Organise a runfolder in preparation for delivery. This will create separate subdirectories for each of the @@ -148,7 +147,6 @@ def organise_project_file(self, project_file, organised_project_path): before organisation :param organised_project_path: path where the project will be organised """ - # the relative path from the project file base to the project file (e.g. plots/filename.png) relpath = self.file_system_service.relpath( project_file.file_path, diff --git a/delivery/services/staging_service.py b/delivery/services/staging_service.py index bd5ebfd..cc1a1d2 100644 --- a/delivery/services/staging_service.py +++ b/delivery/services/staging_service.py @@ -96,14 +96,14 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi session.commit() execution_result = yield external_program_service.wait_for_execution(execution) - + log.debug("Execution result: {}".format(execution_result)) if execution_result.status_code == 0: # Parse the file size from the output of rsync stats: # Total file size: 207,707,566 bytes match = re.search(r'Total file size: ([\d,]+) bytes', - execution_result.stdout, - re.MULTILINE) + execution_result.stdout, + re.MULTILINE) size_of_transfer = match.group(1) size_of_transfer = int(size_of_transfer.replace(",", "")) staging_order.size = size_of_transfer @@ -113,7 +113,7 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi else: staging_order.status = StagingStatus.staging_failed log.error("Failed in staging: {} because rsync returned exit code: {}". - format(staging_order, execution_result.status_code)) + format(staging_order, execution_result.status_code)) # TODO Better exception handling here... except Exception as e: @@ -149,7 +149,7 @@ def stage_order(self, stage_order): "session_factory": self.session_factory} if not self.file_system_service.exists(stage_order.staging_target): self.file_system_service.makedirs(stage_order.staging_target) - + yield StagingService._copy_dir(**args_for_copy_dir) # TODO Better error handling diff --git a/tests/integration_tests/test_integration.py b/tests/integration_tests/test_integration.py index 277fb0a..a5ec4d9 100644 --- a/tests/integration_tests/test_integration.py +++ b/tests/integration_tests/test_integration.py @@ -52,7 +52,6 @@ def test_can_return_projects(self): def test_can_organise_project(self): runfolder = unorganised_runfolder() - with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix="{}_".format(runfolder.name)) as runfolder_path: runfolder = unorganised_runfolder( diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 033d24c..6ffb6ff 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -175,10 +175,9 @@ def test_can_stage_and_deliver_batch_flowcells(self): @gen_test def test_can_stage_and_deliver_force_flowcells(self): with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', - prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ + prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: - self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123', os.path.basename(tmpdir1)) self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123', os.path.basename(tmpdir2)) diff --git a/tests/resources/readme/README.md b/tests/resources/readme/README.md deleted file mode 100644 index 646621891922500045bce0033f520e09700230f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 zcmV+b1poV&nSvKSPSEtb+5Ew*wr?`X^mEdjt6p`(N7`YewP|L@TDbEt1}2BphO2G+ zkDM)0)h61z$X@y7B)%$|WZt$NUt8{{dapJ_c7Ue8-+g4lBWmT%#2~o#aE9>G#7P4y z+qExQmCM(%Q&};O-Y23(NH)%McW3SO@mz|HYYZy;UrmZ;YX-; zU6bRE4Wgw0^3!%|pirk1eke6V5HSnecZd$bqP3kW>D38xz%u@?x%^Zo|Fu4MfG#>b zu6`eyEjEdL5C7y0QPyjENRta{$Ox+uDmHpw2cM*j_OgM#x`3b3m5!x4BVJVfsDOzY zo3TMS{+%4ZZUji)_d4ZF(0=%O$6*FKMo1ES{0uX#Idd*=bbcD# zeZqLk?k}vhc>z;YyR}N$gXqxIVgfV>7EbPmDv{~Urp%C?{_~=L6}DY3VgKPt;!zgb zYzpN$?3(>Nef!%{8O<^%|GJI+*=<&qXG0W>xwJIbC{}{i)0Es+SWGbYV;Yy0L756M zq+tvf?Q;pUTY#+wZ_x!iVifor+JTul9J&y`NQ~4KQI6}lR*L*wYHF>4IL=H&r^LCU z^@!S9+%g*MeCyFe!CUr#+waMvODzU&pNcw|P$?IGvn~(R44Ar^+nNHt7x}X^_w6Z# zQBPnFTVz~%-Xbju(WWcROm_C`)fgDozJ@v4B58DZ$wwed6Fc`mHlwg&yPO=oJmHf! z`Pr=MMPV`JAs|sZ{rXWY)F(XPF&Vi7rhG-^i^yF|+iR!}R4+z`n&W%kMX24*+rT?j zND{15dar8ClgJ8OQv3kYpo!KRi*Ms0yH^?>DGv@SBA5KA93|@c@&7-ZVXyzY+4av7_#s2Gw1!d0j zp=&#&lP6Iigrxlz36A)?u{87d*ov25x;}uB#|w8V2KE#*=jV6ZUcGX9@<#l<%yvDI zDymCUh;OWo=pSA^lg?ZqG5*1Awx`z^{ ze;&9H>yoSO#vHMFxlqb}?1L)cr%eGRWPoSfQwX#G From 6a033a736ab613b5cd5e1644106251175ab2616b Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Tue, 17 Sep 2024 13:39:02 +0200 Subject: [PATCH 04/12] Code formatting and changes after PR review --- .github/workflows/tests.yml | 2 +- delivery/handlers/staging_handlers.py | 1 + delivery/services/delivery_service.py | 1 + delivery/services/organise_service.py | 4 +-- delivery/services/staging_service.py | 6 +++-- .../Projects/ABC_123/test_file | 1 + tests/resources/README.md | 25 +++++++++++++++++++ 7 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 tests/resources/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file create mode 100644 tests/resources/README.md diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4bb7172..8fceb34 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,6 @@ name: Run Unit Tests -on: [push] +on: [push, pull_request] jobs: build: diff --git a/delivery/handlers/staging_handlers.py b/delivery/handlers/staging_handlers.py index 7c5529c..877d4a2 100644 --- a/delivery/handlers/staging_handlers.py +++ b/delivery/handlers/staging_handlers.py @@ -30,6 +30,7 @@ def _construct_response_from_project_and_status(self, staging_order_projects_and return link_results, id_results + class StagingProjectRunfoldersHandler(BaseStagingHandler): """ Handler class for handling how to start staging of runfolders belonging to a project. Polling for status, diff --git a/delivery/services/delivery_service.py b/delivery/services/delivery_service.py index 5a8f72c..3a5e224 100644 --- a/delivery/services/delivery_service.py +++ b/delivery/services/delivery_service.py @@ -190,6 +190,7 @@ def deliver_all_runfolders_for_project(self, project_name, mode): batch_nbr=batch_nbr) self.delivery_sources_repo.add_source(source) + stage_order = self.staging_service.create_new_stage_order(path=source.path, project_name=project_name) self.staging_service.stage_order(stage_order) return {source.project_name: stage_order.id}, projects_to_deliver diff --git a/delivery/services/organise_service.py b/delivery/services/organise_service.py index 71ebd66..25b70af 100644 --- a/delivery/services/organise_service.py +++ b/delivery/services/organise_service.py @@ -29,6 +29,7 @@ def __init__(self, runfolder_service, file_system_service=FileSystemService()): """ self.runfolder_service = runfolder_service self.file_system_service = file_system_service + def organise_runfolder(self, runfolder_id, lanes, projects, force): """ Organise a runfolder in preparation for delivery. This will create separate subdirectories for each of the @@ -114,8 +115,7 @@ def organise_project( sample, organised_project_runfolder_path, lanes)) - # symlink the project files - + # symlink the project files organised_project_files = [] if project.project_files: for project_file in project.project_files: diff --git a/delivery/services/staging_service.py b/delivery/services/staging_service.py index cc1a1d2..7737e4a 100644 --- a/delivery/services/staging_service.py +++ b/delivery/services/staging_service.py @@ -90,6 +90,7 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi staging_source_with_trailing_slash = staging_order.source + "/" cmd = ['rsync', '--stats', '-r', '--copy-links', '--times', staging_source_with_trailing_slash, staging_order.staging_target] + log.debug("Running rsync with command: {}".format(" ".join(cmd))) execution = external_program_service.run(cmd) staging_order.pid = execution.pid @@ -102,8 +103,8 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi # Parse the file size from the output of rsync stats: # Total file size: 207,707,566 bytes match = re.search(r'Total file size: ([\d,]+) bytes', - execution_result.stdout, - re.MULTILINE) + execution_result.stdout, + re.MULTILINE) size_of_transfer = match.group(1) size_of_transfer = int(size_of_transfer.replace(",", "")) staging_order.size = size_of_transfer @@ -147,6 +148,7 @@ def stage_order(self, stage_order): "external_program_service": self.external_program_service, "staging_repo": self.staging_repo, "session_factory": self.session_factory} + if not self.file_system_service.exists(stage_order.staging_target): self.file_system_service.makedirs(stage_order.staging_target) diff --git a/tests/resources/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file b/tests/resources/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file new file mode 100644 index 0000000..db11c83 --- /dev/null +++ b/tests/resources/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file @@ -0,0 +1 @@ +Test content... \ No newline at end of file diff --git a/tests/resources/README.md b/tests/resources/README.md new file mode 100644 index 0000000..16318a0 --- /dev/null +++ b/tests/resources/README.md @@ -0,0 +1,25 @@ +# DELIVERY OF FASTQ FILES FROM NGI-UPPSALA,THE SNP&SEQ TECHNOLOGY PLATFORM + +This delivery includes sequencing data in FASTQ format, a summary report created with MultiQC, checksums and a copy of the sample sheet used for demultiplexing. + +## Delivery structure +``` + +└── + ├── README.md + ├── checksums.md5 + ├── SampleSheet.csv + ├── __multiqc_report_data.zip + ├── __multiqc_report.html + ├── + ├── __R1_001.fastq.gz + └── __R2_001.fastq.gz + ├── + ├── __R1_001.fastq.gz + └── __R2_001.fastq.gz + : + : + └── + ├── __R1_001.fastq.gz + └── __R2_001.fastq.gz +``` \ No newline at end of file From b59ee2b00ce1817be16e90146fc6f420e28a8690 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Tue, 17 Sep 2024 13:49:44 +0200 Subject: [PATCH 05/12] Refactored code --- delivery/services/staging_service.py | 2 +- .../160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/resources/{ => runfolders}/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file (100%) diff --git a/delivery/services/staging_service.py b/delivery/services/staging_service.py index 7737e4a..debfe5f 100644 --- a/delivery/services/staging_service.py +++ b/delivery/services/staging_service.py @@ -148,7 +148,7 @@ def stage_order(self, stage_order): "external_program_service": self.external_program_service, "staging_repo": self.staging_repo, "session_factory": self.session_factory} - + if not self.file_system_service.exists(stage_order.staging_target): self.file_system_service.makedirs(stage_order.staging_target) diff --git a/tests/resources/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file b/tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file similarity index 100% rename from tests/resources/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file rename to tests/resources/runfolders/160930_ST-E00216_0111_BH37CWALXX/Projects/ABC_123/test_file From 4ef760350ba287d8d526ea9292f8a2953597d645 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Thu, 19 Sep 2024 15:27:15 +0200 Subject: [PATCH 06/12] Adding integration tests between organise and staging serveice --- delivery/services/delivery_service.py | 10 ++---- .../integration_tests/test_integration_dds.py | 35 +++++++++++++++---- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/delivery/services/delivery_service.py b/delivery/services/delivery_service.py index 3a5e224..d6d2991 100644 --- a/delivery/services/delivery_service.py +++ b/delivery/services/delivery_service.py @@ -82,13 +82,9 @@ def _create_links_area_for_project_runfolders(self, project_name, projects, batc for project in projects: try: link_name = os.path.join(project_dir, project.runfolder_name) - project_path = project.path - if ( - os.path.exists(runfolder_path := os.path.join(project.path, project.runfolder_name)) and - len(os.listdir(project_path)) == 1 - ): - project_path = runfolder_path - self.file_system_service.symlink(project_path, link_name) + self.file_system_service.symlink( + os.path.join(project.path, project.runfolder_name), link_name + ) except FileExistsError as e: log.error("Project link: {} already exists".format(project_dir)) raise e diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 6ffb6ff..b449831 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -8,7 +8,7 @@ from delivery.models.db_models import StagingStatus, DeliveryStatus from tests.integration_tests.base import BaseIntegration - +from tests.test_utils import unorganised_runfolder class TestIntegrationDDS(BaseIntegration): @gen_test @@ -178,11 +178,32 @@ def test_can_stage_and_deliver_force_flowcells(self): prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: - self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123', os.path.basename(tmpdir1)) - self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123', os.path.basename(tmpdir2)) + # First organise + unorganised_runfolder1 = unorganised_runfolder( + name=os.path.basename(tmpdir1), + root_path=os.path.dirname(tmpdir1)) + unorganised_runfolder2 = unorganised_runfolder( + name=os.path.basename(tmpdir2), + root_path=os.path.dirname(tmpdir2)) + + self._create_runfolder_structure_on_disk(unorganised_runfolder1) + self._create_runfolder_structure_on_disk(unorganised_runfolder2) - # First just stage it - url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'XYZ_123']) + url = "/".join([self.API_BASE, "organise", "runfolder", unorganised_runfolder1.name]) + response1 = yield self.http_client.fetch(self.get_url(url), method='POST', body='') + + self.assertEqual(response1.code, 200) + + response_json1 = json.loads(response1.body) + + url = "/".join([self.API_BASE, "organise", "runfolder", unorganised_runfolder2.name]) + response2 = yield self.http_client.fetch(self.get_url(url), method='POST', body='') + self.assertEqual(response2.code, 200) + + response_json2 = json.loads(response2.body) + + # Then just stage it + url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'JKL_123']) payload = {'delivery_mode': 'BATCH'} response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) self.assertEqual(response.code, 202) @@ -200,12 +221,14 @@ def test_can_stage_and_deliver_force_flowcells(self): response_json = json.loads(response_forced.body) staging_status_links = response_json.get("staging_order_links") + #TODO: Assert the staged folder structure has only one runfolder folder + print(f"staging_status_links......{staging_status_links}") # Insert a pause to allow staging to complete time.sleep(1) for project, link in staging_status_links.items(): - self.assertEqual(project, 'XYZ_123') + self.assertEqual(project, 'JKL_123') status_response = yield self.http_client.fetch(link) self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) From 6286d01003c798f8ca71491de2448e7ad47b4302 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Fri, 20 Sep 2024 10:41:58 +0200 Subject: [PATCH 07/12] Added test to check runfolders are not duplicated --- tests/integration_tests/test_integration_dds.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index b449831..11c652c 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -221,9 +221,13 @@ def test_can_stage_and_deliver_force_flowcells(self): response_json = json.loads(response_forced.body) staging_status_links = response_json.get("staging_order_links") - #TODO: Assert the staged folder structure has only one runfolder folder - print(f"staging_status_links......{staging_status_links}") + staging_order_ids = response_json.get("staging_order_ids") + # Assert the staged folder structure has only one runfolder folder + temp_staging_dir = f"/tmp/{staging_order_ids.get('JKL_123')}/JKL_123" + for runfolder in os.listdir(temp_staging_dir): + self.assertFalse(set(runfolder).issuperset(set(os.listdir(f"{temp_staging_dir}/{runfolder}")))) + # Insert a pause to allow staging to complete time.sleep(1) From b3d437cdb355d44088438daefead761b293d08a0 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Fri, 20 Sep 2024 12:30:38 +0200 Subject: [PATCH 08/12] Refactored code --- .../integration_tests/test_integration_dds.py | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 11c652c..47cf616 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -172,6 +172,12 @@ def test_can_stage_and_deliver_batch_flowcells(self): status_response = yield self.http_client.fetch(link) self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) + def create_unorganised_test_runfolders(self, tmpdir): + return( + unorganised_runfolder( + name=os.path.basename(tmpdir), + root_path=os.path.dirname(tmpdir)) + ) @gen_test def test_can_stage_and_deliver_force_flowcells(self): with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', @@ -179,29 +185,20 @@ def test_can_stage_and_deliver_force_flowcells(self): tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: # First organise - unorganised_runfolder1 = unorganised_runfolder( - name=os.path.basename(tmpdir1), - root_path=os.path.dirname(tmpdir1)) - unorganised_runfolder2 = unorganised_runfolder( - name=os.path.basename(tmpdir2), - root_path=os.path.dirname(tmpdir2)) + unorganised_runfolder1 = self.create_unorganised_test_runfolders(tmpdir1) + unorganised_runfolder2 = self.create_unorganised_test_runfolders(tmpdir2) self._create_runfolder_structure_on_disk(unorganised_runfolder1) self._create_runfolder_structure_on_disk(unorganised_runfolder2) url = "/".join([self.API_BASE, "organise", "runfolder", unorganised_runfolder1.name]) response1 = yield self.http_client.fetch(self.get_url(url), method='POST', body='') - self.assertEqual(response1.code, 200) - - response_json1 = json.loads(response1.body) - + url = "/".join([self.API_BASE, "organise", "runfolder", unorganised_runfolder2.name]) response2 = yield self.http_client.fetch(self.get_url(url), method='POST', body='') self.assertEqual(response2.code, 200) - - response_json2 = json.loads(response2.body) - + # Then just stage it url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'JKL_123']) payload = {'delivery_mode': 'BATCH'} From 0d26c3ef2e0ab94b020f8baa2e45816be171c460 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Mon, 23 Sep 2024 11:29:35 +0200 Subject: [PATCH 09/12] Correcting integration tests --- delivery/services/staging_service.py | 9 +++++---- tests/integration_tests/test_integration_dds.py | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/delivery/services/staging_service.py b/delivery/services/staging_service.py index debfe5f..fb23639 100644 --- a/delivery/services/staging_service.py +++ b/delivery/services/staging_service.py @@ -102,11 +102,12 @@ def _copy_dir(staging_order_id, external_program_service, session_factory, stagi # Parse the file size from the output of rsync stats: # Total file size: 207,707,566 bytes - match = re.search(r'Total file size: ([\d,]+) bytes', - execution_result.stdout, - re.MULTILINE) + + match = re.search(r'Total file size: ([\d,.]+) bytes', + execution_result.stdout, + re.MULTILINE) size_of_transfer = match.group(1) - size_of_transfer = int(size_of_transfer.replace(",", "")) + size_of_transfer = int(size_of_transfer.replace(",", "").replace(".", "")) staging_order.size = size_of_transfer staging_order.status = StagingStatus.staging_successful diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 47cf616..74d51b5 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -119,8 +119,8 @@ def test_can_stage_and_deliver_clean_flowcells(self): prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1,\ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: - self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123') - self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123') + self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123', os.path.basename(tmpdir1)) + self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123', os.path.basename(tmpdir2)) url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'XYZ_123']) payload = {'delivery_mode': 'CLEAN'} @@ -147,12 +147,13 @@ def test_can_stage_and_deliver_batch_flowcells(self): prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: - self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123') - self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123') + self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123', os.path.basename(tmpdir1)) + self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123', os.path.basename(tmpdir2)) url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'XYZ_123']) payload = {'delivery_mode': 'BATCH'} response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) + self.assertEqual(response.code, 202) payload = {'delivery_mode': 'BATCH'} @@ -177,7 +178,7 @@ def create_unorganised_test_runfolders(self, tmpdir): unorganised_runfolder( name=os.path.basename(tmpdir), root_path=os.path.dirname(tmpdir)) - ) + ) @gen_test def test_can_stage_and_deliver_force_flowcells(self): with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', @@ -199,7 +200,7 @@ def test_can_stage_and_deliver_force_flowcells(self): response2 = yield self.http_client.fetch(self.get_url(url), method='POST', body='') self.assertEqual(response2.code, 200) - # Then just stage it + # Then stage it url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'JKL_123']) payload = {'delivery_mode': 'BATCH'} response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) From 91fc8cff8b1da38168a5b356d479c265229320e6 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Fri, 27 Sep 2024 15:17:06 +0200 Subject: [PATCH 10/12] Testing reformatting changes --- .../integration_tests/test_integration_dds.py | 59 ++++++++++++++----- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 74d51b5..4b18d1d 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -174,15 +174,53 @@ def test_can_stage_and_deliver_batch_flowcells(self): self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) def create_unorganised_test_runfolders(self, tmpdir): - return( - unorganised_runfolder( + return unorganised_runfolder( name=os.path.basename(tmpdir), - root_path=os.path.dirname(tmpdir)) - ) + root_path=os.path.dirname(tmpdir) + ) + @gen_test def test_can_stage_and_deliver_force_flowcells(self): with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', - prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ + prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ + tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', + prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: + self._create_projects_dir_with_random_data(tmpdir1, 'XYZ_123', os.path.basename(tmpdir1)) + self._create_projects_dir_with_random_data(tmpdir2, 'XYZ_123', os.path.basename(tmpdir2)) + + # First just stage it + url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'XYZ_123']) + payload = {'delivery_mode': 'BATCH'} + response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) + self.assertEqual(response.code, 202) + + # The it should be denied (since if has already been staged) + payload = {'delivery_mode': 'BATCH'} + response_failed = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload), raise_error=False) + self.assertEqual(response_failed.code, 403) + + # Then it should work once force is specified. + payload = {'delivery_mode': 'FORCE'} + response_forced = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) + self.assertEqual(response_forced.code, 202) + + response_json = json.loads(response_forced.body) + + staging_status_links = response_json.get("staging_order_links") + + # Insert a pause to allow staging to complete + time.sleep(1) + + for project, link in staging_status_links.items(): + self.assertEqual(project, 'XYZ_123') + + status_response = yield self.http_client.fetch(link) + self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) + + @gen_test + def test_can_organise_stage_and_deliver_force_flowcells(self): + with tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', + prefix='160930_ST-E00216_0555_BH37CWALXX_') as tmpdir1, \ tempfile.TemporaryDirectory(dir='./tests/resources/runfolders/', prefix='160930_ST-E00216_0556_BH37CWALXX_') as tmpdir2: # First organise @@ -201,17 +239,6 @@ def test_can_stage_and_deliver_force_flowcells(self): self.assertEqual(response2.code, 200) # Then stage it - url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'JKL_123']) - payload = {'delivery_mode': 'BATCH'} - response = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) - self.assertEqual(response.code, 202) - - # The it should be denied (since if has already been staged) - payload = {'delivery_mode': 'BATCH'} - response_failed = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload), raise_error=False) - self.assertEqual(response_failed.code, 403) - - # Then it should work once force is specified. payload = {'delivery_mode': 'FORCE'} response_forced = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) self.assertEqual(response_forced.code, 202) From 36614d72bd5e3fa20feaf0cb32e53099d10e98d6 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Fri, 27 Sep 2024 17:45:11 +0200 Subject: [PATCH 11/12] Testing reformatting changes --- tests/integration_tests/test_integration_dds.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 4b18d1d..2fe08f1 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -239,6 +239,7 @@ def test_can_organise_stage_and_deliver_force_flowcells(self): self.assertEqual(response2.code, 200) # Then stage it + url = "/".join([self.API_BASE, "stage", "project", 'runfolders', 'JKL_123']) payload = {'delivery_mode': 'FORCE'} response_forced = yield self.http_client.fetch(self.get_url(url), method='POST', body=json.dumps(payload)) self.assertEqual(response_forced.code, 202) From c5e980da1c73998d7a220681ae1ddd0c03c5b0d0 Mon Sep 17 00:00:00 2001 From: nelnk861 Date: Fri, 11 Oct 2024 13:53:49 +0200 Subject: [PATCH 12/12] Reformatting anf changed how to assert a folder is not in directory --- tests/integration_tests/test_integration_dds.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration_tests/test_integration_dds.py b/tests/integration_tests/test_integration_dds.py index 2fe08f1..8fa7947 100644 --- a/tests/integration_tests/test_integration_dds.py +++ b/tests/integration_tests/test_integration_dds.py @@ -249,11 +249,6 @@ def test_can_organise_stage_and_deliver_force_flowcells(self): staging_status_links = response_json.get("staging_order_links") staging_order_ids = response_json.get("staging_order_ids") - # Assert the staged folder structure has only one runfolder folder - temp_staging_dir = f"/tmp/{staging_order_ids.get('JKL_123')}/JKL_123" - for runfolder in os.listdir(temp_staging_dir): - self.assertFalse(set(runfolder).issuperset(set(os.listdir(f"{temp_staging_dir}/{runfolder}")))) - # Insert a pause to allow staging to complete time.sleep(1) @@ -263,6 +258,11 @@ def test_can_organise_stage_and_deliver_force_flowcells(self): status_response = yield self.http_client.fetch(link) self.assertEqual(json.loads(status_response.body)["status"], StagingStatus.staging_successful.name) + # Assert the staged folder structure has only one runfolder folder + temp_staging_dir = f"/tmp/{staging_order_ids.get('JKL_123')}/JKL_123" + for runfolder in os.listdir(temp_staging_dir): + self.assertFalse(runfolder in os.listdir(f"{temp_staging_dir}/{runfolder}")) + @gen_test def test_can_create_project(self): project_name = "CD-1234"