panda-server-source 0.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (375) hide show
  1. panda_server_source-0.8.0.dist-info/METADATA +55 -0
  2. panda_server_source-0.8.0.dist-info/RECORD +375 -0
  3. panda_server_source-0.8.0.dist-info/WHEEL +4 -0
  4. panda_server_source-0.8.0.dist-info/licenses/LICENSE.txt +202 -0
  5. pandajedi/__init__.py +0 -0
  6. pandajedi/jedibrokerage/AtlasAnalJobBroker.py +2343 -0
  7. pandajedi/jedibrokerage/AtlasBrokerUtils.py +1292 -0
  8. pandajedi/jedibrokerage/AtlasProdJobBroker.py +2064 -0
  9. pandajedi/jedibrokerage/AtlasProdTaskBroker.py +629 -0
  10. pandajedi/jedibrokerage/GenJobBroker.py +381 -0
  11. pandajedi/jedibrokerage/JobBrokerBase.py +133 -0
  12. pandajedi/jedibrokerage/TaskBrokerBase.py +15 -0
  13. pandajedi/jedibrokerage/__init__.py +0 -0
  14. pandajedi/jediconfig/__init__.py +0 -0
  15. pandajedi/jediconfig/jedi_config.py +40 -0
  16. pandajedi/jedicore/FactoryBase.py +182 -0
  17. pandajedi/jedicore/Interaction.py +433 -0
  18. pandajedi/jedicore/JediDBProxy.py +56 -0
  19. pandajedi/jedicore/JediDBProxyPool.py +37 -0
  20. pandajedi/jedicore/JediDBSchemaInfo.py +17 -0
  21. pandajedi/jedicore/JediException.py +13 -0
  22. pandajedi/jedicore/JediTaskBuffer.py +984 -0
  23. pandajedi/jedicore/JediTaskBufferInterface.py +50 -0
  24. pandajedi/jedicore/MsgWrapper.py +124 -0
  25. pandajedi/jedicore/ProcessUtils.py +34 -0
  26. pandajedi/jedicore/SiteCandidate.py +90 -0
  27. pandajedi/jedicore/ThreadUtils.py +205 -0
  28. pandajedi/jedicore/__init__.py +0 -0
  29. pandajedi/jediddm/AtlasDDMClient.py +1708 -0
  30. pandajedi/jediddm/DDMClientBase.py +16 -0
  31. pandajedi/jediddm/DDMInterface.py +83 -0
  32. pandajedi/jediddm/GenDDMClient.py +17 -0
  33. pandajedi/jediddm/__init__.py +0 -0
  34. pandajedi/jedidog/AtlasAnalWatchDog.py +648 -0
  35. pandajedi/jedidog/AtlasDataCarouselWatchDog.py +189 -0
  36. pandajedi/jedidog/AtlasDataLocalityUpdaterWatchDog.py +215 -0
  37. pandajedi/jedidog/AtlasProdWatchDog.py +443 -0
  38. pandajedi/jedidog/AtlasQueueFillerWatchDog.py +800 -0
  39. pandajedi/jedidog/AtlasTaskWithholderWatchDog.py +245 -0
  40. pandajedi/jedidog/AtlasWorkflowManagerWatchDog.py +63 -0
  41. pandajedi/jedidog/GenWatchDog.py +21 -0
  42. pandajedi/jedidog/JumboWatchDog.py +147 -0
  43. pandajedi/jedidog/TypicalWatchDogBase.py +122 -0
  44. pandajedi/jedidog/WatchDogBase.py +53 -0
  45. pandajedi/jedidog/__init__.py +0 -0
  46. pandajedi/jediexec/reniceJEDI.py +25 -0
  47. pandajedi/jedigen/AtlasTaskGenerator.py +110 -0
  48. pandajedi/jedigen/TaskGeneratorBase.py +15 -0
  49. pandajedi/jedigen/__init__.py +0 -0
  50. pandajedi/jedimsgprocessor/__init__.py +0 -0
  51. pandajedi/jedimsgprocessor/ai_parameter_adjuster_msg_processor +71 -0
  52. pandajedi/jedimsgprocessor/atlas_idds_msg_processor.py +66 -0
  53. pandajedi/jedimsgprocessor/base_msg_processor.py +33 -0
  54. pandajedi/jedimsgprocessor/forwarding_msg_processor.py +29 -0
  55. pandajedi/jedimsgprocessor/hpo_msg_processor.py +93 -0
  56. pandajedi/jedimsgprocessor/jedi_contents_feeder_msg_processor.py +63 -0
  57. pandajedi/jedimsgprocessor/jedi_job_generator_msg_processor.py +185 -0
  58. pandajedi/jedimsgprocessor/jedi_post_processor_msg_processor.py +82 -0
  59. pandajedi/jedimsgprocessor/kafka_msg_processor.py +44 -0
  60. pandajedi/jedimsgprocessor/panda_callback_msg_processor.py +182 -0
  61. pandajedi/jedimsgprocessor/panda_to_jedi_msg_processor.py +74 -0
  62. pandajedi/jedimsgprocessor/processing_msg_processor.py +134 -0
  63. pandajedi/jedimsgprocessor/status_report_msg_processor.py +129 -0
  64. pandajedi/jedimsgprocessor/tape_carousel_msg_processor.py +118 -0
  65. pandajedi/jedimsgprocessor/workflow_manager_msg_processor.py +89 -0
  66. pandajedi/jediorder/ContentsFeeder.py +785 -0
  67. pandajedi/jediorder/JediDaemon.py +27 -0
  68. pandajedi/jediorder/JediKnight.py +55 -0
  69. pandajedi/jediorder/JediMaster.py +238 -0
  70. pandajedi/jediorder/JediMsgProcessor.py +32 -0
  71. pandajedi/jediorder/JobBroker.py +33 -0
  72. pandajedi/jediorder/JobGenerator.py +2763 -0
  73. pandajedi/jediorder/JobSplitter.py +308 -0
  74. pandajedi/jediorder/JobThrottler.py +28 -0
  75. pandajedi/jediorder/PostProcessor.py +166 -0
  76. pandajedi/jediorder/TaskBroker.py +268 -0
  77. pandajedi/jediorder/TaskCommando.py +334 -0
  78. pandajedi/jediorder/TaskGenerator.py +17 -0
  79. pandajedi/jediorder/TaskRefiner.py +611 -0
  80. pandajedi/jediorder/TaskSetupper.py +17 -0
  81. pandajedi/jediorder/WatchDog.py +79 -0
  82. pandajedi/jediorder/__init__.py +0 -0
  83. pandajedi/jedipprocess/AtlasAnalPostProcessor.py +404 -0
  84. pandajedi/jedipprocess/AtlasPostProcessorUtils.py +50 -0
  85. pandajedi/jedipprocess/AtlasProdPostProcessor.py +178 -0
  86. pandajedi/jedipprocess/GenPostProcessor.py +35 -0
  87. pandajedi/jedipprocess/MailTemplates.py +185 -0
  88. pandajedi/jedipprocess/PostProcessorBase.py +269 -0
  89. pandajedi/jedipprocess/__init__.py +0 -0
  90. pandajedi/jedirefine/AtlasAnalTaskRefiner.py +259 -0
  91. pandajedi/jedirefine/AtlasProdTaskRefiner.py +162 -0
  92. pandajedi/jedirefine/GenTaskRefiner.py +61 -0
  93. pandajedi/jedirefine/RefinerUtils.py +154 -0
  94. pandajedi/jedirefine/TaskRefinerBase.py +996 -0
  95. pandajedi/jedirefine/__init__.py +0 -0
  96. pandajedi/jedisetup/AtlasTaskSetupper.py +309 -0
  97. pandajedi/jedisetup/GenTaskSetupper.py +16 -0
  98. pandajedi/jedisetup/SimpleTaskSetupper.py +152 -0
  99. pandajedi/jedisetup/TaskSetupperBase.py +15 -0
  100. pandajedi/jedisetup/__init__.py +0 -0
  101. pandajedi/jeditest/SchemaChecker.py +41 -0
  102. pandajedi/jeditest/addContWoSoTask.py +54 -0
  103. pandajedi/jeditest/addDataCarouselRequest.py +47 -0
  104. pandajedi/jeditest/addEventServiceTask.py +101 -0
  105. pandajedi/jeditest/addHpoTask.py +81 -0
  106. pandajedi/jeditest/addIDDSStageInRequest.py +56 -0
  107. pandajedi/jeditest/addNonAtlasTask.py +71 -0
  108. pandajedi/jeditest/addNonAtlasTaskEnc.py +64 -0
  109. pandajedi/jeditest/addTestTask.py +124 -0
  110. pandajedi/jeditest/addTestTaskParamToDEFT.py +70 -0
  111. pandajedi/jeditest/addTestTaskWithMerger.py +97 -0
  112. pandajedi/jeditest/brokerTest.py +78 -0
  113. pandajedi/jeditest/cancelDataCarouselRequest.py +35 -0
  114. pandajedi/jeditest/contentsFeederTest.py +28 -0
  115. pandajedi/jeditest/contentsFeederTestWithTask.py +18 -0
  116. pandajedi/jeditest/ddmTest.py +4 -0
  117. pandajedi/jeditest/jobGenForOneTask.py +38 -0
  118. pandajedi/jeditest/jobGeneratorTest.py +43 -0
  119. pandajedi/jeditest/jobSplitterTest.py +104 -0
  120. pandajedi/jeditest/jobThrottlerTest.py +22 -0
  121. pandajedi/jeditest/msgProcessorTest.py +9 -0
  122. pandajedi/jeditest/postProcessorTest.py +18 -0
  123. pandajedi/jeditest/resubmitDataCarouselRequest.py +35 -0
  124. pandajedi/jeditest/resubmitTaskParam.py +20 -0
  125. pandajedi/jeditest/taskBrokerTest.py +22 -0
  126. pandajedi/jeditest/taskBrokerTestWithTask.py +38 -0
  127. pandajedi/jeditest/taskBufferTest.py +5 -0
  128. pandajedi/jeditest/taskCommandoTest.py +28 -0
  129. pandajedi/jeditest/taskRefinerTest.py +30 -0
  130. pandajedi/jeditest/testOneTaskToRefine.py +49 -0
  131. pandajedi/jeditest/testOneTaskToTaskBroker.py +42 -0
  132. pandajedi/jeditest/testPandaDDMMap.py +62 -0
  133. pandajedi/jeditest/updateDataCarouselRequestParams.py +50 -0
  134. pandajedi/jeditest/watchDogTest.py +25 -0
  135. pandajedi/jeditest/workQueueTest.py +22 -0
  136. pandajedi/jedithrottle/AtlasAnalJobThrottler.py +19 -0
  137. pandajedi/jedithrottle/AtlasProdJobThrottler.py +18 -0
  138. pandajedi/jedithrottle/GenJobThrottler.py +26 -0
  139. pandajedi/jedithrottle/JobThrottlerBase.py +496 -0
  140. pandajedi/jedithrottle/__init__.py +0 -0
  141. pandaserver/__init__.py +0 -0
  142. pandaserver/api/__init__.py +0 -0
  143. pandaserver/api/v1/__init__.py +0 -0
  144. pandaserver/api/v1/common.py +339 -0
  145. pandaserver/api/v1/credential_management_api.py +372 -0
  146. pandaserver/api/v1/data_carousel_api.py +264 -0
  147. pandaserver/api/v1/event_api.py +269 -0
  148. pandaserver/api/v1/file_server_api.py +942 -0
  149. pandaserver/api/v1/harvester_api.py +445 -0
  150. pandaserver/api/v1/http_client.py +166 -0
  151. pandaserver/api/v1/idds_api.py +180 -0
  152. pandaserver/api/v1/job_api.py +463 -0
  153. pandaserver/api/v1/metaconfig_api.py +122 -0
  154. pandaserver/api/v1/pilot_api.py +895 -0
  155. pandaserver/api/v1/statistics_api.py +207 -0
  156. pandaserver/api/v1/system_api.py +186 -0
  157. pandaserver/api/v1/task_api.py +1520 -0
  158. pandaserver/api/v1/tests/__init__.py +0 -0
  159. pandaserver/api/v1/tests/credential_management_api_tests.py +116 -0
  160. pandaserver/api/v1/tests/data_carousel_api_tests.py +82 -0
  161. pandaserver/api/v1/tests/harvester_api_tests.py +188 -0
  162. pandaserver/api/v1/tests/idds_api_tests.py +45 -0
  163. pandaserver/api/v1/tests/job_api_tests.py +112 -0
  164. pandaserver/api/v1/tests/pilot_api_tests.py +154 -0
  165. pandaserver/api/v1/tests/statistics_api_tests.py +104 -0
  166. pandaserver/api/v1/tests/system_api_tests.py +58 -0
  167. pandaserver/api/v1/tests/task_api_tests.py +590 -0
  168. pandaserver/api/v1/version.py +2 -0
  169. pandaserver/api/v1/workflow_api.py +136 -0
  170. pandaserver/brokerage/SiteMapper.py +406 -0
  171. pandaserver/brokerage/__init__.py +0 -0
  172. pandaserver/brokerage/broker.py +272 -0
  173. pandaserver/config/__init__.py +0 -0
  174. pandaserver/config/config_utils.py +15 -0
  175. pandaserver/config/daemon_config.py +29 -0
  176. pandaserver/config/mcp_config.py +38 -0
  177. pandaserver/config/panda_config.py +233 -0
  178. pandaserver/configurator/Carbon.py +65 -0
  179. pandaserver/configurator/Configurator.py +908 -0
  180. pandaserver/configurator/__init__.py +0 -0
  181. pandaserver/configurator/aux.py +73 -0
  182. pandaserver/daemons/__init__.py +0 -0
  183. pandaserver/daemons/master.py +110 -0
  184. pandaserver/daemons/master_systemd.py +79 -0
  185. pandaserver/daemons/scripts/__init__.py +0 -0
  186. pandaserver/daemons/scripts/add_main.py +264 -0
  187. pandaserver/daemons/scripts/add_sub.py +221 -0
  188. pandaserver/daemons/scripts/cache_pilots.py +47 -0
  189. pandaserver/daemons/scripts/cache_schedconfig.py +286 -0
  190. pandaserver/daemons/scripts/carbon.py +50 -0
  191. pandaserver/daemons/scripts/configurator.py +94 -0
  192. pandaserver/daemons/scripts/copyArchive.py +1387 -0
  193. pandaserver/daemons/scripts/datasetManager.py +1154 -0
  194. pandaserver/daemons/scripts/dummy_test.py +25 -0
  195. pandaserver/daemons/scripts/evpPD2P.py +144 -0
  196. pandaserver/daemons/scripts/hs_scrapers.py +264 -0
  197. pandaserver/daemons/scripts/metric_collector.py +927 -0
  198. pandaserver/daemons/scripts/panda_activeusers_query.py +80 -0
  199. pandaserver/daemons/scripts/pilotStreaming.py +109 -0
  200. pandaserver/daemons/scripts/process_workflow_files_daemon.py +166 -0
  201. pandaserver/daemons/scripts/recover_lost_files_daemon.py +177 -0
  202. pandaserver/daemons/scripts/task_evaluator.py +405 -0
  203. pandaserver/daemons/scripts/tmpwatch.py +70 -0
  204. pandaserver/daemons/scripts/worker_synchronization.py +97 -0
  205. pandaserver/daemons/utils.py +753 -0
  206. pandaserver/dataservice/DataServiceUtils.py +323 -0
  207. pandaserver/dataservice/ErrorCode.py +25 -0
  208. pandaserver/dataservice/RecoverLostFilesCore.py +322 -0
  209. pandaserver/dataservice/__init__.py +0 -0
  210. pandaserver/dataservice/activator.py +79 -0
  211. pandaserver/dataservice/adder_atlas_plugin.py +1106 -0
  212. pandaserver/dataservice/adder_dummy_plugin.py +31 -0
  213. pandaserver/dataservice/adder_gen.py +954 -0
  214. pandaserver/dataservice/adder_plugin_base.py +27 -0
  215. pandaserver/dataservice/adder_result.py +75 -0
  216. pandaserver/dataservice/adder_simple_plugin.py +160 -0
  217. pandaserver/dataservice/closer.py +247 -0
  218. pandaserver/dataservice/closer_atlas_plugin.py +90 -0
  219. pandaserver/dataservice/ddm.py +1381 -0
  220. pandaserver/dataservice/ddm_handler.py +95 -0
  221. pandaserver/dataservice/dyn_data_distributer.py +824 -0
  222. pandaserver/dataservice/event_lookup_client_ei.py +77 -0
  223. pandaserver/dataservice/event_picker.py +268 -0
  224. pandaserver/dataservice/finisher.py +194 -0
  225. pandaserver/dataservice/setupper.py +225 -0
  226. pandaserver/dataservice/setupper_atlas_plugin.py +1851 -0
  227. pandaserver/dataservice/setupper_dummy_plugin.py +47 -0
  228. pandaserver/dataservice/setupper_plugin_base.py +67 -0
  229. pandaserver/jobdispatcher/DispatcherUtils.py +35 -0
  230. pandaserver/jobdispatcher/ErrorCode.py +19 -0
  231. pandaserver/jobdispatcher/JobDispatcher.py +1625 -0
  232. pandaserver/jobdispatcher/Protocol.py +443 -0
  233. pandaserver/jobdispatcher/Watcher.py +186 -0
  234. pandaserver/jobdispatcher/__init__.py +0 -0
  235. pandaserver/pandamcp/__init__.py +0 -0
  236. pandaserver/pandamcp/mcp_main.py +56 -0
  237. pandaserver/pandamcp/mcp_test_client.py +95 -0
  238. pandaserver/pandamcp/mcp_utils.py +74 -0
  239. pandaserver/proxycache/__init__.py +0 -0
  240. pandaserver/proxycache/panda_proxy_cache.py +240 -0
  241. pandaserver/proxycache/token_cache.py +141 -0
  242. pandaserver/server/.gacl +6 -0
  243. pandaserver/server/panda.py +539 -0
  244. pandaserver/srvcore/CoreUtils.py +572 -0
  245. pandaserver/srvcore/MailUtils.py +106 -0
  246. pandaserver/srvcore/__init__.py +0 -0
  247. pandaserver/srvcore/allowed_methods.py +100 -0
  248. pandaserver/srvcore/oidc_utils.py +152 -0
  249. pandaserver/srvcore/panda_request.py +196 -0
  250. pandaserver/srvcore/srv_msg_utils.py +42 -0
  251. pandaserver/taskbuffer/ConBridge.py +513 -0
  252. pandaserver/taskbuffer/DBProxyPool.py +95 -0
  253. pandaserver/taskbuffer/DataCarousel.py +3053 -0
  254. pandaserver/taskbuffer/DatasetSpec.py +137 -0
  255. pandaserver/taskbuffer/DdmSpec.py +201 -0
  256. pandaserver/taskbuffer/ErrorCode.py +87 -0
  257. pandaserver/taskbuffer/EventServiceUtils.py +396 -0
  258. pandaserver/taskbuffer/FileSpec.py +290 -0
  259. pandaserver/taskbuffer/GlobalShares.py +244 -0
  260. pandaserver/taskbuffer/HarvesterMetricsSpec.py +92 -0
  261. pandaserver/taskbuffer/Initializer.py +82 -0
  262. pandaserver/taskbuffer/InputChunk.py +1080 -0
  263. pandaserver/taskbuffer/JediCacheSpec.py +57 -0
  264. pandaserver/taskbuffer/JediDatasetSpec.py +588 -0
  265. pandaserver/taskbuffer/JediFileSpec.py +242 -0
  266. pandaserver/taskbuffer/JediTaskSpec.py +1687 -0
  267. pandaserver/taskbuffer/JobSpec.py +1006 -0
  268. pandaserver/taskbuffer/JobUtils.py +232 -0
  269. pandaserver/taskbuffer/NucleusSpec.py +116 -0
  270. pandaserver/taskbuffer/OraDBProxy.py +174 -0
  271. pandaserver/taskbuffer/PanDAMsgProcessor.py +8 -0
  272. pandaserver/taskbuffer/PandaDBSchemaInfo.py +18 -0
  273. pandaserver/taskbuffer/ParseJobXML.py +350 -0
  274. pandaserver/taskbuffer/PickleFileSpec.py +18 -0
  275. pandaserver/taskbuffer/PickleJobSpec.py +25 -0
  276. pandaserver/taskbuffer/PrioUtil.py +40 -0
  277. pandaserver/taskbuffer/ProcessGroups.py +111 -0
  278. pandaserver/taskbuffer/ResourceSpec.py +175 -0
  279. pandaserver/taskbuffer/SQLDumper.py +37 -0
  280. pandaserver/taskbuffer/SQLManager.py +60 -0
  281. pandaserver/taskbuffer/SiteSpec.py +304 -0
  282. pandaserver/taskbuffer/SupErrors.py +10 -0
  283. pandaserver/taskbuffer/TaskBuffer.py +2882 -0
  284. pandaserver/taskbuffer/TaskBufferInterface.py +163 -0
  285. pandaserver/taskbuffer/Utils.py +848 -0
  286. pandaserver/taskbuffer/WorkQueue.py +227 -0
  287. pandaserver/taskbuffer/WorkQueueMapper.py +203 -0
  288. pandaserver/taskbuffer/WorkerSpec.py +143 -0
  289. pandaserver/taskbuffer/WrappedCursor.py +487 -0
  290. pandaserver/taskbuffer/WrappedPickle.py +88 -0
  291. pandaserver/taskbuffer/WrappedPostgresConn.py +24 -0
  292. pandaserver/taskbuffer/__init__.py +0 -0
  293. pandaserver/taskbuffer/db_proxy_mods/OraDBProxy_structure.png +0 -0
  294. pandaserver/taskbuffer/db_proxy_mods/__init__.py +7 -0
  295. pandaserver/taskbuffer/db_proxy_mods/base_module.py +841 -0
  296. pandaserver/taskbuffer/db_proxy_mods/data_carousel_module.py +772 -0
  297. pandaserver/taskbuffer/db_proxy_mods/entity_module.py +3804 -0
  298. pandaserver/taskbuffer/db_proxy_mods/job_complex_module.py +5661 -0
  299. pandaserver/taskbuffer/db_proxy_mods/job_standalone_module.py +2640 -0
  300. pandaserver/taskbuffer/db_proxy_mods/metrics_module.py +874 -0
  301. pandaserver/taskbuffer/db_proxy_mods/misc_standalone_module.py +4272 -0
  302. pandaserver/taskbuffer/db_proxy_mods/task_complex_module.py +6172 -0
  303. pandaserver/taskbuffer/db_proxy_mods/task_event_module.py +4953 -0
  304. pandaserver/taskbuffer/db_proxy_mods/task_standalone_module.py +4999 -0
  305. pandaserver/taskbuffer/db_proxy_mods/task_utils_module.py +2063 -0
  306. pandaserver/taskbuffer/db_proxy_mods/worker_module.py +1944 -0
  307. pandaserver/taskbuffer/db_proxy_mods/workflow_module.py +832 -0
  308. pandaserver/taskbuffer/retryModule.py +552 -0
  309. pandaserver/taskbuffer/task_split_rules.py +308 -0
  310. pandaserver/taskbuffer/workflow_processor.py +249 -0
  311. pandaserver/taskbuffer/wrapped_oracle_conn.py +18 -0
  312. pandaserver/test/SchemaChecker.py +40 -0
  313. pandaserver/test/__init__.py +0 -0
  314. pandaserver/test/banUser.py +43 -0
  315. pandaserver/test/boostPrio.py +19 -0
  316. pandaserver/test/boostUser.py +35 -0
  317. pandaserver/test/callbackDDM.py +11 -0
  318. pandaserver/test/daod_on_demand.py +95 -0
  319. pandaserver/test/finishJob.py +184 -0
  320. pandaserver/test/finishTaskJEDI.py +11 -0
  321. pandaserver/test/getJobs.py +53 -0
  322. pandaserver/test/killJob.py +79 -0
  323. pandaserver/test/killJobLowPrio.py +99 -0
  324. pandaserver/test/killJobsInTask.py +56 -0
  325. pandaserver/test/killTask.py +80 -0
  326. pandaserver/test/killTaskJEDI.py +11 -0
  327. pandaserver/test/killUser.py +83 -0
  328. pandaserver/test/lsst/README.txt +7 -0
  329. pandaserver/test/lsst/lsstSubmit.py +139 -0
  330. pandaserver/test/lsst/lsstSubmitMERGEtest.py +141 -0
  331. pandaserver/test/lsst/lsstSubmitPhosim332.py +53 -0
  332. pandaserver/test/lsst/prepare-client-tarball-from-bigpanda-server.sh +41 -0
  333. pandaserver/test/reassignJobs.py +17 -0
  334. pandaserver/test/reassignSite.py +82 -0
  335. pandaserver/test/reassignTask.py +117 -0
  336. pandaserver/test/reassignWaiting.py +39 -0
  337. pandaserver/test/recoverLostFiles.py +7 -0
  338. pandaserver/test/reloadInputDS.py +51 -0
  339. pandaserver/test/sendCommandToJob.py +26 -0
  340. pandaserver/test/setDebugMode.py +38 -0
  341. pandaserver/test/setPriority.py +28 -0
  342. pandaserver/test/testEvgen.py +60 -0
  343. pandaserver/test/testEvgen17.py +58 -0
  344. pandaserver/test/testG4sim.py +81 -0
  345. pandaserver/test/testG4sim17.py +90 -0
  346. pandaserver/test/testGlobalShares.py +131 -0
  347. pandaserver/test/testReco.py +103 -0
  348. pandaserver/test/testSimulReco14.py +98 -0
  349. pandaserver/test/testSiteMap.py +26 -0
  350. pandaserver/test/testUpdateWorkerPilotStatus.py +9 -0
  351. pandaserver/userinterface/Client.py +1686 -0
  352. pandaserver/userinterface/UserIF.py +1799 -0
  353. pandaserver/userinterface/__init__.py +0 -0
  354. pandaserver/workflow/__init__.py +0 -0
  355. pandaserver/workflow/data_handler_plugins/base_data_handler.py +48 -0
  356. pandaserver/workflow/data_handler_plugins/ddm_collection_data_handler.py +100 -0
  357. pandaserver/workflow/data_handler_plugins/panda_task_data_handler.py +140 -0
  358. pandaserver/workflow/pcwl_test.py +122 -0
  359. pandaserver/workflow/pcwl_utils.py +384 -0
  360. pandaserver/workflow/psnakemake_container.json +68 -0
  361. pandaserver/workflow/psnakemake_task.json +62 -0
  362. pandaserver/workflow/psnakemake_test.py +60 -0
  363. pandaserver/workflow/snakeparser/__init__.py +3 -0
  364. pandaserver/workflow/snakeparser/extensions.py +74 -0
  365. pandaserver/workflow/snakeparser/log.py +53 -0
  366. pandaserver/workflow/snakeparser/names.py +3 -0
  367. pandaserver/workflow/snakeparser/parser.py +332 -0
  368. pandaserver/workflow/snakeparser/utils.py +29 -0
  369. pandaserver/workflow/step_handler_plugins/base_step_handler.py +85 -0
  370. pandaserver/workflow/step_handler_plugins/panda_task_step_handler.py +280 -0
  371. pandaserver/workflow/workflow_base.py +531 -0
  372. pandaserver/workflow/workflow_core.py +1974 -0
  373. pandaserver/workflow/workflow_core_smoketest.py +388 -0
  374. pandaserver/workflow/workflow_parser.py +222 -0
  375. pandaserver/workflow/workflow_utils.py +1047 -0
@@ -0,0 +1,590 @@
1
+ # Description: Unit tests for the Task API methods
2
+ import os
3
+ import unittest
4
+ from datetime import datetime, timedelta
5
+
6
+ from pandaserver.api.v1.http_client import HttpClient, api_url_ssl
7
+
8
+ # to run the tests with a real JEDI Task ID by setting the environment variable
9
+ JEDI_TASK_ID = os.environ.get("JEDI_TASK_ID_TEST", -1)
10
+
11
+
12
+ class TestTaskAPI(unittest.TestCase):
13
+ def setUp(self):
14
+ self.http_client = HttpClient()
15
+
16
+ def test_retry(self):
17
+ url = f"{api_url_ssl}/task/retry"
18
+ print(f"Testing URL: {url}")
19
+ data = {"task_id": JEDI_TASK_ID}
20
+ status, output = self.http_client.post(url, data)
21
+ print(output)
22
+ output["status"] = status
23
+ output["message"] = ""
24
+
25
+ if JEDI_TASK_ID == -1:
26
+ # Fake task should not be found
27
+ expected_response = {"status": 0, "success": False, "data": 2, "message": ""}
28
+ else:
29
+ # Real task
30
+ expected_response = {"status": 0, "success": True, "data": 0, "message": ""}
31
+ self.assertEqual(output, expected_response)
32
+
33
+ def test_enable_jumbo_jobs(self):
34
+ url = f"{api_url_ssl}/task/enable_jumbo_jobs"
35
+ print(f"Testing URL: {url}")
36
+ data = {"task_id": JEDI_TASK_ID, "jumbo_jobs_total": 1}
37
+ status, output = self.http_client.post(url, data)
38
+ print(output)
39
+ output["status"] = status
40
+ del output["data"]
41
+ del output["message"]
42
+
43
+ if JEDI_TASK_ID == -1:
44
+ # Fake task should not be found
45
+ expected_response = {"status": 0, "success": False}
46
+ else:
47
+ # Real task
48
+ expected_response = {"status": 0, "success": True}
49
+ self.assertEqual(output, expected_response)
50
+
51
+ def test_enable_job_cloning(self):
52
+ url = f"{api_url_ssl}/task/enable_job_cloning"
53
+ print(f"Testing URL: {url}")
54
+ data = {"task_id": JEDI_TASK_ID}
55
+ status, output = self.http_client.post(url, data)
56
+ print(output)
57
+ output["status"] = status
58
+ del output["data"]
59
+ del output["message"]
60
+
61
+ if JEDI_TASK_ID == -1:
62
+ # Fake task should not be found
63
+ expected_response = {"status": 0, "success": False}
64
+ else:
65
+ # Real task
66
+ expected_response = {"status": 0, "success": True}
67
+ self.assertEqual(output, expected_response)
68
+
69
+ def test_disable_job_cloning(self):
70
+ url = f"{api_url_ssl}/task/disable_job_cloning"
71
+ print(f"Testing URL: {url}")
72
+ data = {"task_id": JEDI_TASK_ID}
73
+ status, output = self.http_client.post(url, data)
74
+ print(output)
75
+ output["status"] = status
76
+ del output["data"]
77
+ del output["message"]
78
+
79
+ if JEDI_TASK_ID == -1:
80
+ # Fake task should not be found
81
+ expected_response = {"status": 0, "success": False}
82
+ else:
83
+ # Real task
84
+ expected_response = {"status": 0, "success": True}
85
+ self.assertEqual(output, expected_response)
86
+
87
+ def test_increase_attempts(self):
88
+ url = f"{api_url_ssl}/task/increase_attempts"
89
+ print(f"Testing URL: {url}")
90
+ data = {"task_id": JEDI_TASK_ID}
91
+ status, output = self.http_client.post(url, data)
92
+ print(output)
93
+ output["status"] = status
94
+ del output["data"]
95
+ del output["message"]
96
+
97
+ if JEDI_TASK_ID == -1:
98
+ # Fake task should not be found
99
+ expected_response = {"status": 0, "success": False}
100
+ else:
101
+ # Real task
102
+ expected_response = {"status": 0, "success": True}
103
+ self.assertEqual(output, expected_response)
104
+
105
+ def test_resume(self):
106
+ url = f"{api_url_ssl}/task/resume"
107
+ print(f"Testing URL: {url}")
108
+ data = {"task_id": JEDI_TASK_ID}
109
+ status, output = self.http_client.post(url, data)
110
+ print(output)
111
+ output["status"] = status
112
+ del output["data"]
113
+ del output["message"]
114
+
115
+ if JEDI_TASK_ID == -1:
116
+ # Fake task should not be found
117
+ expected_response = {"status": 0, "success": False}
118
+ else:
119
+ # Real task
120
+ expected_response = {"status": 0, "success": True}
121
+ self.assertEqual(output, expected_response)
122
+
123
+ def test_release(self):
124
+ url = f"{api_url_ssl}/task/release"
125
+ print(f"Testing URL: {url}")
126
+ data = {"task_id": JEDI_TASK_ID}
127
+ status, output = self.http_client.post(url, data)
128
+ print(output)
129
+ output["status"] = status
130
+ del output["data"]
131
+ del output["message"]
132
+
133
+ if JEDI_TASK_ID == -1:
134
+ # Fake task should not be found
135
+ expected_response = {"status": 0, "success": False}
136
+ else:
137
+ # Real task
138
+ expected_response = {"status": 0, "success": True}
139
+ self.assertEqual(output, expected_response)
140
+
141
+ def test_reassign(self):
142
+ # reassign(req: PandaRequest, task_id: int, site: str = None, cloud: str = None, nucleus: str = None, soft: bool = None, mode: str = None):
143
+ url = f"{api_url_ssl}/task/reassign"
144
+ print(f"Testing URL: {url}")
145
+ data = {"task_id": JEDI_TASK_ID, "site": "CERN"}
146
+ status, output = self.http_client.post(url, data)
147
+ print(output)
148
+ output["status"] = status
149
+ del output["data"]
150
+ del output["message"]
151
+
152
+ if JEDI_TASK_ID == -1:
153
+ # Fake task should not be found
154
+ expected_response = {"status": 0, "success": False}
155
+ else:
156
+ # Real task
157
+ expected_response = {"status": 0, "success": True}
158
+ self.assertEqual(output, expected_response)
159
+
160
+ def test_pause(self):
161
+ url = f"{api_url_ssl}/task/pause"
162
+ print(f"Testing URL: {url}")
163
+ data = {"task_id": JEDI_TASK_ID}
164
+ status, output = self.http_client.post(url, data)
165
+ print(output)
166
+ output["status"] = status
167
+ del output["data"]
168
+ del output["message"]
169
+
170
+ if JEDI_TASK_ID == -1:
171
+ # Fake task should not be found
172
+ expected_response = {"status": 0, "success": False}
173
+ else:
174
+ # Real task
175
+ expected_response = {"status": 0, "success": True}
176
+ self.assertEqual(output, expected_response)
177
+
178
+ def test_kill(self):
179
+ url = f"{api_url_ssl}/task/kill"
180
+ print(f"Testing URL: {url}")
181
+ data = {"task_id": JEDI_TASK_ID}
182
+ status, output = self.http_client.post(url, data)
183
+ print(output)
184
+ output["status"] = status
185
+ del output["data"]
186
+ del output["message"]
187
+
188
+ if JEDI_TASK_ID == -1:
189
+ # Fake task should not be found
190
+ expected_response = {"status": 0, "success": False}
191
+ else:
192
+ # Real task
193
+ expected_response = {"status": 0, "success": True}
194
+ self.assertEqual(output, expected_response)
195
+
196
+ def test_finish(self):
197
+ # def finish(req: PandaRequest, task_id: int, soft: bool = False, broadcast: bool = False) -> Dict[str, Any]:
198
+ url = f"{api_url_ssl}/task/finish"
199
+ print(f"Testing URL: {url}")
200
+ data = {"task_id": JEDI_TASK_ID, "soft": False, "broadcast": False}
201
+ status, output = self.http_client.post(url, data)
202
+ print(output)
203
+ output["status"] = status
204
+ del output["data"]
205
+ del output["message"]
206
+
207
+ if JEDI_TASK_ID == -1:
208
+ # Fake task should not be found
209
+ expected_response = {"status": 0, "success": False}
210
+ else:
211
+ # Real task
212
+ expected_response = {"status": 0, "success": True}
213
+ self.assertEqual(output, expected_response)
214
+
215
+ def test_reactivate(self):
216
+ # def reactivate(req: PandaRequest, task_id: int, keep_attempt_nr: bool = False, trigger_job_generation: bool = False) -> Dict[str, Any]:
217
+ url = f"{api_url_ssl}/task/reactivate"
218
+ print(f"Testing URL: {url}")
219
+ data = {"task_id": JEDI_TASK_ID}
220
+ status, output = self.http_client.post(url, data)
221
+ print(output)
222
+ output["status"] = status
223
+ del output["data"]
224
+ del output["message"]
225
+
226
+ # This method does not distinguish between real and fake tasks
227
+ expected_response = {"status": 0, "success": True}
228
+ self.assertEqual(output, expected_response)
229
+
230
+ def test_avalanche(self):
231
+ url = f"{api_url_ssl}/task/avalanche"
232
+ print(f"Testing URL: {url}")
233
+ data = {"task_id": JEDI_TASK_ID}
234
+ status, output = self.http_client.post(url, data)
235
+ print(output)
236
+ output["status"] = status
237
+ del output["data"]
238
+ del output["message"]
239
+
240
+ if JEDI_TASK_ID == -1:
241
+ # Fake task should not be found
242
+ expected_response = {"status": 0, "success": False}
243
+ else:
244
+ # Real task
245
+ expected_response = {"status": 0, "success": True}
246
+ self.assertEqual(output, expected_response)
247
+
248
+ def test_reload_input(self):
249
+ url = f"{api_url_ssl}/task/reload_input"
250
+ print(f"Testing URL: {url}")
251
+ data = {"task_id": JEDI_TASK_ID}
252
+ status, output = self.http_client.post(url, data)
253
+ print(output)
254
+ output["status"] = status
255
+ del output["data"]
256
+ del output["message"]
257
+
258
+ if JEDI_TASK_ID == -1:
259
+ # Fake task should not be found
260
+ expected_response = {"status": 0, "success": False}
261
+ else:
262
+ # Real task
263
+ expected_response = {"status": 0, "success": True}
264
+ self.assertEqual(output, expected_response)
265
+
266
+ def test_reassign_global_share(self):
267
+ url = f"{api_url_ssl}/task/reassign_global_share"
268
+ print(f"Testing URL: {url}")
269
+ data = {"task_id_list": [JEDI_TASK_ID], "share": "Test", "reassign_running_jobs": False}
270
+ status, output = self.http_client.post(url, data)
271
+ print(output)
272
+ output["status"] = status
273
+ del output["data"]
274
+ del output["message"]
275
+
276
+ if JEDI_TASK_ID == -1:
277
+ # Fake task should not be found
278
+ expected_response = {"status": 0, "success": False}
279
+ else:
280
+ # Real task
281
+ expected_response = {"status": 0, "success": True}
282
+ self.assertEqual(output, expected_response)
283
+
284
+ def test_get_status(self):
285
+ url = f"{api_url_ssl}/task/get_status"
286
+ print(f"Testing URL: {url}")
287
+ data = {"task_id": JEDI_TASK_ID}
288
+ status, output = self.http_client.get(url, data)
289
+ print(output)
290
+ output["status"] = status
291
+ del output["data"]
292
+ del output["message"]
293
+
294
+ if JEDI_TASK_ID == -1:
295
+ # Fake task should not be found
296
+ expected_response = {"status": 0, "success": False}
297
+ else:
298
+ # Real task
299
+ expected_response = {"status": 0, "success": True}
300
+ self.assertEqual(output, expected_response)
301
+
302
+ def test_get_details(self):
303
+ url = f"{api_url_ssl}/task/get_details"
304
+ print(f"Testing URL: {url}")
305
+ data = {"task_id": JEDI_TASK_ID, "include_parameters": False, "include_status": False}
306
+ status, output = self.http_client.get(url, data)
307
+ print(output)
308
+ output["status"] = status
309
+ del output["data"]
310
+ del output["message"]
311
+
312
+ if JEDI_TASK_ID == -1:
313
+ # Fake task should not be found
314
+ expected_response = {"status": 0, "success": False}
315
+ else:
316
+ # Real task
317
+ expected_response = {"status": 0, "success": True}
318
+ self.assertEqual(output, expected_response)
319
+
320
+ def test_change_attribute(self):
321
+ url = f"{api_url_ssl}/task/change_attribute"
322
+ print(f"Testing URL: {url}")
323
+ data = {"task_id": JEDI_TASK_ID, "attribute_name": "coreCount", "value": 8}
324
+ status, output = self.http_client.post(url, data)
325
+ print(output)
326
+ output["status"] = status
327
+ del output["data"]
328
+ del output["message"]
329
+
330
+ if JEDI_TASK_ID == -1:
331
+ # Fake task should not be found
332
+ expected_response = {"status": 0, "success": False}
333
+ else:
334
+ # Real task
335
+ expected_response = {"status": 0, "success": True}
336
+ self.assertEqual(output, expected_response)
337
+
338
+ def test_change_modification_time(self):
339
+ url = f"{api_url_ssl}/task/change_modification_time"
340
+ print(f"Testing URL: {url}")
341
+ data = {"task_id": JEDI_TASK_ID, "positive_hour_offset": 1}
342
+ status, output = self.http_client.post(url, data)
343
+ print(output)
344
+ output["status"] = status
345
+ del output["data"]
346
+ del output["message"]
347
+
348
+ if JEDI_TASK_ID == -1:
349
+ # Fake task should not be found
350
+ expected_response = {"status": 0, "success": False}
351
+ else:
352
+ # Real task
353
+ expected_response = {"status": 0, "success": True}
354
+ self.assertEqual(output, expected_response)
355
+
356
+ def test_change_priority(self):
357
+ url = f"{api_url_ssl}/task/change_priority"
358
+ print(f"Testing URL: {url}")
359
+ data = {"task_id": JEDI_TASK_ID, "priority": 1}
360
+ status, output = self.http_client.post(url, data)
361
+ print(output)
362
+ output["status"] = status
363
+ del output["data"]
364
+ del output["message"]
365
+
366
+ if JEDI_TASK_ID == -1:
367
+ # Fake task should not be found
368
+ expected_response = {"status": 0, "success": False}
369
+ else:
370
+ # Real task
371
+ expected_response = {"status": 0, "success": True}
372
+ self.assertEqual(output, expected_response)
373
+
374
+ def test_change_split_rule(self):
375
+ url = f"{api_url_ssl}/task/change_split_rule"
376
+ print(f"Testing URL: {url}")
377
+ data = {"task_id": JEDI_TASK_ID, "attribute_name": "AI", "value": 1}
378
+ status, output = self.http_client.post(url, data)
379
+ print(output)
380
+ output["status"] = status
381
+ del output["data"]
382
+ del output["message"]
383
+
384
+ if JEDI_TASK_ID == -1:
385
+ # Fake task should not be found
386
+ expected_response = {"status": 0, "success": False}
387
+ else:
388
+ # Real task
389
+ expected_response = {"status": 0, "success": True}
390
+ self.assertEqual(output, expected_response)
391
+
392
+ def test_get_tasks_modified_since(self):
393
+ # def get_tasks_modified_since(req, since: str, dn: str = "", full: bool = False, min_task_id: int = None, prod_source_label: str = "user") -> Dict[str, Any]:
394
+ url = f"{api_url_ssl}/task/get_tasks_modified_since"
395
+ print(f"Testing URL: {url}")
396
+
397
+ # generate the date one week ago
398
+ one_week_ago = datetime.now() - timedelta(weeks=1)
399
+ one_week_ago_str = one_week_ago.strftime("%Y-%m-%d %H:%M:%S")
400
+
401
+ data = {"since": one_week_ago_str, "dn": "test", "full": False, "min_task_id": 1, "prod_source_label": "user"}
402
+ status, output = self.http_client.get(url, data)
403
+ print(output)
404
+ output["status"] = status
405
+ del output["data"]
406
+ del output["message"]
407
+
408
+ expected_response = {"status": 0, "success": True}
409
+ self.assertEqual(output, expected_response)
410
+
411
+ def test_get_datasets_and_files(self):
412
+ # def get_datasets_and_files(req, task_id, dataset_types: List = ("input", "pseudo_input")) -> Dict[str, Any]:
413
+ url = f"{api_url_ssl}/task/get_datasets_and_files"
414
+ print(f"Testing URL: {url}")
415
+ data = {"task_id": JEDI_TASK_ID, "dataset_types": ["input", "inexisting_type"]}
416
+ status, output = self.http_client.get(url, data)
417
+ print(output)
418
+ output["status"] = status
419
+ del output["data"]
420
+ del output["message"]
421
+
422
+ if JEDI_TASK_ID == -1:
423
+ # Fake task should not be found
424
+ expected_response = {"status": 0, "success": False}
425
+ else:
426
+ # Real task
427
+ expected_response = {"status": 0, "success": True}
428
+ self.assertEqual(output, expected_response)
429
+
430
+ def test_get_job_ids(self):
431
+ # def get_job_ids(req: PandaRequest, task_id: int) -> Dict[str, Any]:
432
+ url = f"{api_url_ssl}/task/get_job_ids"
433
+ print(f"Testing URL: {url}")
434
+ data = {"task_id": [JEDI_TASK_ID]}
435
+ status, output = self.http_client.get(url, data)
436
+ print(output)
437
+ output["status"] = status
438
+ del output["data"]
439
+ del output["message"]
440
+
441
+ # This method does not distinguish between real and fake tasks
442
+ expected_response = {"status": 0, "success": True}
443
+ self.assertEqual(output, expected_response)
444
+
445
+ def test_insert_task_parameters(self):
446
+ # def insert_task_parameters(req: PandaRequest, task_parameters: Dict, parent_tid: int = None) -> Dict[str, Any]:
447
+ url = f"{api_url_ssl}/task/insert_task_parameters"
448
+ print(f"Testing URL: {url}")
449
+ data = {"task_parameters": {"test": 1, "taskName": "test_task"}, "parent_tid": 1}
450
+ status, output = self.http_client.post(url, data)
451
+ print(output)
452
+ output["status"] = status
453
+ del output["data"]
454
+ del output["message"]
455
+
456
+ expected_response = {"status": 0, "success": True}
457
+ self.assertEqual(output, expected_response)
458
+
459
+ def test_get_task_parameters(self):
460
+ # def get_task_parameters(req: PandaRequest, task_id: int) -> Dict[str, Any]:
461
+ url = f"{api_url_ssl}/task/get_task_parameters"
462
+ print(f"Testing URL: {url}")
463
+ data = {"task_id": JEDI_TASK_ID}
464
+ status, output = self.http_client.get(url, data)
465
+ print(output)
466
+ output["status"] = status
467
+ del output["data"]
468
+ del output["message"]
469
+
470
+ if JEDI_TASK_ID == -1:
471
+ # Fake task should not be found
472
+ expected_response = {"status": 0, "success": False}
473
+ else:
474
+ # Real task
475
+ expected_response = {"status": 0, "success": True}
476
+ self.assertEqual(output, expected_response)
477
+
478
+ def test_get_detailed_info(self):
479
+ # def get_detailed_info(req: PandaRequest, task_id: int) -> Dict[str, Any]:
480
+ url = f"{api_url_ssl}/task/get_detailed_info"
481
+ print(f"Testing URL: {url}")
482
+ data = {"task_id": JEDI_TASK_ID}
483
+ status, output = self.http_client.get(url, data)
484
+ print(output)
485
+ output["status"] = status
486
+
487
+ if JEDI_TASK_ID == -1:
488
+ # Fake task should not be found
489
+ del output["data"]
490
+ del output["message"]
491
+ expected_response = {"status": 0, "success": False}
492
+ else:
493
+ # Real task - verify the returned dict contains expected keys
494
+ task_info = output.get("data", {})
495
+ self.assertIn("jediTaskID", task_info)
496
+ self.assertIn("status", task_info)
497
+ self.assertIn("jobParamsTemplate", task_info)
498
+ self.assertIn("taskParams", task_info)
499
+ self.assertEqual(task_info["jediTaskID"], JEDI_TASK_ID)
500
+ del output["data"]
501
+ del output["message"]
502
+ expected_response = {"status": 0, "success": True}
503
+ self.assertEqual(output, expected_response)
504
+
505
+ def test_get_parent_detailed_info(self):
506
+ # def get_parent_detailed_info(req: PandaRequest, task_id: int) -> Dict[str, Any]:
507
+ url = f"{api_url_ssl}/task/get_parent_detailed_info"
508
+ print(f"Testing URL: {url}")
509
+ data = {"task_id": JEDI_TASK_ID}
510
+ status, output = self.http_client.get(url, data)
511
+ print(output)
512
+ output["status"] = status
513
+
514
+ if JEDI_TASK_ID == -1:
515
+ # Fake task should not be found
516
+ del output["data"]
517
+ del output["message"]
518
+ expected_response = {"status": 0, "success": False}
519
+ self.assertEqual(output, expected_response)
520
+ return
521
+
522
+ # For real tasks, parent may or may not exist. Validate shape and consistency.
523
+ if output.get("success"):
524
+ task_info = output.get("data", {})
525
+ self.assertIn("jediTaskID", task_info)
526
+ self.assertIn("status", task_info)
527
+ else:
528
+ self.assertIn(
529
+ output.get("message"),
530
+ {
531
+ "Child task not found",
532
+ "No parent task found",
533
+ "Parent task not found",
534
+ "Error resolving parent task",
535
+ "Parent task details not found or retrieval error",
536
+ },
537
+ )
538
+
539
+ del output["data"]
540
+ del output["message"]
541
+ expected_response = {"status": 0, "success": output["success"]}
542
+ self.assertEqual(output, expected_response)
543
+
544
+
545
+ def test_get_scout_job_descriptions(self):
546
+ # def get_scout_job_descriptions(req: PandaRequest, task_id: int) -> Dict:
547
+ url = f"{api_url_ssl}/task/get_scout_job_descriptions"
548
+ print(f"Testing URL: {url}")
549
+ data = {"task_id": JEDI_TASK_ID}
550
+ status, output = self.http_client.get(url, data)
551
+ print(output)
552
+ output["status"] = status
553
+
554
+ if JEDI_TASK_ID == -1:
555
+ # Fake task has no scout jobs, returns empty list
556
+ output["message"] = ""
557
+ expected_response = {"status": 0, "success": True, "data": [], "message": ""}
558
+ self.assertEqual(output, expected_response)
559
+ else:
560
+ # Real task: success with a list of scout job descriptions
561
+ self.assertEqual(status, 0)
562
+ self.assertTrue(output["success"])
563
+ self.assertIsInstance(output["data"], list)
564
+
565
+ def test_get_job_descriptions(self):
566
+ # def get_job_descriptions(req: PandaRequest, task_id: int, unsuccessful_only: bool = False) -> Dict:
567
+ url = f"{api_url_ssl}/task/get_job_descriptions"
568
+ print(f"Testing URL: {url}")
569
+
570
+ for unsuccessful_only in [False, True]:
571
+ data = {"task_id": JEDI_TASK_ID, "unsuccessful_only": unsuccessful_only}
572
+ status, output = self.http_client.get(url, data)
573
+ print(output)
574
+ output["status"] = status
575
+
576
+ if JEDI_TASK_ID == -1:
577
+ # Fake task has no jobs, returns empty list
578
+ output["message"] = ""
579
+ expected_response = {"status": 0, "success": True, "data": [], "message": ""}
580
+ self.assertEqual(output, expected_response)
581
+ else:
582
+ # Real task: success with a list of job descriptions
583
+ self.assertEqual(status, 0)
584
+ self.assertTrue(output["success"])
585
+ self.assertIsInstance(output["data"], list)
586
+
587
+
588
+ # Run tests
589
+ if __name__ == "__main__":
590
+ unittest.main()
@@ -0,0 +1,2 @@
1
+ version = "1.0.0"
2
+ supported_until = None